#flutter #dart #gmail-api
#flutter #dart #gmail-api
Вопрос:
Я перестраиваю свой личный веб-сайт в Flutter, и мне нужно отправить электронное письмо после заполнения формы
ЧТО: Я пытаюсь отправить электронное письмо, используя библиотеку Dart API Gmail
ОШИБКА: DetailedApiRequestError (статус: 400, сообщение: недопустимое значение в ‘сообщении.raw’ (TYPE_BYTES), сбой декодирования Base64 при вызове ‘send’
Аутентификация работает нормально. Я выполнил шаги в пакете googleapis, чтобы реализовать аутентификацию, используя учетную запись службы и метод clientViaServiceAccount.
Я следовал документации Gmail API для отправки электронного письма с использованием метода send, создания MimeMessage, форматирования его в RFC 2822 и кодирования в base64url, создания объекта Message и установки свойства ‘raw’ для закодированного MimeMessage и вызова метода GmailAPIs ‘send’.
Похоже, проблема связана с кодировкой MimeMessage.
Я создал MimeMessage, используя пакет enough_mail, и установил для сообщения базовую кодировку 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);
}
Код инициализации:
@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}');
});
}
Ответ №1:
Я думаю, что вам, возможно, придется закодировать ваше MimeMessage следующим образом,
message.raw = base64.encode(utf8.encode(mimeMessage.renderMessage()));
Ответ №2:
Я реализовал отправку электронной почты с использованием подхода «mailto», используя пакеты Flutter ‘mail_to’ и ‘url_launcher’. Для этого нужно открыть почтовое приложение клиента, но оно работает просто отлично. API Gmail для Dart ужасен, и нет документации, поэтому я бы предложил просто использовать другой подход.
// 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');
}