Add a Real “Email User” Button for a SharePoint List using Power Automate




Add a Real “Email User” Button for a SharePoint List using Power Automate — 

Overview

This guide shows how to send server-side emails from a SharePoint list item using Power Automate. It includes two options:

  • Option 2A — “For a selected item” flow: runs from the list’s Automate menu.

  • Option 2B — Real in-row button: a column-format button that opens the flow’s run panel (uses executeFlow).

Everything here is generic—replace the placeholders with your own values (no tenant domains or personal addresses exposed).


Prerequisites

  • A SharePoint list (call it anything, e.g., Email Requests).

  • A Person column (single or multi). In steps below, use its internal name: <PersonColumnInternalName>.

  • (Optional) Column Title for the email subject.

  • Power Automate access and an Outlook mailbox (personal or a shared mailbox).

Placeholders you’ll see

  • <SiteUrl> — your SharePoint site URL (e.g., https://<yourtenant>.sharepoint.com/sites/<yourSite>).

  • <ListName> — your list name (e.g., Email Requests).

  • <PersonColumnInternalName> — internal name of the Person column (e.g., Recipient).

  • <SharedMailboxAddress> — shared mailbox address if you send from a shared mailbox.


Option 2A — “For a selected item” flow (menu-triggered)

Step 1 — Create the flow

  1. In your list: Automate ▸ Power Automate ▸ Create a flow.

  2. Choose For a selected item (list-scoped manual trigger).

  3. Add Get item (SharePoint):

    • Site Address: <SiteUrl>

    • List Name: <ListName>

    • Id: ID (dynamic from the trigger)

Step 2 — Build the recipients

Single-person column? You can map To directly from Get item ▸ <PersonColumnInternalName> Email.

Multi-person column? Create a semicolon string:

  • Add Compose (name: Compose_Recipients)

join(
  select(
    outputs('Get_item')?['body/<PersonColumnInternalName>'],
    item()?['Email']
  ),
  ';'
)

If your environment returns a simple array of strings, use:

join(outputs('Get_item')?['body/<PersonColumnInternalName>'],';')

Step 3 — Send the email

Add Send an email (V2):

  • To (single):

    @{outputs('Get_item')?['body/<PersonColumnInternalName>']?['Email']}
    
  • To (multi):

    @{outputs('Compose_Recipients')}
    
  • Subject:

    Regarding: @{coalesce(outputs('Get_item')?['body/Title'],'List item')}
    
  • Body (plain text example):

    Hi @{coalesce(outputs('Get_item')?['body/<PersonColumnInternalName>']?['DisplayName'], 'there')},
    
    This is a quick note regarding "@{outputs('Get_item')?['body/Title']}".
    

Turn on Is HTML if you paste an HTML body (see variants below).

Click Save and test it by selecting a row → Automate ▸ your flow.


Useful Variants (All Generic)

A) Send from a Shared Mailbox

Replace the action with Send an email from a shared mailbox (V2):

  • From (Shared Mailbox Address): <SharedMailboxAddress>

  • To / Subject / Body: same as above

  • Ensure the connection owner has Send As or Send on behalf rights.

B) Add CC/BCC

  • CC: team@yourdomain.com; approver@yourdomain.com

  • BCC: audit@yourdomain.com

C) HTML template + item link

  1. Add Initialize variable:

    • Name: SiteUrl

    • Type: String

    • Value: <SiteUrl>

  2. Add Compose (Compose_Html):

<p>Hi @{coalesce(outputs('Get_item')?['body/<PersonColumnInternalName>']?['DisplayName'], 'team')},</p>
<p>Here are the details for <b>@{outputs('Get_item')?['body/Title']}</b>.</p>
<p><a href="@{concat(variables('SiteUrl'), '/Lists/', encodeUriComponent('<ListName>'), '/DispForm.aspx?ID=', outputs('Get_item')?['body/ID'])}">Open item</a></p>
<hr>
<p>Sent automatically by Power Automate.</p>
  1. In Send an email, set Is HTML = Yes and use @outputs('Compose_Html') as Body.

If your trigger exposes Link to item, you can use that instead of building the URL.

D) Include attachments stored on the list item

  1. Get attachments (SharePoint) after Get item.

  2. Apply to each (value from Get attachments):

    • Get attachment content.

    • Append into two arrays you initialize beforehand: AttachNames, AttachContents.

  3. In Send an email (V2):

    • Attachments Name: @{variables('AttachNames')}

    • Attachments Content: @{variables('AttachContents')}

E) Only notify when a condition is met

Add a Condition before the email:

  • Left: outputs('Get_item')?['body/Status']

  • Equals: Ready to Notify
    Put the Send email action in the Yes branch.

F) Log emails to a separate list (audit)

Create list EmailLog with: ItemId (Number), To (Text), Subject (Text), SentOn (DateTime), RunBy (Person).
After sending, Create item:

  • ItemId: @{outputs('Get_item')?['body/ID']}

  • To: (single) as above, or (multi) @{outputs('Compose_Recipients')}

  • Subject: same as the email subject

  • SentOn: @{utcNow()}

  • RunBy: User email from the trigger

G) Fallback recipient if Person is empty

@if(
  empty(outputs('Get_item')?['body/<PersonColumnInternalName>']),
  'fallback@yourdomain.com',
  outputs('Get_item')?['body/<PersonColumnInternalName>']?['Email']
)

(For multi-person, wrap outputs('Compose_Recipients') in the same if.)


Option 2B — Real in-row button (executeFlow)

Step 1 — Reuse your working 2A flow

It must be a For a selected item flow.

Step 2 — Get the flow GUID

Open the flow in the maker portal and copy the GUID from its URL.

Step 3 — Allow Run-only users

In the flow details → Run-only users → add your site (or the specific list).

Step 4 — Add a button column with JSON

  1. Add a Single line of text column, e.g., SendMail.

  2. Column header → Format this column ▸ Advanced mode → paste:

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
  "elmType": "button",
  "txtContent": "Send email",
  "iconName": "Send",
  "attributes": { "class": "ms-fontColor-white ms-bgColor-themePrimary" },
  "customRowAction": {
    "action": "executeFlow",
    "actionParams": "{\"id\": \"PUT-FLOW-GUID-HERE\", \"headerText\": \"Send email to user\", \"runFlowButtonText\": \"Send\", \"includeFormValues\": true}"
  }
}
  1. Replace PUT-FLOW-GUID-HERE with your flow ID → Save and test.


Governance & Tips

  • Sender identity: By default, email sends under the connection owner. Use a shared mailbox for a neutral “From”.

  • Array shapes vary: If join() fails on the Person field, map with select(array, item()?['Email']) then join.

  • HTML bodies: Don’t forget Is HTML = Yes.

  • Attachment limits: Respect your Exchange attachment size limits (often ~25 MB unless customized).

  • Keep secrets out of flows: No tenant domains or personal addresses should be hard-coded. Use environment variables or config lists for addresses.


Copy-Paste Recipes (Generic)

Subject with ID + Title

Regarding: @{outputs('Get_item')?['body/ID']}: @{coalesce(outputs('Get_item')?['body/Title'],'List item')}

Robust multi-recipient

@{join(select(outputs('Get_item')?['body/<PersonColumnInternalName>'], item()?['Email']), ';')}

HTML line break: <br/>



Comments

Popular posts from this blog

Bridging the Impossible: Connecting Jira On-Prem to Power Automate & Copilot Studio — The Solution Nobody Built Until Now"

How I Automated My Entire SharePoint Tenant with 150 MCP Tools and Claude Desktop

Azure Management MCP Server