You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.5 KiB

  1. package sugoi.mail;
  2. import tink.core.Future;
  3. import tink.core.Noise;
  4. import sugoi.mail.IMailer;
  5. import smtpmailer.Address;
  6. typedef SmtpInfo = {
  7. host:String,
  8. port:Int,
  9. auth:{
  10. username:String, password:String
  11. }
  12. }
  13. /**
  14. * Send emails thru OS command `sendemail`
  15. * requires: `apt install sendemail libio-socket-ssl-perl libnet-ssleay-perl`
  16. */
  17. class SendEmailMailer implements IMailer {
  18. var m:SmtpInfo;
  19. public function new() {}
  20. public function init(?conf:{
  21. smtp_host:String,
  22. smtp_port:Int,
  23. smtp_user:String,
  24. smtp_pass:String
  25. }):IMailer {
  26. var mailer:SendEmailMailer = new SendEmailMailer();
  27. mailer.m = {
  28. host: conf.smtp_host,
  29. port: conf.smtp_port,
  30. auth: {
  31. username: conf.smtp_user,
  32. password: conf.smtp_pass
  33. }
  34. };
  35. return mailer;
  36. }
  37. public function send(e:sugoi.mail.IMail, ?params:Dynamic, ?callback:MailerResult->Void) {
  38. var to:String;
  39. var bcc:String;
  40. var recipientCounts = e.getRecipients().length;
  41. if (recipientCounts > 1) {
  42. to = sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email);
  43. bcc = [for (i in e.getRecipients()) i.email].join(",");
  44. App.log('recipients has been transformed to ${recipientCounts} bcc');
  45. App.log(bcc);
  46. } else {
  47. to = e.getRecipients()[0].email;
  48. bcc = "";
  49. }
  50. var args = [
  51. // arguments
  52. "-s",
  53. '${this.m.host}:${this.m.port}',
  54. "-xu",
  55. ${this.m.auth.username},
  56. "-xp",
  57. ${this.m.auth.password},
  58. "-o",
  59. "message-charset=utf-8",
  60. "-o",
  61. "message-format=html",
  62. "-o",
  63. "message-header=X-Mailer: CagettePei",
  64. "-f",
  65. sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email),
  66. "-t",
  67. to,
  68. "-bcc",
  69. bcc,
  70. "-u",
  71. e.getSubject(),
  72. ];
  73. // FIME: deal with replyTo
  74. if (e.getHeaders().exists("Reply-To")) {
  75. var replyTo = e.getHeaders()["Reply-To"];
  76. App.log('replyTo "$replyTo" detected');
  77. args.push("-o");
  78. args.push('message-header=Reply-To: ${replyTo}');
  79. }
  80. args.push("-m");
  81. args.push('<html>${e.getHtmlBody()}</html>');
  82. // if (App.config.DEBUG)
  83. // App.log('args=${args.join(" ")}');
  84. var exitCode = Sys.command("sendemail", args);
  85. // var exitCode = 0;
  86. var summary = 'email from="${sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email)}" subject=<${e.getSubject()}>';
  87. if (exitCode == 0)
  88. App.log('$summary successfully sent');
  89. else
  90. App.log('ERROR: $summary cannot be sent, please review logs');
  91. if (callback != null) {
  92. var map = new MailerResult();
  93. if (exitCode == 0)
  94. map.set("*", Success(Sent));
  95. else
  96. map.set("*", Failure(HardBounce));
  97. callback(map);
  98. }
  99. }
  100. }