Different Ways To Send Email From A SPFx Webpart

Introduction 

 
While creating a SPFx web part in a SharePoint site, we need to send email to any user for notification. We have a couple of options. In this article, we will see different options to send emails. We will also see the pros and cons of each of them. We are going to cover 3 ways to send an email notification, using PNP Js, Power Automate, and using MS Graph API.
 
For this, I created a react based web part. Which do have one textbox and three buttons As shown in the images, there is one textbox for entering Email ID. One button for sending an email using "Pnp js", one for Power Automate and one for MS Graph.
 
For this example, I am not going to cover basic operations like creating a SPFx web part using the Yeoman generation and deploying it in the SharePoint site. For that, you can check how to get started from MSDN.

uiofwebPart
Here is the code for creating UI in "SendEmailWebPart.ts"  
 
As shown in the code below, the first set state for initial values and set up for PNP js operation. Then in render method added Message bar for notification, one Textfield, and 3 Compound Button for each operation. 
  1. export default class SendEmail extends React.Component<ISendEmailProps, ISendEmailState, {}> {  
  2.   
  3.   constructor(props: ISendEmailProps, state: ISendEmailState) {  
  4.     super(props);  
  5.   
  6.     //Set initial value for state  
  7.     this.state = ({  
  8.       emailId: "",  
  9.       statusMessage: {  
  10.         isShowMessage: false,  
  11.         message: "",  
  12.         messageType: 90000  
  13.       }  
  14.     });  
  15.   
  16.     //Set UP for PNP Operation  
  17.     sp.setup({  
  18.       spfxContext : this.props.wpContext  
  19.     });  
  20.   }  
  21.   
  22.   public render(): React.ReactElement<ISendEmailProps> {  
  23.     return (  
  24.       <div className={styles.sendEmail}>  
  25.   
  26.         {/* Show Message bar for Notification*/}  
  27.         {this.state.statusMessage.isShowMessage ?  
  28.           <MessageBar  
  29.             messageBarType={this.state.statusMessage.messageType}  
  30.             isMultiline={false}  
  31.             dismissButtonAriaLabel="Close"  
  32.           >{this.state.statusMessage.message}</MessageBar>  
  33.           : ''}  
  34.   
  35.           {/* Text field for entering Email id*/}  
  36.         <TextField required label="Enter Email Id" value={this.state.emailId} onChange={(e) => this.OnChangeTextBox(e)} /><br />  
  37.   
  38.         {/* Button for Send Email using PNP Js*/}  
  39.         <CompoundButton onClick={() => this.SendAnEmilUsingPnpJs()} primary secondaryText="Send an Email using Pnp js" >  
  40.           Pnp js  
  41.       </CompoundButton>        
  42.   
  43.       {/* Button for Send Email using Power Automate*/}  
  44.         <CompoundButton onClick={() => this.SendAnEmilUsingPowerAutomate()} primary secondaryText="Send an Email using Power Automate" >  
  45.           Power Automate  
  46.       </CompoundButton>       
  47.   
  48.       {/* Button for Send Email using Graph API*/}  
  49.         <CompoundButton onClick={() => this.SendAnEmilUsingMSGraph()} primary secondaryText="Send an Email using Graph" >  
  50.           MS Graph  
  51.       </CompoundButton>  
  52.       </div>  
  53.     );  
  54.   }  
  55. }  
Here is the code for implementing interface in "ISendEmailProps.ts"
  1. import { WebPartContext } from "@microsoft/sp-webpart-base";    
  2.   
  3.   
  4. export interface ISendEmailProps {  
  5.   description: string;  
  6.   wpContext:WebPartContext;  
  7.   msGraphClientFactory : any;  
  8. }  
  9.   
  10. export interface ISendEmailState {  
  11.   emailId: string;  
  12.   statusMessage:IMessage;    
  13. }  
  14.   
  15. export interface IMessage{  
  16.   isShowMessage:boolean;  
  17.   messageType:number;  
  18.   message:string;  
  19. }  
Here is the method to handle Textbox on change and setting the value of a textbox in the state.
  1. private OnChangeTextBox(e): void {  
  2.     this.setState({  
  3.       emailId: e.target.value  
  4.     });  
  5.   }  

Send Email using PNP Js

 
In this method, the mail is sent using "sp.utility" class of PNP js. This is the easiest method out of 3. However, this comes with its limitations as well. We can not add attachment and mail can not be sent out of the organization. You can read the documentation here.

