This package allows to create and send emails in a very simple form; you don't need to know about the mailing RFC, MimeMessage or any other low level mail APIs. Also, mailClient Object takes care of all the connection and security properties for you.

1 Mailer

Mailer object can be created invoking a new Ax.mail.Mailer Constructor.

Copy
<script>
    var mail = new Ax.mail.MailerMessage();
    mail.to("user@destination.com");
    mail.subject("Hello from JS");
    mail.setText("Hello world!\nBye.");
    
    var mailer = new Ax.mail.Mailer();
    mailer.setSMTPServer("authsmtp.myserver.com", 25);
    mailer.setSMTPUsername("john@myserver.com");
    mailer.setSMTPPassword("*****2016");
    mailer.testConnection();
    
    mailer.send(mail);
</script>
Return Method Description
Mailer Ax.mail.Mailer() Constructor of client SMTP mail Object with clear text SMTP authentication
Mailer Ax.mail.Mailer("SMTP_TLS") Constructor of client SMTP mail Object with SMTP TLS authentication
Mailer Ax.mail.Mailer("SMTPS") Constructor of client SMTP mail Object with SSL encryption
Mailer setSMTPServer(String host, int port) Configures SMTP host and connection port
Mailer setSMTPUsername(String user) Configures user name for SMTP authentication
Mailer setSMTPPassword(String password) Configures user password for SMTP authentication
Mailer setProxyHost(String host) Mailer Object supports sending emails through a proxy. This method configures proxy host.
Mailer setProxyPort(int port) Configures proxy port for relaying SMTP server connection
Mailer setProxyUser(String username) Configures user for authenticated proxies
Mailer setProxyPassword(String password) Configures password for authenticated proxies
Mailer setTrustSSLHosts(String ...hosts) White list hosts for SSL connections, don't validate keys for these
Mailer setTrustAllSSLHosts() Trust all hosts for SSL connections, don't validate keys
Mailer setSessionTimeout(int millis) Change the session timeout (affects socket connect-, read- and write timeouts)
boolean isValid(String address) validate email addresses. It's not just a simple regex check, but a complete and robust full validation against RFC-2822. Address validation is performed automatically when sending emails, but you can also use this method directly to perform validations.
Mailer testConnection() Executes a connection test using your current configuration, including transport strategy and (authenticated) proxy. No error means success.
void send(JSMail mail) Sends email synchronously, blocking execution until the email was processed completely and the STMP server sent a succesful result.
void send(JSMail mail, boolean async) Sends the email getting the generated email id after sending like <1420232606.6.1509560747190@Cypher>. Second parameter defines if mail sending is executed synchronously or nyschronously in parallel or batches, or simply send in a fire-and-forget way. Depending on the SMTP server (and proxy server if used) this can greatly influence how fast emails are sent.

2 MailerMessage

MailerMessage object can be created invoking a new Ax.mail.MailerMessage Constructor and stores content of an e-Mail Message.

