← All white papersBuild plan · October 2026

Asking for Reviews on Microsoft 365

The same standard, for a trade business that lives in Microsoft 365: Power Automate reads the job system for finished jobs, every customer gets the same message and review link, and a low score texts the owner.

8 min read·Free to implement·Published by AI Pathway

Used by

  • AI Officer
  • Business Systems Analyst
  • Office Manager

The message is the easy part. What takes thought is the same as on any stack: the flow reads the job system at the moment of sending, so a job with an open callback waits; every customer gets the words from one row in Rules, so there is nowhere for a second link to live; and an opt-out is kept against the customer, where no later job can reach it.

In short

  • What this is

    A build plan for the Review Request standard on Microsoft 365. Five lists, three flows, and a job system Power Automate can read.

  • The core rule

    Flow 1 builds every ask from Rules.MessageText and Rules.ReviewLink with only the name filled in. No list has a column for a different link or a score threshold.

  • What it does not do

    No flow sends anything to a customer after they reply, and no flow posts or answers a review. A low score adds an alert to the owner in Teams or by SMS.

  • The hard part

    Reading callbacks, disputes and complaints from the job system each time a message would go, and matching a reply that arrives days later back to its job.

Take the spec to Claude, ChatGPT or Copilot. The sentence to paste is one click away.

Want the whole thing by email?

This paper, plus the rest of the library. One click to stop them.

1. Before you start

Read the Review Request build standard first. It defines its objects, and the lists below are those objects with SharePoint types on them. Shared conventions are in building the standards on Microsoft 365.

Check what your job system lets a flow read. ServiceM8, Simpro, Fergus, Jobber and AroFlo each have an integration route, usually through an HTTP action with a key the business owns rather than a ready connector. You need job status and its timestamps, linked callback jobs, and the invoice’s disputed state. Tradify has no public API, so this plan cannot read it live.

Then decide where the texts go from. An SMS provider with a connector or an HTTP API, on an account the business owns, with inbound replies forwarded back into Flow 2. Email works the same way through a shared Outlook mailbox. Fill in the one Rules row before switching anything on.

2. The lists, with their columns

For your developer. Show the fields for your developer
Site: ReviewRequests

LIST  Rules                 (one row, written by the owner)
  Trigger         Choice          indexed, REQUIRED. complete | paid
  WaitHours       Number          REQUIRED. after the trigger, before the ask
  ReminderHours   Number          REQUIRED. after the ask, before the one reminder
  WindowDays      Number          REQUIRED. at most one ask per customer in this many days
  ReviewLink      Hyperlink       REQUIRED. the only link any message carries
  MessageText     Note            REQUIRED. the one ask, with {name} and the link
  ReminderText    Note            REQUIRED

LIST  Asks                  (one per job. Never two.)
  JobId           Text            indexed, UNIQUE, REQUIRED
  CustomerId      Text            indexed, REQUIRED
  TriggeredAt     DateTime        read from the job system
  Channel         Choice          sms | email
                                  the customer's channel on record
  AskedAt         DateTime
  RemindedAt      DateTime        set once; no flow sets it twice
  Status          Choice          waiting | held | asked | reminded | replied
                                  | review_marked | skipped_window | opted_out
  ReviewMarkedBy  Person          the office marked the review as posted

LIST  Holds                 (read from the job, never a score)
  Ask             Text            lookup to Asks
  Reason          Choice          REQUIRED. open_callback | invoice_disputed
                                  | open_complaint
  RaisedAt        DateTime        indexed
  ClearedAt       DateTime        when the job system shows it closed

LIST  OptOuts               (no flow clears a row)
  CustomerId      Text            indexed, UNIQUE
  Said            Note            their words, exactly
  ReceivedAt      DateTime

LIST  Replies               (append only)
  Ask             Text            lookup to Asks
  ReplyText       Note            REQUIRED. exactly as received
  Score           Number          1 to 5 if they gave one; blank otherwise
  ReceivedAt      DateTime        indexed
  OwnerAlertedAt  DateTime        set for a 1, 2 or 3
  OwnerCalledAt   DateTime        typed by the owner

There is no link column on Asks, no score threshold anywhere, and no feedback-form address. Every message is built from Rules.MessageText or Rules.ReminderText and Rules.ReviewLink, so every customer gets the same words and the same link.

An OptOuts row has no ClearedAt. If the customer themselves asks to hear from you again, a person removes the row and records why.

Unique values on Asks.JobId is the line that holds one ask per job: a second run fails at SharePoint rather than sending twice. Unique CustomerId on OptOuts keeps one opt-out per customer, whichever job it came from.

3. Every rule, and what enforces it

