Browse Source

reply-to working

master
pvincent 3 years ago
parent
commit
ea4da3c270
  1. 1
      cagette.hxml
  2. 6
      src/controller/Messages.hx
  3. 37
      src/sugoi/mail/Mail.hx
  4. 25
      src/sugoi/mail/SendEmailMailer.hx
  5. 68
      src/sugoi/mail/SmtpMailer.hx

1
cagette.hxml

@ -21,6 +21,7 @@
-lib tink_streams:0.2.1 -lib tink_streams:0.2.1
-lib tink_syntaxhub:0.4.3 -lib tink_syntaxhub:0.4.3
-lib tink_typecrawler:0.7.0 -lib tink_typecrawler:0.7.0
-lib thx.text:0.2.1
## GIT ## GIT
# -lib sugoi:git:https://git.artcode.re/cagetters/sugoi.git # -lib sugoi:git:https://git.artcode.re/cagetters/sugoi.git

6
src/controller/Messages.hx

@ -51,7 +51,7 @@ class Messages extends Controller {
// send mail confirmation link // send mail confirmation link
var e = new sugoi.mail.Mail(); var e = new sugoi.mail.Mail();
e.setSender(App.config.get("default_email"));
e.setSender(App.config.get("default_email"), t._("Cagette.net"));
e.setSubject(subject); e.setSubject(subject);
var replyTo = form.getValueOf("senderMail"); var replyTo = form.getValueOf("senderMail");
@ -62,8 +62,6 @@ class Messages extends Controller {
for (x in mails) for (x in mails)
e.addRecipient(x); e.addRecipient(x);
// sender : default email ( explicitly tells that the server send an email on behalf of the user )
// e.setHeader("Sender", App.config.get("default_email"));
var text:String = form.getValueOf("text"); var text:String = form.getValueOf("text");
var html = app.processTemplate("mail/message.mtt", {text: text, group: app.user.amap, list: getListName(listId)}); var html = app.processTemplate("mail/message.mtt", {text: text, group: app.user.amap, list: getListName(listId)});
e.setHtmlBody(html); e.setHtmlBody(html);
@ -84,6 +82,8 @@ class Messages extends Controller {
lm.insert(); lm.insert();
throw Ok("/messages", t._("The message has been sent")); throw Ok("/messages", t._("The message has been sent"));
} else {
App.log('Administrator #${app.user.id} <${senderName}> prepares sending an email from choices list');
} }
view.form = form; view.form = form;

37
src/sugoi/mail/Mail.hx

@ -1,17 +1,24 @@
package sugoi.mail; package sugoi.mail;
using Lambda;
class Mail implements IMail
{
using Lambda;
class Mail implements IMail {
public var title:String; public var title:String;
public var htmlBody:String; public var htmlBody:String;
public var textBody:String; public var textBody:String;
var headers:Map<String, String>; var headers:Map<String, String>;
var sender:{name:String, email:String, ?userId:Int}; var sender:{name:String, email:String, ?userId:Int};
var recipients:Array<{name:String, email:String, ?userId:Int}>; var recipients:Array<{name:String, email:String, ?userId:Int}>;
static public function fromString(name:String, email:String) {
if (name == null)
return email;
else {
var finalName = thx.text.Diactrics.clean(name);
return '${finalName} <${email}>';
}
}
public function new() { public function new() {
recipients = []; recipients = [];
@ -23,16 +30,17 @@ class Mail implements IMail
} }
public function setSender(email, ?name, ?userId) { public function setSender(email, ?name, ?userId) {
if(!isValid(email)) throw "invalid sender email : \""+email+"\"";
if (!isValid(email))
throw "invalid sender email : \"" + email + "\"";
sender = {name: name, email: email, userId: userId}; sender = {name: name, email: email, userId: userId};
return this; return this;
} }
public function setReplyTo(email, ?name) { public function setReplyTo(email, ?name) {
if(!isValid(email)) throw "invalid reply-to email : \""+email+"\"";
setHeader("Reply-To","<"+email+">"+(name==null?"":name));
if (!isValid(email))
throw "invalid reply-to email : \"" + email + "\"";
setHeader("Reply-To", fromString(name, email));
} }
public function setSubject(s:String) { public function setSubject(s:String) {
@ -47,7 +55,8 @@ class Mail implements IMail
* @param ?userId * @param ?userId
*/ */
public function addRecipient(email:String, ?name:String, ?userId:Int) { public function addRecipient(email:String, ?name:String, ?userId:Int) {
if(!isValid(email)) throw "invalid recipient \""+email+"\"";
if (!isValid(email))
throw "invalid recipient \"" + email + "\"";
recipients.push({email: email, name: name, userId: userId}); recipients.push({email: email, name: name, userId: userId});
return this; return this;
} }
@ -88,7 +97,8 @@ class Mail implements IMail
public function setHtmlBodyWithTemplate(tpl, ctx:Dynamic) { public function setHtmlBodyWithTemplate(tpl, ctx:Dynamic) {
var app = App.current; var app = App.current;
var tpl = app.loadTemplate(tpl); var tpl = app.loadTemplate(tpl);
if( ctx == null ) ctx = { };
if (ctx == null)
ctx = {};
ctx.HOST = App.config.HOST; ctx.HOST = App.config.HOST;
ctx.key = getKey(); ctx.key = getKey();
ctx.senderName = sender.name; ctx.senderName = sender.name;
@ -98,7 +108,6 @@ class Mail implements IMail
ctx.recipients = recipients; ctx.recipients = recipients;
CSSInlining(ctx); CSSInlining(ctx);
htmlBody = tpl.execute(ctx); htmlBody = tpl.execute(ctx);
} }
public function setHtmlBody(s) { public function setHtmlBody(s) {
@ -109,14 +118,14 @@ class Mail implements IMail
public function setTextBodyWithTemplate(tpl, ctx:Dynamic) { public function setTextBodyWithTemplate(tpl, ctx:Dynamic) {
var app = App.current; var app = App.current;
var tpl = app.loadTemplate(tpl); var tpl = app.loadTemplate(tpl);
if( ctx == null ) ctx = { };
if (ctx == null)
ctx = {};
ctx.HOST = App.config.HOST; ctx.HOST = App.config.HOST;
ctx.key = getKey(); ctx.key = getKey();
textBody = tpl.execute(ctx); textBody = tpl.execute(ctx);
return this; return this;
} }
function CSSInlining(ctx) { function CSSInlining(ctx) {
// CSS inlining // CSS inlining
var css:Map<String, Array<String>> = new Map(); var css:Map<String, Array<String>> = new Map();
@ -149,7 +158,6 @@ class Mail implements IMail
} }
} }
public function getSubject() { public function getSubject() {
return title; return title;
} }
@ -178,5 +186,4 @@ class Mail implements IMail
public function getSender() { public function getSender() {
return sender; return sender;
} }
} }

25
src/sugoi/mail/SendEmailMailer.hx

@ -40,17 +40,13 @@ class SendEmailMailer implements IMailer {
return mailer; return mailer;
} }
private function fromString(name:String, email:String) {
return (name == null) ? email : '${name} <${email}>';
}
public function send(e:sugoi.mail.IMail, ?params:Dynamic, ?callback:MailerResult->Void) { public function send(e:sugoi.mail.IMail, ?params:Dynamic, ?callback:MailerResult->Void) {
var to:String; var to:String;
var bcc:String; var bcc:String;
var recipientCounts = e.getRecipients().length; var recipientCounts = e.getRecipients().length;
if (recipientCounts > 1) { if (recipientCounts > 1) {
to = fromString(e.getSender().name, e.getSender().email);
to = sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email);
bcc = [for (i in e.getRecipients()) i.email].join(","); bcc = [for (i in e.getRecipients()) i.email].join(",");
App.log('recipients has been transformed to ${recipientCounts} bcc'); App.log('recipients has been transformed to ${recipientCounts} bcc');
App.log(bcc); App.log(bcc);
@ -72,26 +68,35 @@ class SendEmailMailer implements IMailer {
"-o", "-o",
"message-format=html", "message-format=html",
"-o", "-o",
"X-Mailer=CagettePei",
"message-header=X-Mailer: CagettePei",
"-f", "-f",
fromString(e.getSender().name, e.getSender().email),
sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email),
"-t", "-t",
to, to,
"-bcc", "-bcc",
bcc, bcc,
"-u", "-u",
e.getSubject(), e.getSubject(),
"-m",
'<html>${e.getHtmlBody()}</html>',
]; ];
// FIME: deal with replyTo
if (e.getHeaders().exists("Reply-To")) {
var replyTo = e.getHeaders()["Reply-To"];
App.log('replyTo "$replyTo" detected');
args.push("-o");
args.push('message-header=Reply-To: ${replyTo}');
}
args.push("-m");
args.push('<html>${e.getHtmlBody()}</html>');
// if (App.config.DEBUG) // if (App.config.DEBUG)
// App.log('args=${args.join(" ")}'); // App.log('args=${args.join(" ")}');
var exitCode = Sys.command("sendemail", args); var exitCode = Sys.command("sendemail", args);
// var exitCode = 0; // var exitCode = 0;
var summary = 'email from="${fromString(e.getSender().name, e.getSender().email)}"> subject=<${e.getSubject()}>';
var summary = 'email from="${sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email)}" subject=<${e.getSubject()}>';
if (exitCode == 0) if (exitCode == 0)
App.log('$summary successfully sent'); App.log('$summary successfully sent');
else else

68
src/sugoi/mail/SmtpMailer.hx

@ -1,68 +0,0 @@
package sugoi.mail;
import tink.core.Future;
import tink.core.Noise;
import sugoi.mail.IMailer;
import smtpmailer.Address;
/**
* Send emails thru SMTP by using ben merckx's library
* @ref https://github.com/benmerckx/smtpmailer
*/
class SmtpMailer implements IMailer
{
var m : smtpmailer.SmtpMailer;
public function new(){}
public function init(?conf:{smtp_host:String,smtp_port:Int,smtp_user:String,smtp_pass:String}) :IMailer
{
m = new smtpmailer.SmtpMailer({
host: conf.smtp_host,
port: conf.smtp_port,
auth: {
username: conf.smtp_user,
password: conf.smtp_pass
}
});
return this;
}
public function send(e:sugoi.mail.IMail,?params:Dynamic,?callback:MailerResult->Void)
{
var surprise = m.send({
subject: e.getSubject(),
/*from: e.getSender().email,
to: Lambda.array(Lambda.map(e.getRecipients(), function(x) return smtpmailer.Address.ofString(x.email) )),
//headers : e.getHeaders(),*/
from: new Address({address:e.getSender().email}),
to: Lambda.array(Lambda.map(e.getRecipients(), function(x) return new Address({address:x.email}) )),
headers : e.getHeaders(),
content: {
text: e.getTextBody(),
html: e.getHtmlBody()
}/*,
attachments: []*/
});
if (callback != null){
surprise.handle(function(s){
var map = new MailerResult();
switch(s){
case Success(_):
map.set("*",Success(Sent));
case Failure(e):
map.set("*",Failure(GenericError(e)));
}
callback(map);
});
}
}
}
Loading…
Cancel
Save