Return Method Description
JSMail Ax.mail.MailerMessage() Constructor of e-Mail Object
MailerMessage addHeader(String name, Object value) Adds extra headers in your email because your email server, recipient server or your email client needs it: e.g. .addHeader("X-Priority", 2);
MailerMessage setMessageId(String id) Message id's are normally generated by the underlying framework, but you can provide your own if required. Just make sure your own id's conform to the rfc5322 msg-id format standard like <123@456>
MailerMessage to(String oneOrMoreAddresses) Adds "to" addresses to e-mail. Multiple comma / semicolon separated addresses are supported.
MailerMessage to(String name, String address) Adds "to" addresses to e-mail. Explicit destination name is defined in first parameter and e-mail address in second: e.g.: .to("John Smith", "john@acme.com")
MailerMessage toWithDefaultName(String name, String oneOrMoreAddresses) Adds "to" addresses to e-mail. All addresses passed without explicit name will get default name from first parameter.
MailerMessage cc(String oneOrMoreAddresses) Adds "cc" addresses to e-mail. Multiple comma / semicolon separated addresses are supported.
MailerMessage cc(String name, String address) Adds "cc" addresses to e-mail. Explicit destination name is defined in first parameter and e-mail address in second: e.g.: .to("John Smith", "john@acme.com")
MailerMessage ccWithDefaultName(String name, String oneOrMoreAddresses) Adds "cc" addresses to e-mail. All addresses passed without explicit name will get default name from first parameter.
MailerMessage bcc(String oneOrMoreAddresses) Adds "bcc" addresses to e-mail. Multiple comma / semicolon separated addresses are supported.
MailerMessage bcc(String name, String address) Adds "bcc" addresses to e-mail. Explicit destination name is defined in first parameter and e-mail address in second: e.g.: .to("John Smith", "john@acme.com")
MailerMessage bccWithDefaultName(String name, String oneOrMoreAddresses) Adds "bcc" addresses to e-mail. All addresses passed without explicit name will get default name from first parameter.
MailerMessage from(String fromAddress) .
MailerMessage reply(String replyToAddress) .
MailerMessage subject(String subject) Defines e-mail subject.
MailerMessage setText(String text) Defines e-mail body in text format.
MailerMessage setHtml(String text) Defines e-mail body in html format.
MailerMessage addAttachment(String name, Object data, String contentType) Attach an object (file, byte[] or Blob) to e-mail. You should define attachment name and mime-type manually.
MailerMessage addAttachment(String name, JSFile file) Attach a file to e-mail. You should define file name manually.
MailerMessage addAttachment(JDBCBlobJMEM data) Attach a Blob to e-mail.
MailerMessage addEmbeddedImage(String name, Object data, String contentType) Adds an image object (file, byte[] or Blob) to be used in HTML e-mail body. Name provided should be used in html reference: <img src='cid: name'>
MailerMessage addEmbeddedImage(String name, JSFile file) Adds an image from a file to be used in HTML e-mail body. Name provided should be used in html reference: <img src='cid: name'>
MailerMessage addEmbeddedImage(JDBCBlobJMEM data) Adds an image from a Blob to be used in HTML e-mail body. Name provided should be used in html reference: <img src='cid: name'>
MailerMessage setDispositionNotificationTo() For servers and clients that support it (mostly Outlook at offices), enables support for 'delivery receipt'
MailerMessage setDispositionNotificationTo(String name, String address) For servers and clients that support it (mostly Outlook at offices), enables support for 'delivery receipt'. Configures an alternative e-mail address to send the receipt.
MailerMessage setReturnReceiptTo() For servers and clients that support it (mostly Outlook at offices), enables support for 'read receipt'
MailerMessage setReturnReceiptTo(String name, String address) For servers and clients that support it (mostly Outlook at offices), enables support for 'read receipt'. Configures an alternative e-mail address to send the receipt.
String getMessageContent(String[] ignoreList) Output the message as an RFC 822 format stream, without specified headers.
MimeMessage toMimeMessage() Return the message as a javax.mail.internet.MimeMessage Java Class.

3 Examples

Let's see a few send main examples.

3.1 Basic example

Simple a mail to a group of destinations.

Copy
<script>
    var mail = new Ax.mail.MailerMessage();
    mail.from("user@source.com");
    mail.to("user@destination.com");
    mail.to("user2@destination.com");
    mail.cc("user3@destination.com");
    mail.bcc("user4@destination.com");
    mail.subject("Hello from JS");
    mail.setText("Hello world!\nBye.");
    
    console.log(mail.getMessageContent(["From", "Message-ID"]));

    var mailer = new Ax.mail.Mailer();
    mailer.setSMTPServer("authsmtp.myserver.com", 25);
    mailer.setSMTPUsername("john@myserver.com");
    mailer.setSMTPPassword("*****2016");
    mailer.send(mail);
</script>

3.2 Sending attachments

Send an email with attachments

3.2.1 Sending file attachments

