Send Email On Behalf Of Another User in SPFx using MS Graph

For the past few months, I’ve been working on a SharePoint Framework (SPFx) web part for a client. This web part uses the Microsoft Graph API to send emails whenever a new item is added to a SharePoint list or when an item’s status changes.

To send emails, I used Mail.Send permission from Microsoft Graph. Since this is a delegated permission, the email is automatically sent from the account of the user who triggers the action in the web part. Because many users use this web part, the sender email kept changing based on who performed the action.

However, the client wanted all emails to come from one fixed email address, such as “donotreply@domain.com” or “admin@domain.com,” instead of the individual user’s email.

In this article, we’ll discuss how to send an email on behalf of another user in an SPFx web part using Microsoft Graph (Old SPFx Version).

Send Emails on Behalf of Another User in SPFx Using MS Graph

To show you an example, I created a simple SPFx web part, as shown below. This web part includes a text input field where the user can enter the To email address, along with a button to send an email using Microsoft Graph.

After entering the email address and clicking the button, an email is sent successfully. If you check the From address of that email, you’ll see it shows “Do not reply”.

Now, even if another user opens the same SharePoint site and sends an email using this web part, the From address still appears as “Do not reply.”

So, no matter which user triggers the email, the sender always remains the same fixed email address.

how to send emails on behalf of another user in SPFx using MS graph

Allow Users to Send Emails from a Shared Mailbox

To use a single, fixed From email address for all emails sent from an SPFx web part, no matter who triggers the email, we need to grant users Send As permission for that email address. After this permission is added, users will be able to send emails from that address.

Follow the steps below to permit users to use that email address as the From address.

  1. Open the Exchange admin center -> Under Recipients -> Click Mailboxes.
  2. On the right, select the email address you want to keep as the fixed From address. Then click on the Mailbox delegation permission.
give mailbox permissions to another user in office 365
  1. Then, you will see the image below, which shows all the permissions. Click the Edit button for Send as.
how to add someone to a shared mailbox in outlook 365
  1. After that, it will open the pane below. Here, you can see all members who have permission to send emails on behalf of this email address. If you want to add a new person to it, click on the +Add members -> Select the user -> Click on Save -> Click on Confirm.
how to add users to shared mailbox in outlook

After a few seconds, the selected user will be added to this. So they can use this email as a from address. That’s it; this way, we can easily allow users to use this email as a sender.

In the section below, we’ll see how to send emails using MSGraph in SPFx web part, with a fixed email as the From address.

SPFx Web Part: Send Email Using MSGraph

Here, the SPFx web part im showing is a very old version (1.10.0), but the steps will be the same for the latest versions. I’ll also explain exactly what we need to change in the latest SPFx versions to achieve this requirement. Let’s follow the steps below.

I hope by this time, you know how to create an SPFx web part using React.

  1. Once the SPFx web part is created, open the package-solution.json file in the config folder, and then add the MSGraph permissions below, as shown in the image.
"webApiPermissionRequests": [
      {
        "resource": "Microsoft Graph",
        "scope": "Mail.Send"
      }
    ]
Send Email in SPFx Using Microsoft Graph API
  1. If your admin has already granted the above MSGraph permission in SharePoint Admin Center API Access, follow the next step. If not, run the commands below to build the package, then deploy it to the tenant app catalog to grant the permission.
gulp clean
gulp build
gulp bundl --ship
gulp package-solution --ship

After running these commands, under the SharePoint folder, the .sppkg file will be generated. Upload that file to the tenant or site collection app catalog, based on your requirement.

Then, in the “SharePoint Admin Center”, open “API Access” under Pending requests. There, you can see the solution you uploaded and its permissions. Select it, then click the Approve button at the top. This way, you can grant permissions.

  1. Now, we’ll create a prop to keep the Microsoft Graph client for sending emails. So open the Props.ts file located under src/webparts/components/. Then update that file with the code below.
import { MSGraphClient } from '@microsoft/sp-http';
import { WebPartContext } from '@microsoft/sp-webpart-base';
export interface IEmailSendingOldmSgraphProps {
  description: string;
  graphClient?: MSGraphClient;
  context: WebPartContext
}
  1. Then, open the .ts file and add the import statement below, and update onInit() and render() as shown below.
import { MSGraphClient } from '@microsoft/sp-http';


export default class EmailSendingOldmSgraphWebPart extends BaseClientSideWebPart<IEmailSendingOldmSgraphWebPartProps> {

  private _graphClient: MSGraphClient | undefined;

  protected onInit(): Promise<void> {
    return super.onInit().then(_ => {
      return this.context.msGraphClientFactory.getClient().then((client: MSGraphClient) => {
        this._graphClient = client;
        this.render();
      });
    });
  }

  public render(): void {
    const element: React.ReactElement<IEmailSendingOldmSgraphProps> = React.createElement(
      EmailSendingOldmSgraph,
      {
        description: this.properties.description,
        graphClient: this._graphClient,
        context: this.context
      }
    );

    ReactDom.render(element, this.domElement);
  }
}

