问题描述
我正在重建my personal website in Flutter,需要在填写表格后发送电子邮件
内容:我正在尝试使用Gmail API Dart库发送电子邮件
错误:DetailedApiRequestError(状态:400,消息:“ message.raw”处的值无效(TYPE_BYTES),调用“发送”时Base64解码失败
身份验证正常。我按照googleapis程序包中的步骤使用服务帐户和'clientViaServiceAccount'方法来实现身份验证。
我遵循了Gmail API documentation for sending an email using the send method,创建了MimeMessage,将其格式化为RFC 2822并将其编码为base64url,创建了Message对象,并将'raw'属性设置为已编码的MimeMessage,然后将GmailAPI称为'send'方法。
问题似乎与MimeMessage的编码有关。
我使用enough_mail package创建了MimeMessage并将消息设置为Base 64编码
以下是Github上该项目的链接:https://github.com/ashtonjonesdev/ashton_jones_dev_website “发送”方法位于consulting.dart
中感谢您的帮助!如果您可以帮助我解决此问题,请在我的文章中大声疾呼
发送电子邮件代码:
sendEmail() async {
print('sendEmail');
// Create a Mime Message and encode it using base64
MessageBuilder messageBuilder = MessageBuilder();
messageBuilder.from = [
MailAddress('Ashton Jones','ashton@grapeworks.dev')
];
messageBuilder.to = [MailAddress('Ashton Jones','ashtonjonesdev@gmail.com')];
messageBuilder.subject = 'cool subject';
messageBuilder.text = 'cool text';
messageBuilder.encoding = MessageEncoding.base64;
// Added Rfc822 encoding
messageBuilder.contentType = ContentTypeHeader.from(MediaType.fromSubtype(MediaSubtype.messageRfc822));
messageBuilder.messageId = '1';
MimeMessage mimeMessage = messageBuilder.buildMimeMessage();
// Ensure body is also encoded as base64 and Rfc822
mimeMessage.body = BodyPart();
mimeMessage.body.contentType = ContentTypeHeader.from(MediaType.fromSubtype(MediaSubtype.messageRfc822));
mimeMessage.body.encoding = 'base64';
// Create a Message object and set the 'raw' property to the encoded String
Message message = Message();
// TODO Need to set the 'raw' property as the entire encoded MimeMessage
// TODO: Figure out if I need to encode the entire MimeMessage as a base 64 String here again (I already set the encoding of the MimeMessage to base64 on line 156)
// Should return the entire encoded MimeMessage
String encodedMimeMessage = mimeMessage.renderMessage();
// Error happening here
message.raw = encodedMimeMessage;
print('Encoded message: ${message.raw}');
// Send the email using the Gmail API 'send' method
// TODO: When I run this,I get an 'invalid value at 'message.raw' (TYPE_BYTES),Base64 decoding failed' error
Message messageCompleted =
await _gmailApi.users.messages.send(message,'me').catchError((error) {
print(error);
});
print(messageCompleted);
}
initState代码:
@override
void initState() {
super.initState();
print(
'CREDENTIALS: Client ID: ${_credentials.clientId.toString()} | Client Secret: ${_credentials.privateKey}');
// Authenticate the credentials with the service account and use them to initialize the GmailAPI
clientViaServiceAccount(_credentials,scopes).then((AuthClient httpClient) {
_gmailApi = GmailApi(httpClient);
print('Users: ${_gmailApi.users}');
});
}
解决方法
我认为您可能必须像这样对mimeMessage进行编码,
message.raw = base64.encode(utf8.encode(mimeMessage.renderMessage()));
,
我实现了使用“ mailto”和“ url_launcher” Flutter软件包使用“ mailto”方法发送电子邮件的方法。它必须打开客户端的电子邮件应用程序,但效果很好。用于Dart的Gmail API很糟糕,并且没有文档,所以我建议您采取另一种方法。
// Send email using mail_to and url_launcher packages
sendEmail()异步{
print('sendEmail');
final mailtoLink = Mailto(
to: ['ashtonjonesdev@gmail.com'],subject: '$_subject',body: '$_message',);
// Convert the Mailto instance into a string.
// Use either Dart's string interpolation
// or the toString() method.
await launch('$mailtoLink');
}