The ruleEnforced byHow
The ask starts when the job system says the job is finishedFlow 1, Rules.TriggerFlow 1 polls the job system and only creates an Asks row for a job whose status matches Rules.Trigger, with TriggeredAt taken from the job system's own timestamp.
The ask waits the written timeFlow 1, Rules.WaitHoursA row stays waiting until TriggeredAt plus WaitHours has passed. The number lives in Rules, not in the flow.
Every customer gets the same message and the same linkRules.MessageText and Rules.ReviewLinkThe send action composes from those two columns and the customer's name. There is no other text source and no other link anywhere in the site.
A job that is not finished is held, and read again at sendingFlow 1, the Holds listJust before the send, Flow 1 re-reads the job. An open callback, disputed invoice or open complaint writes a Holds row, posts the reason to the owner, and skips the send.
One ask per customer per windowFlow 1, Asks.CustomerId, Rules.WindowDaysFlow 1 filters Asks on CustomerId for an AskedAt inside the window and marks the job skipped_window instead of sending.
A STOP is for good, and a low score alerts the ownerFlow 2, OptOuts and RepliesFlow 2 appends the reply exactly, writes OptOuts on STOP, and on a score of 1 to 3 alerts the owner. It has no action that sends to the customer.

4. The three flows

For your developer. Show the fields for your developer
FLOW 1  Finished job to ask
  trigger  every 15 minutes
  logic    read jobs from the job system whose status matches
             Rules.Trigger; create Asks row (JobId unique), waiting
           waiting and TriggeredAt + WaitHours passed:
             re-read the job from the job system
             open callback / disputed invoice / open complaint
               -> Holds row with Reason, post to the owner, skip
             CustomerId in OptOuts -> opted_out, skip
             another ask to CustomerId inside WindowDays
               -> skipped_window
             no mobile and no email -> post to the owner, skip
             send Rules.MessageText with the name and ReviewLink
               -> AskedAt, Status asked
           held and the job system shows it clear -> ClearedAt,
             back to waiting, so the same ask goes the same way
  never    choose the text or the link by anything about the customer.

FLOW 2  A reply arrives
  trigger  an inbound SMS webhook, or a new email in the shared box
  logic    match the sender to the newest Asks row for that customer
           append to Replies with the text exactly as received
           STOP or unsubscribe -> OptOuts row
           a score of 1, 2 or 3 -> alert the owner with the job,
             the customer and the reply; set OwnerAlertedAt
           set the Asks row to replied
  never    send anything to the customer.

FLOW 3  The one reminder
  trigger  daily, 10am
  logic    Asks rows with Status asked, RemindedAt blank,
             AskedAt + ReminderHours passed, no Replies row and
             no ReviewMarkedBy, CustomerId not in OptOuts
           send Rules.ReminderText with the name and ReviewLink
             -> RemindedAt, Status reminded
  never    remind a row whose RemindedAt is already set.

Flow 2 is the only flow that reads replies, and it has no send action. An owner who wants to answer a customer answers them as themselves, by phone.

5. The order to build it in

  1. Create the five lists from the schema, with Asks.JobId and OptOuts.CustomerId unique, and fill in the one Rules row.
  2. Build Flow 1 up to the hold, and prove a job with an open callback gets a Holds row and no send.
  3. Add the send, and prove two customers get the same words with the same link.
  4. Build Flow 2 against your own phone, and prove a 2 alerts the owner and a STOP writes OptOuts.
  5. Build Flow 3, and prove a customer who replied gets no reminder.

6. Four traps specific to this build

Switching on the review tool's own score-first feature

Some SMS and review add-ons offer to send the link only to a 4 or a 5. That is review gating. Leave it off, and keep the link in Rules where every message reads it.

Deciding the hold when the job is first seen

A callback raised during the wait must still hold the ask. Re-read the job in the same run as the send, not in an earlier one.

Keeping the opt-out on the Asks row

Next month's job is a new Asks row. If the STOP lived on last month's row, Flow 1 would ask them again.

Asking Copilot to draft a reply to the review

Answering reviews is the owner's. No flow here posts to Google or replies on it, and none should.

7. Where the automation stops

  • Answering every Google review, and the call to every low score.
  • Closing callbacks, settling disputes and closing complaints in the job system.
  • Writing the message, the wait, the reminder interval and the window.
  • Marking a review as posted, and taking anyone off OptOuts, which happens only if they ask.

The pass test. Mark two real jobs complete in your job system, one with a callback job open against it, with your own mobile as the customer on both. After the wait, the clean job gets one ask and the other has a Holds row naming the open callback. Reply 2 from your phone: the owner is alerted, Replies holds your words exactly, and nothing more arrives on your phone. Close the callback: the second job gets the same message, word for word. A minute to stage on your own tenant, then the wait.

Related reading