使用PHP调用Microsoft Graph如何创建正文超3MB的大邮件草稿
超3MB邮件正文写入Microsoft Graph草稿解决方案
前置说明
Microsoft Graph REST API 单个普通POST/PATCH请求的默认负载上限为3-4MB,邮件正文属于请求体的一部分,直接通过更新草稿接口提交超大小正文会触发阈值限制,无法写入成功。
可用实现方案
方案1:使用可恢复上传会话写入正文(官方推荐)
该方案适配所有正文超限制场景,不需要修改正文结构,步骤如下:
- 第一步先创建不带正文的空白邮件草稿,获取草稿ID
{draft_id} - 调用创建上传会话的接口,目标资源指定为草稿的body内容,接口地址为
POST /me/messages/{draft_id}/createUploadSession,请求体示例:
如果是纯文本正文,将{ "item": { "@odata.type": "microsoft.graph.message", "body": { "contentType": "HTML", "content": "" } }, "deferCommit": false }contentType改为Text即可 - 拿到返回的
uploadUrl后,分片上传你的正文内容,分片大小建议设置为2MB-3MB之间,每次请求携带Content-Range头标注当前分片的字节范围,所有分片上传完成后正文会自动写入草稿 - PHP环境下用cURL实现分片上传的示例代码片段:
// $content为你的完整正文内容字符串 $contentLength = strlen($content); $chunkSize = 2 * 1024 * 1024; // 2MB分片 $offset = 0; while ($offset < $contentLength) { $chunk = substr($content, $offset, $chunkSize); $currentChunkLength = strlen($chunk); $headers = [ "Content-Length: $currentChunkLength", "Content-Range: bytes $offset-".($offset + $currentChunkLength - 1)."/$contentLength" ]; $ch = curl_init($uploadUrl); curl_setopt($ch, CURLOPT_PUT, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $chunk); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); curl_close($ch); $offset += $currentChunkLength; }
方案2:内嵌附件降容方案
如果你的正文是HTML格式且包含大量图片、音视频等静态资源,可通过拆分资源降低正文本身大小:
- 提取HTML正文中所有的静态资源,单独作为附件上传到草稿,设置
isInline属性为true,并指定唯一contentId - 把HTML正文中的资源引用地址替换为
cid:{对应的contentId} - 处理后的纯HTML框架大小通常远小于3MB,可以直接通过PATCH请求更新草稿正文
PHP Microsoft Graph SDK适配代码
如果你使用composer引入的microsoft/microsoft-graph库,可以直接调用SDK封装的可恢复上传能力,无需手动实现分片逻辑:
use Microsoft\Graph\Graph; use Microsoft\Graph\Model\Message; use Microsoft\Graph\Model\UploadSession; $graph = new Graph(); $graph->setAccessToken($yourAccessToken); // 创建空白草稿 $draft = new Message(); $draft->setSubject("大正文测试邮件"); $draft->setToRecipients([/* 你的收件人配置 */]); $createdDraft = $graph->createRequest("POST", "/me/messages") ->attachBody($draft) ->setReturnType(Message::class) ->execute(); $draftId = $createdDraft->getId(); // 创建上传会话 $session = $graph->createRequest("POST", "/me/messages/$draftId/createUploadSession") ->attachBody([ "item" => [ "@odata.type" => "microsoft.graph.message", "body" => [ "contentType" => "HTML", "content" => "" ] ] ]) ->setReturnType(UploadSession::class) ->execute(); // 上传正文内容,本地存为文件或直接读入内存均可 $bodyFile = fopen("path/to/your/large_body.html", "r"); $uploadResult = $graph->createUploadRequest($session, $bodyFile) ->setReturnType(Message::class) ->upload(); fclose($bodyFile);
内容的提问来源于stack exchange,提问作者Richard Toth
相关产品推荐
相关产品推荐

