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

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

列出用户的收件箱

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

  1. 将以下函数添加到 graph.py

    async def get_inbox(self):
        query_params = MessagesRequestBuilder.MessagesRequestBuilderGetQueryParameters(
            # Only request specific properties
            select=['from', 'isRead', 'receivedDateTime', 'subject'],
            # Get at most 25 results
            top=25,
            # Sort by received time, newest first
            orderby=['receivedDateTime DESC']
        )
        request_config = MessagesRequestBuilder.MessagesRequestBuilderGetRequestConfiguration(
            query_parameters= query_params
        )
    
        messages = await self.user_client.me.mail_folders.by_mail_folder_id('inbox').messages.get(
                request_configuration=request_config)
        return messages
    
  2. main.py 中的空list_inbox函数替换为以下内容。

    async def list_inbox(graph: Graph):
        message_page = await graph.get_inbox()
        if message_page and message_page.value:
            # Output each message's details
            for message in message_page.value:
                print('Message:', message.subject)
                if (
                    message.from_ and
                    message.from_.email_address
                ):
                    print('  From:', message.from_.email_address.name or 'NONE')
                else:
                    print('  From: NONE')
                print('  Status:', 'Read' if message.is_read else 'Unread')
                print('  Received:', message.received_date_time)
    
            # If @odata.nextLink is present
            more_available = message_page.odata_next_link is not None
            print('\nMore messages available?', more_available, '\n')
    
  3. 运行应用,登录,然后选择选项 2 列出收件箱。

    Please choose one of the following options:
    0. Exit
    1. Display access token
    2. List my inbox
    3. Send mail
    4. Make a Graph call
    2
    Message: Updates from Ask HR and other communities
      From: Contoso Demo on Yammer
      Status: Read
      Received: 2022-04-26T19:19:05Z
    Message: Employee Initiative Thoughts
      From: Patti Fernandez
      Status: Read
      Received: 2022-04-25T19:43:57Z
    Message: Voice Mail (11 seconds)
      From: Alex Wilber
      Status: Unread
      Received: 2022-04-22T19:43:23Z
    Message: Our Spring Blog Update
      From: Alex Wilber
      Status: Unread
      Received: 2022-04-19T22:19:02Z
    Message: Atlanta Flight Reservation
      From: Alex Wilber
      Status: Unread
      Received: 2022-04-19T15:15:56Z
    Message: Atlanta Trip Itinerary - down time
      From: Alex Wilber
      Status: Unread
      Received: 2022-04-18T14:24:16Z
    
    ...
    
    More messages available? True
    

get_inbox解释

请考虑 函数中的 get_inbox 代码。

访问已知邮件文件夹

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

访问集合

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

默认页面大小

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

注意

传入的值 $top 是上限,而不是显式数字。 API 返回一些 消息,最多返回 指定值。

获取后续页面

如果服务器上有更多可用的结果,则集合响应将包含一个 @odata.nextLink 具有 API URL 的属性,用于访问下一页。 Python SDK 在集合页对象上提供 odata_next_link 属性。 如果存在此属性,则有更多结果可用。

集合排序

函数使用 $orderby 查询参数 请求按消息接收时间排序的结果, receivedDateTime (属性) 。 它包含DESC关键字 (keyword) 以便先列出最近收到的消息。 在 get_inbox中,使用 对象中的 MessagesRequestBuilderGetQueryParameters 参数完成orderby添加$orderby

发送邮件

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

  1. 将以下函数添加到 graph.py

    async def send_mail(self, subject: str, body: str, recipient: str):
        message = Message()
        message.subject = subject
    
        message.body = ItemBody()
        message.body.content_type = BodyType.Text
        message.body.content = body
    
        to_recipient = Recipient()
        to_recipient.email_address = EmailAddress()
        to_recipient.email_address.address = recipient
        message.to_recipients = []
        message.to_recipients.append(to_recipient)
    
        request_body = SendMailPostRequestBody()
        request_body.message = message
    
        await self.user_client.me.send_mail.post(body=request_body)
    
  2. main.py 中的空send_mail函数替换为以下内容。

    async def send_mail(graph: Graph):
        # Send mail to the signed-in user
        # Get the user for their email address
        user = await graph.get_user()
        if user:
            user_email = user.mail or user.user_principal_name
    
            await graph.send_mail('Testing Microsoft Graph', 'Hello world!', user_email or '')
            print('Mail sent.\n')
    
  3. 运行应用,登录并选择选项 3 以向自己发送电子邮件。

    Please choose one of the following options:
    0. Exit
    1. Display access token
    2. List my inbox
    3. Send mail
    4. Make a Graph call
    3
    Mail sent.
    

    注意

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

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

send_mail说明

请考虑 函数中的 send_mail 代码。

发送邮件

函数使用 user_client.me.send_mail 请求生成器,该生成器生成对 发送邮件 API 的请求。

创建对象

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

后续步骤