Как добавить вложение с помощью mailgun в dart с http?

#http #dart #attachment #mailgun

#http #dart #вложение #mailgun

Вопрос:

Mailgun официально поддерживает http, но по состоянию на сентябрь 2020 года официального пакета для Dart нет. Электронное письмо отправляется успешно, но вложение отсутствует. Обратите внимание на все неудачные попытки.

 import 'dart:io';
import 'package:http/http.dart' as foo;

// must be https for basic auth (un   pw)
const secureProtocol = 'https://';
const host = 'api.mailgun.net/v3/m.givenapp.com/messages';

// basic auth
const userApiKey = 'my api key here'; // pw
const un = 'api';

void main() async {
  //
  const path = 'bin/services/foo.baz.txt';
  var file = File(path);
  print(file.existsSync()); // looks good
  print(file.readAsStringSync()); // looks good
  var list = <String>[];
  list.add(file.readAsStringSync());
  var files = <File>[];
  files.add(file);
  //
  var body = <String, dynamic>{};
  body.putIfAbsent('from', () => 'John Smith <john.smith@example.com>');
  body.putIfAbsent('to', () => 'jane.doe@somehost.com');
  body.putIfAbsent('subject', () => 'test subject  '   DateTime.now().toIso8601String());
  body.putIfAbsent('text', () => 'body text');

  // fixme
  body.putIfAbsent('attachment', () => '@$path'); // failed
  body.putIfAbsent('attachment', () => path); // failed
  //body.putIfAbsent('attachment', () => file); // failed
  //body.putIfAbsent('attachment', () => list); // failed
  //body.putIfAbsent('attachment', () => files); // failed
  body.putIfAbsent('attachment', () => file.readAsStringSync()); // failed
  //body.putIfAbsent('attachment', () => file.readAsBytesSync()); // failed

  final uri = '$secureProtocol$un:$userApiKey@$host';

  final response = await foo.post(uri, body: body);

  print('Response status: ${response.statusCode}');
  print('Response body: ${response.body}');
}
  

Я думаю, что я близок.

https://documentation.mailgun.com/en/latest/api-sending.html#sending

Ответ №1:

Документы, на которые вы ссылались, говорят

Важно: при отправке вложений необходимо использовать кодировку multipart / form-data.

Итак, вы хотите выполнить MultipartRequest , а не просто обычный post-запрос.

Это можно сделать примерно с помощью следующего кода, используя тот же http-пакет, который вы уже используете.

 var request = foo.MultipartRequest(
  'POST',
  Uri.parse('$secureProtocol$un:$userApiKey@$host')
);

var body = <String, dynamic>{};
body.putIfAbsent('from', () => 'John Smith <john.smith@example.com>');
body.putIfAbsent('to', () => 'jane.doe@somehost.com');
body.putIfAbsent('subject', () => 'test subject  '   DateTime.now().toIso8601String());
body.putIfAbsent('text', () => 'body text');

request.fields = body;

request.headers["Content-Type"] = "multipart/form-data";
request.files.add(await http.MultipartFile.fromPath('attachment', path));

var response = await request.send();
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');
  

Все делается так же с добавлением полей from, to, subject и text, просто добавляя его к fields параметрам MultipartRequest .

Заголовки были изменены, чтобы указать правильный тип. A MultipartFile создается по пути и задается именем поля attachment . Это добавляется к части файлов MultipartRequest .

Затем запрос отправляется и обрабатывается аналогично тому, что у вас уже было.


Если вы хотите сделать это проще, вы можете попробовать mailgun пакет, который сделает все это за вас.

Комментарии:

1. Это был самый вежливый способ сказать «RTFM». Этот парень заслуживает ордена чести.