You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MS Graph API标记邮件为已读时遇CompactToken解析失败问题

问题描述

开发了一个基于MS Graph API的程序,用于拉取收件箱中昨日收到的、带附件且未读的邮件,请求端点为:

https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages?$expand=attachments&$search="hasAttachments:true AND received:yesterday AND isRead:false"

认证并获取数据后,将附件内容字节存储到S3桶中,核心代码如下:

result = app.acquire_token_silent(config["scope"], account=a)
s3     = boto3.client('s3')
bucket = config['bucket']
for email in emails:
    if email['hasAttachments']:
        attachments = email['attachments']
        count = 0
        for attachment in attachments:
            if attachment['isInline'] is False:
                name = attachment['name']
                fileContent =  base64.b64decode(attachment['contentBytes'])
                s3.put_object(Bucket=bucket, Key=name, Body=fileContent)
                count = count +1
                emailid = email['id']
                rp      = requests.patch(f'https://graph.microsoft.com/v1.0/me/messages/{emailid}', data ={'isRead':'true'}, headers = {"Authorization": f"Bearer token= {result['access_token']}"})
                print(rp)
                logger.info('Attachment uploaded-' + ' Attachment Size: ' + str(attachment['size']) + ' File Name: ' + attachment['name'] + ' Email Source: ' + email['from']['emailAddress']['address'] + ' Email ID: ' + email['id'] + ' Email Subject Line: ' + email['subject'])     
        logger.info(f"Attachment count uploaded to s3: {count}")
logger.info('All uploads complete')

目前附件上传功能正常,但无法标记邮件为已读,收到的报错信息为:

{"error":{"code":"InvalidAuthenticationToken","message":"CompactToken parsing failed with error code: 80049217","innerError":{"date":"2022-11-17T18:48:54","request-id":"<xxx>","client-request-id":"<xxx>"}}}

当前配置的权限仅为["Mail.ReadWrite"],请问是格式问题还是其他原因导致该错误?

问题分析与解决

直接原因:Authorization请求头格式错误

报错CompactToken parsing failed with error code: 80049217是因为Graph API无法正确解析身份令牌,问题出在请求头的写法上:
你的代码中写的是:

headers = {"Authorization": f"Bearer token= {result['access_token']}"}

正确的Bearer令牌格式应为Bearer {access_token},不需要额外添加token=字段,多余内容导致令牌解析失败。修正后的请求头应为:

headers = {"Authorization": f"Bearer {result['access_token']}"}

额外注意点:请求体格式问题

除了令牌格式,你的requests.patch使用data参数传递请求体,默认会以application/x-www-form-urlencoded格式发送,但Graph API要求请求体为JSON格式,建议改用json参数:

rp = requests.patch(
    f'https://graph.microsoft.com/v1.0/me/messages/{emailid}',
    json={'isRead': True},  # 使用json参数,且isRead应为布尔值而非字符串
    headers={"Authorization": f"Bearer {result['access_token']}"}
)

若坚持使用data参数,需手动设置Content-Type: application/json头,并将字典转为JSON字符串,但使用json参数更简便。

权限验证

你配置的Mail.ReadWrite权限已经足够完成标记邮件为已读的操作,权限本身无问题。

内容的提问来源于stack exchange,提问作者RunRabbit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:10:35