如何修改Flutter中调用Gmail API的代码以支持发送邮件附件?
给Gmail API发送的邮件添加附件
要实现带附件的邮件,你需要把原纯文本邮件改成多部分MIME格式(multipart/mixed),以下是修改后的完整代码和关键说明:
核心修改点
- 邮件内容改为
multipart/mixed类型,拆分出纯文本正文和附件两个MIME部分 - 附件需先读取为字节流,再做Base64编码
- 用唯一边界字符串分隔不同MIME部分,避免内容冲突
修改后的完整代码
import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; Map<String, String> header = { 'Authorization': authorizationHeader, 'X-Goog-AuthUser': xGoogAuthUserHeader, 'Accept': 'application/json', 'Content-type': 'application/json', }; // 生成带附件的MIME格式邮件 Future<String> createEmailWithAttachment( String to, String from, String subject, String bodyText, File attachmentFile, ) async { // 生成唯一边界字符串,用于分隔MIME段落 final boundary = '----GmailApiBoundary${DateTime.now().millisecondsSinceEpoch}'; // 读取附件并编码为Base64 final attachmentBytes = await attachmentFile.readAsBytes(); final attachmentBase64 = base64Encode(attachmentBytes); final fileName = attachmentFile.path.split('/').last; return ''' MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="$boundary" to: $to from: $from subject: ${base64Encode(utf8.encode(subject))} --$boundary Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit $bodyText --$boundary Content-Type: application/octet-stream Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="$fileName" $attachmentBase64 --$boundary-- '''; } // 发送带附件邮件的调用示例 Future<void> sendEmailWithAttachment() async { // 替换为实际收件人、发件人信息 final to = 'recipient@example.com'; final from = user.email!; final subject = '带附件的测试邮件'; final bodyText = '这是邮件正文内容'; // 替换为你的附件文件路径 final attachmentFile = File('/storage/emulated/0/Documents/test.pdf'); final formattedEmail = await createEmailWithAttachment(to, from, subject, bodyText, attachmentFile); // 编码为Gmail API要求的格式 final bytes = utf8.encode(formattedEmail); final base64Email = base64Encode(bytes); final body = json.encode({'raw': base64Email}); final httpsUri = Uri( scheme: 'https', host: 'www.googleapis.com', path: '/gmail/v1/users/${user.email}/messages/send', ); final response = await http.post(httpsUri, headers: header, body: body); // 可选:处理发送结果 if (response.statusCode == 200) { print('邮件发送成功'); } else { print('发送失败:${response.body}'); } }
关键细节说明
- 主题编码:Gmail API要求邮件主题遵循RFC 2047标准,需先将主题字符串UTF8编码再做Base64编码
- 附件Content-Type:示例中用
application/octet-stream通用类型,可根据附件实际类型修改(如图片用image/jpeg、Excel用application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) - 文件权限:移动端需确保已申请文件读取权限,否则无法读取附件
- 边界字符串:用时间戳生成唯一值,避免和邮件正文/附件内容冲突
内容的提问来源于stack exchange,提问作者solacking
相关产品推荐
相关产品推荐

