Метод Dart Gmail API ‘send’ возвращает DetailedApiRequestError

#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');
  

}