使用 Microsoft Graph 向 TypeScript 应用添加电子邮件功能

在本文中,你将使用 Microsoft Graph 邮件 API 扩展在 生成 TypeScript 应用中 创建 Microsoft的应用程序。 使用 Microsoft Graph 列出用户的收件箱并发送电子邮件。

列出用户的收件箱

首先,在用户的电子邮件收件箱中列出邮件。

  1. 打开 graphHelper.ts 并添加以下函数。

    export async function getInboxAsync(): Promise<PageCollection> {
      // Ensure client isn't undefined
      if (!_userClient) {
        throw new Error('Graph has not been initialized for user auth');
      }
    
      return _userClient
        .api('/me/mailFolders/inbox/messages')
        .select(['from', 'isRead', 'receivedDateTime', 'subject'])
        .top(25)
        .orderby('receivedDateTime DESC')
        .get();
    }
    
  2. index.ts 中的空ListInboxAsync函数替换为以下内容。

    async function listInboxAsync() {
      try {
        const messagePage = await graphHelper.getInboxAsync();
        const messages: Message[] = messagePage.value;
    
        // Output each message's details
        for (const message of messages) {
          console.log(`Message: ${message.subject ?? 'NO SUBJECT'}`);
          console.log(`  From: ${message.from?.emailAddress?.name ?? 'UNKNOWN'}`);
          console.log(`  Status: ${message.isRead ? 'Read' : 'Unread'}`);
          console.log(`  Received: ${message.receivedDateTime}`);
        }
    
        // If @odata.nextLink is not undefined, there are more messages
        // available on the server
        const moreAvailable = messagePage['@odata.nextLink'] != undefined;
        console.log(`\nMore messages available? ${moreAvailable}`);
      } catch (err) {
        console.log(`Error getting user's inbox: ${err}`);
      }
    }
    
  3. 运行应用,登录,然后选择选项 2 列出收件箱。

    [1] Display access token
    [2] List my inbox
    [3] Send mail
    [4] Make a Graph call
    [0] Exit
    
    Select an option [1...4 / 0]: 2
    Message: Updates from Ask HR and other communities
      From: Contoso Demo on Yammer
      Status: Read
      Received: 12/30/2021 4:54:54 AM -05:00
    Message: Employee Initiative Thoughts
      From: Patti Fernandez
      Status: Read
      Received: 12/28/2021 5:01:10 PM -05:00
    Message: Voice Mail (11 seconds)
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 5:00:46 PM -05:00
    Message: Our Spring Blog Update
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 4:49:46 PM -05:00
    Message: Atlanta Flight Reservation
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 4:35:42 PM -05:00
    Message: Atlanta Trip Itinerary - down time
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 4:22:04 PM -05:00
    
    ...
    
    More messages available? true
    

getInboxAsync 说明

请考虑 函数中的 getInboxAsync 代码。

访问已知邮件文件夹

函数传递给/me/mailFolders/inbox/messages_userClient.api请求生成器,该生成器生成对列表消息 API 的请求。 由于它包含 /mailFolders/inbox API 终结点的 部分,因此 API 仅返回请求的邮件文件夹中的邮件。 在这种情况下,由于收件箱是用户邮箱中默认的已知文件夹,因此可通过其已知名称访问该文件夹。 非默认文件夹的访问方式相同,方法是将已知名称替换为邮件文件夹的 ID 属性。 有关可用已知文件夹名称的详细信息,请参阅 mailFolder 资源类型

访问集合

与上一 getUserAsync 部分中返回单个 对象的函数不同,此方法返回消息集合。 Microsoft Graph 中返回集合的大多数 API 不会在单个响应中返回所有可用结果。 相反,它们使用 分页 返回部分结果,同时为客户端提供请求下一页的方法。

默认页面大小

使用分页的 API 实现默认页面大小。 对于消息,默认值为 10。 客户端可以使用 $top 查询参数请求更多 (或更少的 ) 。 在 中getInboxAsync,使用 方法完成.top(25)添加$top

注意

传递给 的值 .top() 是上限,而不是显式数字。 API 返回一些 消息,最多返回 指定值。

获取后续页面

如果服务器上有更多可用的结果,则集合响应将包含一个 @odata.nextLink 具有 API URL 的属性,用于访问下一页。 JavaScript 客户端库在 对象上 PageCollection 公开此属性。 如果未定义此属性,则有更多结果可用。

@odata.nextLink的值可以传递给 以获取_userClient.api下一页结果。 或者,可以使用 PageIterator 客户端库中的 对象来 循环访问所有可用页面

集合排序

函数对请求使用 orderby 方法请求按消息接收时间排序的结果, (receivedDateTime 属性) 。 它包含DESC关键字 (keyword) 以便先列出最近收到的消息。 此方法将 $orderby 查询参数 添加到 API 调用。

发送邮件

现在,添加以经过身份验证的用户身份发送电子邮件的功能。

  1. 打开 graphHelper.ts 并添加以下函数。

    export async function sendMailAsync(
      subject: string,
      body: string,
      recipient: string,
    ) {
      // Ensure client isn't undefined
      if (!_userClient) {
        throw new Error('Graph has not been initialized for user auth');
      }
    
      // Create a new message
      const message: Message = {
        subject: subject,
        body: {
          content: body,
          contentType: 'text',
        },
        toRecipients: [
          {
            emailAddress: {
              address: recipient,
            },
          },
        ],
      };
    
      // Send the message
      return _userClient.api('me/sendMail').post({ message: message });
    }
    
  2. index.ts 中的空sendMailAsync函数替换为以下内容。

    async function sendMailAsync() {
      try {
        // Send mail to the signed-in user
        // Get the user for their email address
        const user = await graphHelper.getUserAsync();
        const userEmail = user?.mail ?? user?.userPrincipalName;
    
        if (!userEmail) {
          console.log("Couldn't get your email address, canceling...");
          return;
        }
    
        await graphHelper.sendMailAsync(
          'Testing Microsoft Graph',
          'Hello world!',
          userEmail,
        );
        console.log('Mail sent.');
      } catch (err) {
        console.log(`Error sending mail: ${err}`);
      }
    }
    
  3. 运行应用,登录并选择选项 3 以向自己发送电子邮件。

    [1] Display access token
    [2] List my inbox
    [3] Send mail
    [4] Make a Graph call
    [0] Exit
    
    Select an option [1...4 / 0]: 3
    Mail sent.
    

    注意

    如果使用 Microsoft 365 开发人员计划中的开发人员租户进行测试,则发送的电子邮件可能未送达,并且可能会收到无法交付的报告。 如果要取消阻止从租户发送邮件,请通过Microsoft 365 管理中心联系支持人员。

  4. 若要验证是否已收到邮件,请选择选项 2 列出收件箱。

sendMailAsync 说明

请考虑 函数中的 sendMailAsync 代码。

发送邮件

函数将传递给/me/sendMail_userClient.api请求生成器,该生成器生成对发送邮件 API 的请求。 请求生成器采用表示 Message 要发送的消息的 对象。

创建对象

与以前调用 Microsoft Graph(仅读取数据)不同,此调用会创建数据。 若要使用客户端库创建项,请创建表示本例中数据 (的类的实例, Message) ,设置所需的属性,然后在 API 调用中发送它。 由于调用正在发送数据,因此使用 post 方法而不是 get

后续步骤