Search Posts

WDCO document import – setup guide

This replaces most of the manual “download attachment, log into WordPress, import,
select all, apply category, save” routine with: run a script, check a spreadsheet,
click one import button on the site.

It’s two separate pieces:

  1. A small file on the WordPress site (one-time install, an admin/developer job).
  2. A Google Sheet with a script attached, which anyone can copy into their own
    Google account so more than one person can run it.

Part 1 – WordPress: install the REST snippet

This lets the script check for and create document categories (e.g. “Board Meeting
2026 > July 2026″) on the site. It does not expose documents themselves, and it
doesn’t change anything about how Document Library Pro behaves for normal use.

  1. Using your hosting file manager or FTP/SFTP, go to wp-content/mu-plugins/
    (create that folder if it isn’t there already).
  2. Upload wdco-dlp-rest-api.php into that folder.
  3. That’s it – “mu-plugins” load automatically, nothing to activate.

To remove it later, just delete the file.

Part 2 – The Google Sheet and script

Anyone who wants to be able to run this (you, or someone else at WDCO) does this
once, in their own Google account:

  1. Go to sheets.google.com and create a new blank spreadsheet. Name it
    something like “WDCO Document Import”.
  2. Go to Extensions > Apps Script. Delete the placeholder code, and paste in
    the contents of Code.gs.
  3. In the Apps Script editor, go to Project Settings (the gear icon) and
    tick “Show appsscript.json manifest file in editor”.
  4. A file called appsscript.json will appear in the file list on the left.
    Open it, delete its contents, and paste in the contents of the
    appsscript.json file provided. This limits what permissions Google asks you
    to grant (see “About the permissions” below), and also switches on the Drive
    conversion feature used to turn Word documents into PDFs automatically (see
    “Word documents are converted to PDF automatically” below) – nothing further
    needs enabling separately in the editor’s Services list.
  5. Save the project (the disk icon, or Ctrl/Cmd+S), giving it a name.
  6. Close the Apps Script tab and reload the Google Sheet. A new menu should
    appear: WDCO Document Import.
  7. From that menu, choose 1. Setup / configure… and follow the prompts:
  • Your WordPress site URL
  • Your WordPress username
  • A WordPress Application Password – not your login password. Create one
    under your WordPress profile: Users > Profile > Application Passwords,
    give it a name like “WDCO import script”, and paste the generated password
    when asked. This is what lets the script talk to your site.
  • The Gmail label your filter applies to relevant emails, exactly as it
    appears in Gmail’s own search box (e.g. wdco-meeting-papers – just the
    part after label:, no need to type “label:” itself). Setting up that
    filter is a one-time job in Gmail’s own settings (Settings > Filters and
    Blocked Addresses > Create a new filter), matching on subject words
    (executive, liaison, board, agm) plus “Has attachment,” applying your
    chosen label. If you leave this blank, the script falls back to doing
    that same keyword search itself, but only within a recent time window
    (see the next prompt) rather than your whole mailbox.
  • How many days back to search if no label is set (leave blank for the
    default, 45 days) – or, even with a label set, an extra safety limit in
    case the label ever ends up wider than intended.
  • The first time you run any menu item, Google will ask you to authorize the
    script – review and accept. A note on backlogs: if a label already has a lot of messages under it
    (e.g. you applied the filter retroactively to your whole inbox), the first
    “Find new documents now” click won’t necessarily get through all of them
    in one go – it stops itself cleanly if it’s taking too long, and tells you
    to click it again to keep going. Nothing is missed or double-counted;
    it just picks up from where it left off.

That’s the whole setup. Each person who wants to run this makes their own copy
of the Sheet (File > Make a copy) and repeats step 7 with their own
Application Password – the script code comes along automatically when you copy
the Sheet, but the configuration (site, username, password) does not, so each
copy needs its own.

