0

I am fairly new to MSGraph and I have a problem with the POST request. I am currently building an app in SharePoint Framework with React which should send a message to the typed email with subject and message.

Here I send my file structure:

File structure

Here is the SendmailWebPart.ts file:

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';

import * as strings from 'SendmailWebPartStrings';
import Sendmail from './components/Sendmail';
import { ISendmailProps } from './components/ISendmailProps';

import { MSGraphClientFactory, MSGraphClient } from '@microsoft/sp-http';

export interface ISendmailWebPartProps {
  description: string;
}

export default class SendmailWebPart extends BaseClientSideWebPart<ISendmailWebPartProps> {

  public render(): void {
    const element: React.ReactElement<ISendmailProps > = React.createElement(
      Sendmail,
      {
        description: this.properties.description,
        spfxContext: this.context
      }
    );

    this.context.msGraphClientFactory
        .getClient()
        .then((client: MSGraphClient): void => {
            client
              .api('/me')
              .get((error, response: any, rawResponse?: any) => {
                console.log("Any Graph Response? " + JSON.stringify(response));

              })
        });


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

  protected onDispose(): void {
    ReactDom.unmountComponentAtNode(this.domElement);
  }

  protected get dataVersion(): Version {
    return Version.parse('1.0');
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

Sendmail.tsx:

import * as React from 'react';
import styles from './Sendmail.module.scss';
import { ISendmailProps } from './ISendmailProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { EmailForm } from './EmailForm'

export default class Sendmail extends React.Component<ISendmailProps, {}> {
  public render(): React.ReactElement<ISendmailProps> {
    return (
      <div className={ styles.sendmail }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <span className={ styles.title }>Welcome to SharePoint messenger!</span>
              <EmailForm description={this.props.description} spfxContext={this.context}></EmailForm>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

ISendmailProps.ts:

import { WebPartContext } from "@microsoft/sp-webpart-base";

export interface ISendmailProps {
  description: string;
  spfxContext: WebPartContext;
}

export interface ISendmailState {
  emailTo: string;
  subject: string;
  message: string;
}

And finally here is the component EmailForm.tsx in which I have the issue:

import * as React from 'react';
import styles from './Sendmail.module.scss';
import { ISendmailProps, ISendmailState } from './ISendmailProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { TextField, PrimaryButton } from 'office-ui-fabric-react';
import { MSGraphClientFactory, MSGraphClient } from '@microsoft/sp-http';
import { ServiceKey } from '@microsoft/sp-core-library';


export class EmailForm extends React.Component<ISendmailProps, ISendmailState>{
    /**
     *
     */
    constructor(props) {
        super(props);
        this.state = {
            emailTo: 'dddddddddd.cx',
            subject: 'dsdsd',
            message: 'dsdsdsdsdcdcdcdcdcdcdc'
        }
    }



    //Render Email. Show the attributes
        public render(): React.ReactElement<ISendmailState> {
            return(
                <div>
                    <TextField label="Email to " value={this.state.emailTo} onChange={this._handleMailTo.bind(this)}    required />
                    <TextField label="Subject  " value={this.state.subject} onChange={this._handleSubject.bind(this)}   required />
                    <TextField label="Message  " value={this.state.message} onChange={this._handleMessage.bind(this)}   multiline rows={3} />
                    <PrimaryButton text="Send Message" onClick={() => {this._sendEmail(event)} } /> 
                </div>
            )
        }

        //Method
        private _handleMailTo(e) {
            this.setState({
                emailTo: e.target.value,
            });
        }
        private _handleSubject(e) {
            this.setState({
                subject: e.target.value
            });
        }
        private _handleMessage(e) {
            this.setState({
                message: e.target.value
            });
        }

        //Send Email
        private async _sendEmail(e): Promise<void> {
            alert("Email Sent!");
            console.log(this.state.emailTo);
            console.log(this.state.subject);
            console.log(this.state.message);

            const graphClient : MSGraphClient = this.context.serviceScope.consume(MSGraphClient.serviceKey)

            const options = {
                authProvider,
            };

            const myClient = Client.init(options);

            const sendMail = {
                message: {
                    subject: this.state.subject,
                    body: {
                        contentType: "Text",
                        content: this.state.message
                    },
                    toRecipients: [
                        {
                          emailAddress: {
                            address: this.state.emailTo
                          }
                        }
                      ],
                }
            };

            let res = await myClient.api('/me/sendMail')
                                    .post(sendMail);

        }
}

The problem is, I don't understand why when I type :

this.context.serviceScope.consume(MSGraphClient.serviceKey)

servicekey doesn't exist because I have seen someone else doing it without errors.

And the second problem is with authProvider and Client even though I am following this documentation: https://docs.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=javascript

Here I will provide a screenshot of the errors:

Errors

Here are my approved Graph API:s in API-management: enter image description here

I would appreciate if someone please could help me out here. Thank you very much in advance.

2
  • If there is no particular reason using Microsoft graph then you can use an easy option using PnP JS: github.com/SharePoint/PnP-JS-Core/wiki/… OR check this video if it is helpful. Jan 27 '20 at 13:00
  • @GaneshSanap it is that video I have been watching many times before even asking this question here.
    – kelank
    Jan 27 '20 at 13:20
1

Sample demo to send email. this.props.context the context is from webpart(.ts).

const sendMail = {
      message: {
        subject: "Test",
        body: {
          contentType: "Text",
          content: "test email in SPFx call."
        },
        toRecipients: [
          {
            emailAddress: {
              address: "lee@xxx.onmicrosoft.com"
            }
          }
        ],
        ccRecipients: [
          {
            emailAddress: {
              address: "lee@xxx.onmicrosoft.com"
            }
          }
        ]
      },
      saveToSentItems: "false"
    };

    this.props.context.msGraphClientFactory
      .getClient()
      .then((client: MSGraphClient): void => {
        // get information about the current user from the Microsoft Graph
        client
          // .api('/me')
          // .get((error, response: any, rawResponse?: any) => {
          //   let user = response.displayName;
          // });
          .api('/me/sendMail')
      .post(sendMail).then(()=>{
        console.log('email send');
      })
      });

enter image description here

3

This doesn't answer all your question, but this is to the first error MSGraphClient.serviceKey,

Since 1.6 the MSGraphClient and AadHttpClient classes no longer expose a serviceKey property which means that we cannot get hold of the default instances in custom services without passing in the entire web part context.

We get this error:

Property 'serviceKey' does not exist on type 'typeof MSGraphClient'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.