Copy
<script>
    var mail = new Ax.mail.MailerMessage()
        .from("user@source.com")
        .to("Xavier <user1@acme.net>")
        .cc("Vicente <user2@acme.net>")
        .subject("Hello from JS (Advanced)")
        .from("coyote@acme.com")
        .reply("coyoteReply@acme.com")
        .setText("Hello world in Test 2!\nJust in case you don't have HTML support in your e-mail client.")
        .setHtml("<h1>Message header</h1><p>Hello world in advanced text!.</p><img src=\"cid:imagedata\"/><p>You should see and image on top of this parragraph</p>")
        .addEmbeddedImage("imagedata", new Ax.net.URL("https://apod.nasa.gov/apod/image/1902/RedSprites_Broady_960.jpg").getBytes(), "image/jpg")
        .addAttachment("M82Magnet_SOFIA_960.jpg", new Ax.net.URL("https://apod.nasa.gov/apod/image/1903/M82Magnet_SOFIA_960.jpg").getBytes(), "image/jpg")
        ;

    console.log(mail.getMessageContent(null));

    var mailer = new Ax.mail.Mailer()
        .setSMTPServer("authsmtp.myserver.com", 25)
        .setSMTPUsername("john@myserver.com")
        .setSMTPPassword("*****2016")
        ;
    
    console.log(mailer.send(mail, false));
</script>
<866370634.3.1553009476240@titan>

3.2.2 Sending BLOB attachments

Copy
<script>
    var data = [
    	["1","China",                   1378020000,1578020000],
    	["2","India",                   1266884000,1366884000],
    	["3","United States of America", 323128000, 353128000],
    	["4","Indonesia",                257453000, 37453000 ],
    	["5","Brazil",                   206081000, 246081000]
    ];
    
    // ==================================================================
    // Create an Excel workbook and sheet
    // ==================================================================
    var wb = new Ax.ms.Excel("countries");
    var sheet = wb.createSheet("sheet1");
    
    // Add data to sheet starting at col=1, row=1 ( $B$2 )
    sheet.addRows(1, 1, data);

    // ==================================================================
    // Create an e-mail Object
    // addAttachment receives a blob. Attachment name and mimetype are
    // retrieved automatically from Blob
    // ==================================================================
    var mail = new Ax.mail.MailerMessage()
        .to("user1@acme.es")
        .cc("user2@acme.es")
        .from("coyote@acme.com")
        .subject("Hello from JS (Advanced)")
        .setText("Please see attached Excel.")
        .addAttachment(wb.toBlob());
    
    // ==================================================================
    // Creates and SMTP connection with server and authenticates with user
    // ==================================================================
    var mailer = new Ax.mail.Mailer("SMTP")
    mailer.setSMTPServer("authsmtp.myserver.com", 587);
    mailer.setSMTPUsername("smtp@myserver.com");
    mailer.setSMTPPassword("*****2016");

    // ==================================================================
    // Sends e-mail created previously
    // ==================================================================
    console.log(mailer.send(mail, false));

</script>
<1300261503.11.1553021175324@[192.168.12.159]>

3.2.3 Sending report

Copy
<script>
// Sample data
var rows = [
    // Income Statement
    ["I", "P", "Revenue",                             102007, 118086,  142341, 150772, 158311, 158311],
    ["I", "P", "Cost of Goods Sold(COGS)",            -39023, -48004,  -49123, -52654, -58575, -58575],
    ["I", "E", "Salaries and Benefits",               26427,  22658,   23872,  23002,  25245,   26913],
    ["I", "E", "Rent and Overhead",                   10963,  10125,   10087,  11020,  11412,   10000],
    ["I", "E", "Depreciation & Amortization",         19500,  18150,   17205,  16544,  16080,   15008],
    ["I", "E", "Interest",                            2500,   2500,    1500,   1500,   1500,     1500],
    
    // Balance Sheet
    ["B", "A", "Cash",                                167971, 181210,  183715, 211063, 239550, 272530],
    ["B", "A", "Accounts Receivable",                   5100,   5904,    6567,   7117,   7539,   7807],
    ["B", "A", "Inventory",                             7805,   9601,    9825,  10531,  11342,  11715],
    ["B", "A", "Property & Equipment",                 45500,  42350,   40145,  38602,  37521,  37513],
    ["B", "L", "Accounts Payable",                      3902,   4800,    4912,   5265,   5671,   5938],
    ["B", "L", "Debt",                                 50000,  50000,   30000,  30000,  30000,  30000],
    ["B", "S", "Equity Capital",                      170000, 170000,  170000, 170000, 170000, 170000],
    ["B", "S", "Retained Earnings",                     2474,  14265,   35340,  62053,  30280, 123627],
    
    // Cash Flow Statement  
    ["C", "O", "Not Earnings",                          2474,  11791,   21075,   26713,  28227,  33346],
    ["C", "O", "Plus: Deprecation & Amortization",     19500,  18150,   17205,   16544,  16080,  15008],
    ["C", "O", "Less: Changes in Working Capital",     -9003,  -1702,    -775,    -903,   -827,  -375],
    ["C", "I", "Investments in Property & Equipment",  15000,  15000,   15000,   15000,  15000,  15000],
    ["C", "F", "Issuance(repayment) of debt",           null,   null,   20000,    null,   null,   null],
    ["C", "F", "Issuance(repayment) of equity",       170000,   null,    null,    null,   null,   null],
    ["C", "B", "Net Increase(decrease) in Cash",      167971,  13239,    2505,   27354,  28480,  32980],
    ["C", "B", "Opening Cash Balance",                  null,  167971, 181210,  183715, 211069, 239500],
];