Using it day to day

  • Find new documents now – searches Gmail for anything with an attachment
    whose subject mentions Executive, Liaison, Board, or AGM, sent from an @publicvoice.london or @publicvoice.uk address, and whose subject does not
    mention London Heathside, MHDT, the Partnership Board or the Estate
    Management Board. It works out a category for each, and adds a row per
    document to the “Documents” tab. Rows it isn’t confident about are
    highlighted yellow, with a reason in the “Review reason” column – usually
    because the subject didn’t include a full date, or because an attachment’s
    file name mentions one of the excluded bodies. Edit the “Category” cell
    directly to correct it, or leave it if the guess looks right. Processed
    emails are labelled WDCO/Imported in Gmail so they won’t be fetched again.
  • Turn on monthly automatic check (third Friday) – runs the same search
    on the third Friday of each month, in the morning, and emails you a short
    summary if anything new turns up (nothing is emailed if there’s nothing
    new). Apps Script cannot schedule “the third Friday” directly, so the
    trigger fires every Friday and the script does nothing unless the date is
    the 15th to the 21st. Turning this on also switches off the old weekly
    check. You can still run “Find new documents now” manually at any time. The
    script only ever adds rows to the sheet; nothing is uploaded to WordPress
    until you export the CSV and import it yourself.
  • Duplicate attachments – every row carries an “Attachment fingerprint”
    (file name plus a checksum of the file’s contents). When a later email
    carries an attachment already in the sheet, the earlier row is deleted and
    the later one kept. Rows already marked “Exported” are never deleted: the
    later copy is added and flagged for review instead. A run that removes rows
    lists them in its on-screen message or summary email, and the Drive files
    themselves are left alone. Rows that pre-date this feature are
    fingerprinted automatically at the start of the next run, or on demand with
    Fingerprint existing rows.
  • Check for duplicates on the site – before exporting, searches the
    currently-configured WordPress site’s existing documents for a title match
    against each not-yet-exported row, and writes the result into a “Possible
    duplicate” column (“Yes”, “Maybe”, or “No match found”). This only reads
    from the site, never changes anything there. It checks whichever site
    Setup currently points at – if you’re about to import to the live site,
    make sure you’ve re-run Setup pointing at the live URL first, otherwise
    you’ll be checking against the wrong site’s documents. Requires the
    updated wdco-dlp-rest-api.php (adds read access to documents, alongside
    the categories access it already had).
  • Export CSV for Document Library Pro – takes everything marked “New” in
    the sheet, double-checks with you if anything is still flagged, makes sure
    the categories exist on the site (creating any that don’t, with a
    chronological, collision-free slug), and emails you a CSV file. On your site,
    go to Document Library > Import > CSV upload, choose that file, and run
    the importer – this is the one remaining manual step, and it applies the
    category to everything in the same click.

Word documents are converted to PDF automatically

Any .doc or .docx attachment is converted to PDF before it’s saved to
Drive or listed in the sheet – you’ll see a .pdf filename in the “File
name” column even though the original email attachment was a Word document.
This is because Word documents were being rejected during the WordPress
import step (likely a hosting-level security restriction, not something
within Document Library Pro or WordPress’s own settings), while PDF – the
format used for the great majority of WDCO’s documents anyway – uploads
without issue.

If a particular file can’t be converted for some reason (rare – e.g. a
corrupted attachment), that row is flagged for review with an explanation,
and the original file is kept rather than the row silently failing.

About the permissions Google will ask for

Applying the “already handled” label to a processed email needs Google’s
gmail.modify permission – there isn’t a narrower official option that covers
labelling a specific message without also nominally covering things like
marking read/unread. The script never uses it for anything beyond searching and
labelling. Permanent deletion and sending mail as you to other people are
scopes this script does not request at all (it uses a separate, narrower
scope just to email your own notifications and CSVs to yourself).

The Drive scope had to be widened from the original narrow drive.file to
full drive access – Apps Script’s permission check won’t allow looking up a
previously-created folder by its stored ID (which the script does on every
run, rather than re-searching by name each time) under the narrower scope,
even though that folder was created by the script itself. In practice the
code only ever reads or writes inside the one “WDCO Document Imports” folder
it created during setup – the broader grant is a limitation of what Google
lets you declare, not a change in what the script actually touches.

A note on the category-guessing rules

  • Subject includes a full day + month + year (e.g. “2nd June 2026”) – used
    directly.
  • Subject includes day + month only (e.g. “21st May”) – the year is taken from
    when the email was sent, but only automatically if the meeting month is the
    same as, or the one right after, the send month. Anything else (e.g. an
    email sent in December about a meeting in February) is flagged rather than
    guessed.
  • No date at all in the subject (e.g. “Further AGM papers”) – falls back to
    the email’s own send month/year, always flagged for you to confirm.

If WDCO’s wording changes over time (a new meeting type, a different phrasing),
the rules live near the top of Code.gs in the TYPE_RULES list and are
straightforward to extend.

Filtering out other bodies

Only mail sent from the domains listed in ALLOWED_SENDER_DOMAINS near the
top of Code.gs (publicvoice.london and publicvoice.uk) is picked up, and any
message whose subject contains a phrase from EXCLUDED_SUBJECT_PHRASES
(heathside, mhdt, manor house development trust, partnership board, estate
management board) is skipped. Both checks run in the Gmail search and again
on each message. An attachment whose own file name contains one of the
phrases is kept but flagged “Needs review”, since a genuine WDCO pack
sometimes includes another body’s report. Edit either list if the rules
change. Note that the Gmail filter behind the watch label, if you use one,
is separate: it may still label mail from other senders, but the script will
ignore it.

Because the sender and subject are checked on each message rather than on the
thread as a whole, an unwanted message sharing a Gmail thread with a wanted
one is skipped on its own.

Leave a Reply