← Branch Contact Groups

Power Automate — Thursday Draft Flow

Phase 2, optional. Builds a single BCC'd draft (or, if DLP blocks that, sends individually) to whichever Thursday batch you specify, without you having to rebuild the recipient list by hand every week. v2.0: the Thursday send is split into two independent batches (server-load reasons — see the app's own Send Email screen), so this flow now takes a Batch input and you run it twice, once per batch, reviewing/sending each draft separately.

Why an Instant flow, not scheduled

You want to review subject/body/attachments before anything goes out, and you may want to run it on a day other than Thursday occasionally. A manually-triggered flow (run from Power Automate's mobile app, the web portal, or a button added to the canvas app later) gives you that control. Nothing here auto-sends on a timer.

Trigger

Manually trigger a flow (Power Automate → Instant cloud flow). Inputs:

InputTypeNotes
BatchChoice (Batch 1 / Batch 2)Which Thursday batch to build this run. Run the flow twice, once per batch — the two batches are always disjoint groups, so this never double-emails anyone.
SubjectTextDefault value you set once, editable each run.
BodyText (multi-line)Plain text or simple HTML — used as-is in the draft body.
ConfirmSendYes/NoDefault No. Safety gate — the flow stops early unless this is explicitly set to Yes on the run.

Steps

  1. Get itemsBM Groups, Filter Query: ThursdayBatch eq '@{triggerBody()['Batch']}' (test this exact syntax against your tenant's Choice-column OData behaviour first — some environments want ThursdayBatch/Value eq '...' instead; if the filter comes back empty, that's the first thing to try)
  2. Compose — "Build OData filter", to turn those group names into a filter string for the next step:
    join(select(body('Get_items')?['value'], concat('GroupName eq ''', item()?['Title'], '''')), ' or ')
  3. Get itemsBM Memberships, Filter Query: @{outputs('Build_OData_filter')}
  4. Select — "Emails only": From = body('Get_items_2')?['value'], Map = item()?['Email']
  5. Compose — "Dedupe emails": union(body('Emails_only'), body('Emails_only')) — this is the standard Power Automate trick for deduplicating an array of primitives (union of a list with itself keeps only unique values).
  6. Select — "BCC recipient objects" (for the Graph draft body): From = outputs('Dedupe_emails'), Map = {"emailAddress": {"address": item()}}
  7. Condition — "Confirmed?": ConfirmSend is equal to Yes
  8. Get files (properties only) — SharePoint, List: your document library, Folder: BM Outbox
  9. Apply to each file from the previous step → Get file content, then Compose — "Attachment object":
    {
      "@odata.type": "#microsoft.graph.fileAttachment",
      "name": items('Apply_to_each')?['{FilenameWithExtension}'],
      "contentBytes": base64(body('Get_file_content'))
    }
    (Collect these into an array — either let Apply to each's Compose output accumulate automatically, or use a separate "Select" afterward over the file list mapping to the same shape.)
  10. Send an HTTP requestOffice 365 Outlook connector's built-in action (not a raw HTTP connector — this is what lets a Standard-tier flow call Graph using the connection's own token, no premium connector or app registration needed):
This creates a draft in your own mailbox (POST to /me/messages with no /send call afterwards). Nothing is sent — you open Outlook, review it, hit Send yourself. There is no native "create draft" action in the standard Office 365 Outlook connector, which is why this goes via Send an HTTP request against Graph directly.

DLP Fallback — If "Send an HTTP request" Is Blocked

Some tenants' Data Loss Prevention policies classify Send an HTTP request as a "premium"/blocked action even though it's part of a standard connector, or block outbound HTTP actions generally. If step 10 above fails with a DLP policy violation error, replace steps 9–10 with:

  1. Apply to each — over outputs('Dedupe_emails') (the flat email array from step 5, not the BCC-shaped one)
  2. Inside the loop: Send an email (V2) (standard Office 365 Outlook action)

This sends one individual email per recipient (mail-merge style) rather than one BCC'd draft — no BCC needed since each message has exactly one real recipient. Keep the same ConfirmSend gate in front of this loop. For ~130 recipients per group, this is well within Exchange Online's per-flow-run sending limits, but consider adding a short Delay (1–2 seconds) inside the loop if you see throttling errors on a live run.

Test which variant your tenant allows with a single test recipient (your own email in BM Memberships temporarily, or a one-off manual test group) before running either version against a full batch. Also confirm the ThursdayBatch filter query in step 1 actually returns the right groups for each batch before your first real run — a wrong filter here silently sends to the wrong (or zero) people rather than erroring.