// Build ResultSet with previously created rows 
// and add some column configurations
var rs = new Ax.rs.Reader().build(rows, options => {
    options.setColumnNames([
    "type",
    "group",
    "item",
    "2012", 
    "2013",
    "2014", 
    "2015", 
    "2016", 
    "2017"]);
});

// ========================================================================
// Decorate ResultSet
// ========================================================================
var md = rs.getMetaData();

md.setColumnLabel("item", "");
// Create a combo for type
md.setColumnCombo("type",
    {
        // Types of statements 
        "I" : "Income Statement",
        "B" : "Balance Sheet",
        "C" : "Cash Flow Statement",
    }
);

md.setColumnCombo("group",
    {
        "P" : "Balance",                // Hide group description
        "E" : "Expenses",
        "A" : "Assets",
        "L" : "Liabilities",
        "S" : "Shareholder's Equity",
        "O" : "Operating Cash Flow",
        "I" : "Investing Cash Flow",
        "F" : "Financing Cash Flow",
        "B" : "",
    }
);

// Avoid null values on item columns
md.setColumnNullValue("2012", "-");
md.setColumnNullValue("2013", "-");
md.setColumnNullValue("2014", "-");
md.setColumnNullValue("2015", "-");
md.setColumnNullValue("2016", "-");
md.setColumnNullValue("2017", "-");

rs.setTitle("Financial Statement Report");

// ========================================================================
// Generate report
// ========================================================================
var report = new Ax.rs.Report(rs);

// Group report by type
report.setGroupBy("type", "group")
    // Use a function to map total names
    .setTotalFunction((type, group) => {
    switch (group[0]) {
        case 'I':
            switch (group[1]) {
                case 'P': return 'Gross Profit';
                case 'E': return 'Total Expenses';
            }
            break;
        case 'B':
            switch (group[1]) {
                case 'A': return 'Total Assets';
                case 'L': return 'Total Liabilities';
                case 'S': return 'Shareholders Equity';
            }
            break;
        case 'C':
            switch (group[1]) {
                case 'O': return 'Cash from Operations';
                case 'I': return 'Cash from Investing';
                case 'F': return 'Cash from Financing';
                case 'B': return 'Closing Cash Balance';
            }
            break;
    }
    return "N/A";
    })
    .setTotalBy("2012", "SUM")
    .setTotalBy("2013", "SUM")
    .setTotalBy("2014", "SUM")
    .setTotalBy("2015", "SUM")
    .setTotalBy("2016", "SUM")
    .setTotalBy("2017", "SUM")
    .setDisplayTotalsOnColumn("group");

// Render to HTML
var html = report.toHTML(config => {
    config.setGroupColor(1, 0x192e54, 0xFFFFFF);
    config.setEmitFullHTML(true);
});

// Send mail
var mail = new Ax.mail.MailerMessage();
    mail.from("coyote@acme.com");
    mail.to("user1@acme.es");
    mail.subject("Report with styles");
    mail.setHtml(html);

    var mailer = new Ax.mail.Mailer();
    mailer.setSMTPServer("authsmtp.myserver.com", 587);
    mailer.setSMTPUsername("smtp@myserver.com");
    mailer.setSMTPPassword("*****2016");
    mailer.send(mail);
</script>