Here:

  • We imported the MSGraphClient from the @microsoft/sp-http library.
  • Then we created a _graphClient variable and assigned the MSGraphClient as a data type.
  • After that, in the onInit() method, with this line, this.context.msGraphClientFactory.getClient().then((client: MSGraphClient), we get the MSGraphClient instance, store it in the client variable, and assign it to _graphClient.
  • Finally, in the render() method, we pass the graphClient as a prop to the React component by assigning it to this._graphClient value.
  1. After that, open the .tsx file and replace the sample code with the code below.
import * as React from 'react';
import styles from './EmailSendingOldmSgraph.module.scss';
import { IEmailSendingOldmSgraphProps } from './IEmailSendingOldmSgraphProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
interface IEmailSendingOldmSgraphState {
  to: string;
  sending: boolean;
  message: string; 
}

export default class EmailSendingOldmSgraph extends React.Component<IEmailSendingOldmSgraphProps, IEmailSendingOldmSgraphState> {
  constructor(props: IEmailSendingOldmSgraphProps) {
    super(props);
    this.state = {
      to: '',
      sending: false,
      message: ''
    };
  }

  private _onToChange = (ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => {
    this.setState({ to: newValue || '' });
  }
 private _sendMail = async () => {
  const to = this.state.to && this.state.to.trim();
  if (!to) {
    this.setState({ message: 'Enter a recipient email.' });
    return;
  }

  if (!this.props.graphClient) {
    this.setState({ message: 'Graph client not initialized.' });
    return;
  }

  this.setState({ sending: true, message: 'Sending...' });

  const mailPayload = {
    message: {
      subject: 'Mail sent as Admin',
      body: {
        contentType: 'Text',
        content: 'This email is sent on behalf of Donotreply@domain.onmicrosoft.com using SPFx.'
      },
      from: {
        emailAddress: {
          address: 'Donotreply@domain.onmicrosoft.com'   
        }
      },
      toRecipients: [
        {
          emailAddress: {
            address: to
          }
        }
      ]
    },
    saveToSentItems: true
  };

  try {
    await this.props.graphClient
      .api('me/sendMail')   
      .post(mailPayload);

    this.setState({
      sending: false,
      message: 'Email sent successfully as admin.'
    });
  } catch (err) {
    console.error('Graph sendMail error:', err);
    this.setState({
      sending: false,
      message: 'Failed to send email. Check Send As permission.'
    });
  }
};

  public render(): React.ReactElement<IEmailSendingOldmSgraphProps> {
    const { to, sending, message } = this.state;
    const clientReady = !!this.props.graphClient;

    return (
      <div className={styles.emailSendingOldmSgraph}>
        <div className={styles.container}>
          <div className={styles.row}>
            <div className={styles.column}>
              <span className={styles.title}>Send Email (MS Graph)</span>
              <p className={styles.description}>{escape(this.props.description)}</p>

              <TextField
                label="To"
                placeholder="user@domain.com"
                value={to}
                onChange={this._onToChange}
              />

              <div style={{ marginTop: 12 }}>
                <PrimaryButton
                  text={sending ? 'Sending...' : 'Send Email'}
                  onClick={this._sendMail}
                  disabled={!clientReady || sending || !to}
                />
              </div>

              { !clientReady && (
                <div style={{ marginTop: 8, color: '#d9534f' }}>
                  Graph not initialized yet. If testing locally, use the hosted workbench or deploy the web part.
                </div>
              )}

              { message && (
                <div style={{ marginTop: 8 }}>
                  {message}
                </div>
              ) }
            </div>
          </div>
        </div>
      </div>
    );
  }
}

Here:

  • At the very beginning, we imported the TextField and PrimaryButton controls from Fabric UI.
  • The IEmailSendingOldmSgraphState contains the following states:
    • to = For storing the “To” mail address that the user enters in the web part.
    • sending = Boolean type, used to keep track of sending an email.
    • message = String type, used to display various messages based on the action we are performing.
  • Then, within the constructor(), we initialized the state with empty values.
  • render() method:
    • We added the Text Field control to allow users to enter the email address. Then, in its onChange property, we called the _onToChange method.
      • _onToChange: This method will update the email address we entered in the text field control for the state “to“.
    • Below the Text Field, we added a Primary button control. Based on the sending state value, this button’s name will change, for example, to “Sending…” and “Send Email.”
    • Then, in its onClick property, we call the _sendMail() method to send emails.
    • For the disabled property, we set the condition to “{!clientReady || sending || !to}”, which means that when the MSGraph client or the sending or to state values are empty, the button will always be disabled.
    • Down to the button, messages are displayed.
  •  _sendMail() method: Here, we first check whether the to address and the MS Graph client are present. If not, we are updating the message state value, so the user will be notified that these values are empty.
    • If it exists, we created a mailPayload which contains the subject, body, from, toRecipients, and saveToSentItems values.
    • Then, in the try block, we use the line below to send emails.
    • await this.props.graphClient.api(‘me/sendMail’).post(mailPayload);

Note:

For the latest SPFx solutions, use the “/me/sendMail” Http request within the .api() method. Then, the final code will be looks like below:

await this.props.graphClient.api(‘/me/sendMail’).post(mailPayload);

That’s it, now save the changes and make the package again, redeploy into the app catalog. Don’t test this SPFX solution in the local workbench because the MSGraph client won’t be assigned, and it always contains undefined, so you’ll see an error in the console.

Graph sendMail error: TypeError: Cannot read properties of undefined (reading 'replace')
TypeError Cannot read properties of undefined reading 'replace' in spfx

Conclusion

I hope this article was helpful! In this post, I explained how to allow users to send emails using another user’s email address or a shared email address. I also showed how to send emails using Microsoft Graph in an older SPFx version and discussed the common errors you might face while testing.

This same approach works for the latest SPFx versions as well. You can follow the same steps without any changes. Feel free to download the sample solution and try it out yourself.

If you face any issues while sending emails or have questions, feel free to comment. I’ll be happy to help!

Also, look at some posts related to SPFx:

Power Apps functions free pdf

30 Power Apps Functions

This free guide walks you through the 30 most-used Power Apps functions with real business examples, exact syntax, and results you can see.

Download User registration canvas app

DOWNLOAD USER REGISTRATION POWER APPS CANVAS APP

Download a fully functional Power Apps Canvas App (with Power Automate): User Registration App