Here is the implementation method:
  1. //Send Mail using PNP Js  
  2.   private SendAnEmilUsingPnpJs(): void {  
  3.   
  4.     //Check if TextField value is empty or not  
  5.     if (this.state.emailId) {  
  6.   
  7.       //Send Email using SP Utility  
  8.       sp.utility.sendEmail({  
  9.         //Body of Email  
  10.         Body: "This Email is sent using <b>PNP Js</b>",  
  11.         //Subject of Email  
  12.         Subject: "Mail Sent using PNP js",  
  13.         //Array of string for To of Email  
  14.         To: [this.state.emailId],  
  15.       }).then((i) => {  
  16.   
  17.         //Set Success Message Bar after sending Email  
  18.         this.setState({  
  19.           statusMessage: { isShowMessage: true, message: "Email Sent using PNP Js", messageType: 4 }  
  20.         });  
  21.       }).catch((i) => {  
  22.         //Set Error Message Bar for any error  
  23.         this.setState({  
  24.           statusMessage: { isShowMessage: true, message: "Error", messageType: 1 }  
  25.         });  
  26.       });  
  27.     }  
  28.     else {  
  29.       this.setState({  
  30.         statusMessage: { isShowMessage: true, message: "Please Enter Email ID", messageType: 1 }  
  31.       });  
  32.     }  
  33.   }  
Sending Email to Internal user - With this method, we can only send email to users that are in our organization. As shown in the below image, mail is received from [email protected]
 
 emailsentusingpnpjs-internaluser
 
Sending Email to External user - Using this method, we can not send emails to external users like gmail.com or live.com users. This will give an error if we try to do so. As shown in the image below, I am trying to send an email to the Gmail account and it's giving an error.
 
emailsentusingpnpjs-externaluser 
 
From Address - As per documentation, we can set From address as a parameter. However, this will only change the title of from address. An email address will be always [email protected]

Pros Cons
  • Easy to setup
  • No-dependency outside of webpart
  • Can't be used to send email outside of an organization
  • Attachment is not supported
 

Send Email using Power Automate

 
In this method, mail is sent using power automate. For that, first, create one flow from the Instant template from the Power automate dashboard.
 
createflowfrominstanttemplate
 
Now, add "When an HTTP request is received" from available activities and configure one variable toEmailId in JSON schema and another activity "Send an email (V2)" as shown in the image below.
 
 sendanemailfromspfxwebpartflow
 
Note - "When an HTTP request is received" this connector is now premium connector. So, check the pricing structure first in tenant that you are using it before implementing this.
 
Copy "HTTP POST URL" from the first activity and paste this URL in code below as sendEmailUrl variable.
  1. private SendAnEmilUsingPowerAutomate(): void {  
  2.   
  3.     //Check if TextField value is empty or not  
  4.     if (this.state.emailId) {  
  5.   
  6.       //HTTP POST URL  
  7.       const sendEmailUrl = "URL";  
  8.   
  9.       //Set Header   
  10.       const requestHeaders: Headers = new Headers();  
  11.       requestHeaders.append("Content-type""application/json");  
  12.   
  13.   
  14.       //Rest API call to trigger flow  
  15.       this.props.wpContext.httpClient.post(sendEmailUrl, HttpClient.configurations.v1, {  
  16.         headers: requestHeaders,  
  17.         body: `{ toEmailId: '${this.state.emailId}'}`  
  18.       }).then((response: HttpClientResponse) => {  
  19.         //Set Success Message Bar after calling flow  
  20.         if (response.ok) {  
  21.           this.setState({  
  22.             statusMessage: { isShowMessage: true, message: "Email Sent using Power Automate", messageType: 4 }  
  23.           });  
  24.         }  
  25.          //Set Error Message Bar for any error  
  26.         else {  
  27.           this.setState({  
  28.             statusMessage: { isShowMessage: true, message: 'Error', messageType: 1 }  
  29.           });  
  30.         }  
  31.       }).catch((response: any) => {  
  32.         this.setState({  
  33.           statusMessage: { isShowMessage: true, message: 'Error', messageType: 1 }  
  34.         });  
  35.       });  
  36.     }  
  37.     else {  
  38.       this.setState({  
  39.         statusMessage: { isShowMessage: true, message: "Please Enter Email ID", messageType: 1 }  
  40.       });  
  41.     }  
  42.   }  
Send Email to any user - Using this method, we can send email to any user either from organization or outside from organization
 
 emailsentusinpowerautomate-internaluser
 
emailsentusinpowerautomate-externaluser
As shown in the images above, we can send emails to users from the organization and personal email as well like Gmail.
 
From Address - Email is sent from the address by which connection is established for "Send an email (V2)" activity.

As in this method, we are just calling flow from URL, we can not get any response from flow back to the web part. In response, we can only get if the flow is called or not. So, if any error occurred in flow, we can not handle that in the web part.

Pros Cons
  • Support Attachment
  • Can send emails either to organization users or to outside organization users like Gmail, outlook, etc.
  • Have dependency outside of webpart
  • Can not be traced back in web part
 

Send Email using MS Graph

 
In this way. mail is being sent using Graph API. You can read the full documentation for Graph API to send an email here
 
You need to install npm package "@microsoft/microsoft-graph-types" and add necessary permission in "package-solution.json" file.
 
Install npm package "@microsoft/microsoft-graph-types" using below command in CMD
  1. npm install @microsoft/microsoft-graph-types --save-dev    
  • Open Config\package-solution.json file, and add the below permission scope under webApiPermissionRequests.
    1. "webApiPermissionRequests": [  
    2.       {  
    3.         "resource""Microsoft Graph",  
    4.         "scope""User.ReadBasic.All"  
    5.       },  
    6.       {  
    7.         "resource""Microsoft Graph",  
    8.         "scope""Mail.Send"  
    9.       }  
    10.  ]  
  • Here is the implementation method for the same.

    1. private SendAnEmilUsingMSGraph(): void {  
    2.   
    3.     //Check if TextField value is empty or not  
    4.     if (this.state.emailId) {  
    5.   
    6.       //Create Body fpr Email  
    7.       let emailPostBody: any = {  
    8.         "message": {  
    9.           "subject""Mail Sent using MS Graph",  
    10.           "body": {  
    11.             "contentType""HTML",  
    12.             "content""This Email is sent using <b>MS Graph</b>"  
    13.           },  
    14.           "toRecipients": [  
    15.             {  
    16.               "emailAddress": {  
    17.                 "address"this.state.emailId  
    18.               }  
    19.             }  
    20.           ],  
    21.         }  
    22.       };  
    23.   
    24.       //Send Email uisng MS Graph  
    25.       this.props.msGraphClientFactory  
    26.         .getClient()  
    27.         .then((client: MSGraphClient): void => {  
    28.           client  
    29.             .api('/me/sendMail')  
    30.             .post(emailPostBody, (error, response: any, rawResponse?: any) => {  
    31.               //Set Error Message Bar for any error  
    32.               if (error) {  
    33.                 this.setState({  
    34.                   statusMessage: { isShowMessage: true, message: error.message, messageType: 1 }  
    35.                 });  
    36.               }  
    37.                //Set Success Message Bar after Sending Email  
    38.               else {  
    39.                 this.setState({  
    40.                   statusMessage: { isShowMessage: true, message: "Email Sent using MS Graph", messageType: 4 }  
    41.                 });  
    42.               }  
    43.             });  
    44.         });  
    45.     }  
    46.     else {  
    47.       this.setState({  
    48.         statusMessage: { isShowMessage: true, message: "Please Enter Email ID", messageType: 1 }  
    49.       });  
    50.     }  
    51.   }  
    52. }  
    Send Email to any user - Using this method, we can send email to any user either from organization or outside from organization
     
    emailsentusingmsgraph-internaluser
     
    emailsentusingmsgraph-externaluser
    As shown in the images above, we can send emails to users from the organization and personal email as well such as Gmail.
     
    From Address - By default, email is sent using the current user's email address. However, we can also send email from shared-mailbox.
     
    As we set permission explicitly, the admin must approve the mentioned API access from the admin center. For that open SharePoint admin center (https://[Tenat]-admin.sharepoint.com/), go to API access under Advanced from the left navigation, and approve pending requests. After approving it will be under Approved Requests.
    msgraphapiaccess
     
    Pros Cons
    • Support Attachment
    • Can send emails either to organization users or to outside organization users like Gmail, Outlook, etc.
    • Admin need to approve API request from the admin center
     

    Conclusion

     
    So, based on the requirements, you can pick any method which suits you best. If, you need to send an email notification to only users from the organization and also attachment is not required, then PNP js is a good option. However, if email notification should be sent outside of the organization or you need the attachment, then Send Email using power automate or using MS Graph is appropriate.