SmtpClient
This document describes the SmtpClient available in the JavaScript environment for app serivices.
Table of content
config
Sets the configuration for the SmtpClient. This function has to be called before the sendMail function can be used.
Parameters
string from | The email address of the sender. |
string fromName | The display name of the sender. |
string host | The host name to be included in the EHLO message. Recommendation: use "localhost" if no other host name is available. |
string server | The DNS name of the email server. |
string username | The username of the email account. |
string password | The password of the email account. |
Return value
SmtpClient | A reference to the object itself. Useful for method chaining. |
var cfg = {
from: "appservice@example.com",
fromName: "The App Service",
host: "localhost",
server: "mail.example.com",
username: "appservice@example.com",
password: "pwd"
};
SmtpClient.config(cfg.from, cfg.fromName, cfg.host, cfg.server, cfg.username, cfg.password);
oauth2Config
Sets the OAuth2 configuration for the SmtpClient. This function has to be called before the sendMail function can be used.
web1/oauth2client/innovaphone.smtp.oauth2.js should be referenced to get a list of supported OAuth2 types and to determine for which types each parameter is needed.
This way the SDK can include preconfigured account types for various e-mail service providers. Generic types "client-secret-post" and "private-key-jwt" allow configuration of all parameters und thus adaptation to any provider.
Parameters
string type | The SMTP OAuth2 type. Supported are "off", "client-secret-post", "private-key-jwt" and others according to the array of strings returned by innovaphone.SMTP.OAuth2.getValues(). |
string clientID | Client ID of the "client-secret-post" method based types. Boolean innovaphone.SMTP.OAuth2.needsClientID(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string clientSecret | Client secret of the "client-secret-post" method based types. Boolean innovaphone.SMTP.OAuth2.needsClientSecret(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string ownerUsername | Resource owner username of the "client-secret-post" method based types. Boolean innovaphone.SMTP.OAuth2.needsOwnerUsername(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string ownerPassword | Resource owner password of the "client-secret-post" method based types. Boolean innovaphone.SMTP.OAuth2.needsOwnerPassword(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string clientEMail | Client e-mail of the "private-key-jwt" method based types. Boolean innovaphone.SMTP.OAuth2.needsClientEMail(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string privateKeyID | ID that identifies the private key of the "private-key-jwt" method based types. Boolean innovaphone.SMTP.OAuth2.needsPrivateKeyID(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string privateKey | Private key of the "private-key-jwt" method based types in .pem string format. Boolean innovaphone.SMTP.OAuth2.needsPrivateKey(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string tenant | Tenant of some "client-secret-post" method based types. Boolean innovaphone.SMTP.OAuth2.needsClientID(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string tokenEndpoint | URL of the access token server. Boolean innovaphone.SMTP.OAuth2.needsTokenEndpoint(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
string scope | Scope of requested access. Boolean innovaphone.SMTP.OAuth2.needsScope(oauth2) tells if this parameter is needed for the selected SMTP OAuth2 type. |
Return value
SmtpClient | A reference to the object itself. Useful for method chaining. |
SmtpClient.oauth2Config(smtpOAuth2Type, clientID, clientSecret, ownerUsername, ownerPassword, clientEMail, privateKeyID, privateKey, tenant, tokenEndpoint, scope);
Note that the registration process of the app and the e-mail account at the e-mail provider will tell you the credentials that need to be supplied here. For the interactive authorization step the app needs to offer a link
to the URL string returned by innovaphone.SMTP.OAuth2.getAuthorizationURL(oauth2, redirectURI, clientID, ownerUsername, tenant, tokenEndpoint, scope, authorizationURL).
The redirectURI parameter always needs to be set to the HTTPS Uri of the app service with the file name replaced by "auth.htm":
For the app: redirectURI = start.originalUrl.substr(0, start.originalUrl.lastIndexOf("/")) + "/auth.htm"
For a manager plugin: redirectURI = item.httpsUri.substr(0, item.httpsUri.lastIndexOf("/")) + "/auth.htm"
authorizationURL is needed if boolean innovaphone.SMTP.OAuth2.needsAuthorizationURL(oauth2) returns true and must be the URL to the authorization endpoint of the e-mail service provider plus URL parameters to set scope and offline access.
sendMail
This function is called to start sending an outgoing email.
After calling the function, the application has to immediately set all the email parameters using the functions of the returned SmtpClientSend object.
Please note that the config function has to be called, before sending the first email.
Parameters
string subject | The subject of the email. |
Return value
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!");
to
Adds a recipient to the email.
The function has to called at least once. It can be called multiple times in order to add multiple recipients.
Parameters
string emailAddress | An email address. |
Return value
SmtpClientSend | A reference to the object itself. Useful for method chaining. |
SmtpClient.sendMail("Test email")
.to("user@example.com")
.to("anotheruser@example.com")
.body("It works!");
cc
Adds a CC recipient to the email.
The function can be called multiple times in order to add multiple CC recipients.
Parameters
string emailAddress | An email address. |
Return value
SmtpClientSend | A reference to the object itself. Useful for method chaining. |
SmtpClient.sendMail("Test email")
.to("user@example.com")
.cc("anotheruser@example.com")
.body("It works!");
bcc
Adds a BCC recipient to the email.
The function can be called multiple times in order to add multiple BCC recipients.
Parameters
string emailAddress | An email address. |
Return value
SmtpClientSend | A reference to the object itself. Useful for method chaining. |
SmtpClient.sendMail("Test email")
.to("user@example.com")
.bcc("anotheruser@example.com")
.body("It works!");
body
Adds a body to the email.
Parameters
string or Uint8Array content | The content of the email body. |
string mimeType | The MIME type of the email body. Optional, defaulting to "text/plain". |
string charset | The charset of the email body. Optional, defaulting to "UTF-8". |
Return value
SmtpClientSend | A reference to the object itself. Useful for method chaining. |
// Text email with implicit mimeType "text/plain" and charset "UTF-8"
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!");
// Text email with explicit mimeType and charset
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!", "text/plain", "UTF-8");
// HTML email
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("<!DOCTYPE html><html><head></head><body><b>It works!</b><br/><br/>Best Regards,<br/><i>Your app service</i></body></html>", "text/html", "UTF-8")
attach
Adds an attachment to the email.
The function can be called multiple times in order to add multiple attachments.
Parameters
string filename | The file name of the attachment. |
string mimeType | The MIME type of the attachment. |
function(SmtpClientAttachment attachment) callback | The callback that will be called when the SMTP client is ready to send the attachment data. |
Return value
SmtpClientSend | A reference to the object itself. Useful for method chaining. |
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!")
.attach("readme.txt", "text/plain", function(attachment) {
attachment.send("README\n\nThis is a text file.", true);
});
oncomplete
Sets a callback function that is invoked when the sending of the mail is completed.
Optional.
Parameters
function callback(bool success) | A callback that will be called when the email has been sent. |
Return value
SmtpClientSend | A reference to the object itself. Useful for method chaining. |
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!")
.oncomplete(function(success) {
if (success) log("email sent");
else log("sending email failed");
});
onerror
Sets a callback function that is invoked when the sending of the mail has failed.
Optional. If not set the oncomplete callback will be invoked with success set to false.
Parameters
function callback | A callback that will be called when sending has failed. |
Return value
SmtpClientSend | A reference to the object itself. Useful for method chaining. |
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!")
.oncomplete(function(success) {
log("email sent");
})
.onerror(function() {
log("sending email failed");
});
send
This function is used to send a chunk of data for an attachment.
It has to be called when the callback function from SmtpClientSend.attach is invoked.
Your applications keeps receiving the callback until you call the function send with last set to true.
Parameters
string or Uint8Array data | The next chunk of data. |
boolean last | Set this parameter to false, if you have additional chunks of data to send for this attachment. This will trigger the next callback. Set the parameter to true for the last chunk. |
Return value
// sending a text file in one chunk
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!")
.attach("readme.txt", "text/plain", function(attachment) {
attachment.send("README\n\nThis is a text file.", true);
});
// sending a PNG image file in multiple chunks
const CHUNK_SIZE = 100;
var dataOffset = 0;
var data = new Uint8Array([
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x4B,
0x08, 0x02, 0x00, 0x00, 0x00, 0xB7, 0x2C, 0xED, 0xBD, 0x00, 0x00, 0x02, 0xF3, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0xDB, 0xCF, 0x6B, 0xD4,
0x40, 0x14, 0x07, 0xF0, 0x37, 0xB3, 0x83, 0xB1, 0xAD, 0xD2, 0x2D, 0x58, 0x6C, 0xF0, 0xE4, 0x61, 0x6F, 0x05, 0xB1, 0x5D, 0x45, 0xB4, 0x8A, 0x57,
0xC1, 0x8A, 0x88, 0x88, 0xB9, 0x18, 0xBC, 0xFA, 0x17, 0xF8, 0x1F, 0xF8, 0x1F, 0x78, 0x13, 0x89, 0x97, 0x80, 0x07, 0x29, 0xF4, 0xE0, 0x49, 0x10,
0xAD, 0xAD, 0xE8, 0xB6, 0x55, 0x58, 0x14, 0xDC, 0x83, 0xDE, 0xA2, 0x28, 0xEC, 0x2E, 0xD5, 0x62, 0xDC, 0x59, 0xD7, 0x43, 0x24, 0x87, 0x35, 0xDD,
0x24, 0xF3, 0xE3, 0x25, 0xAC, 0xF3, 0x6E, 0xB9, 0x64, 0xF9, 0x30, 0x93, 0xCD, 0x7B, 0x3B, 0xDF, 0x25, 0x83, 0xC1, 0x00, 0xC6, 0xBA, 0x28, 0x8C,
0x7B, 0x19, 0xA1, 0x11, 0x1A, 0xA1, 0x11, 0x1A, 0xA1, 0x11, 0x96, 0x49, 0xD8, 0xEA, 0xB6, 0xB7, 0xBE, 0x7D, 0x19, 0x5B, 0x61, 0xAB, 0xDB, 0x5E,
0xDE, 0x5C, 0xBB, 0xF4, 0x66, 0xE3, 0xD5, 0xD7, 0xCF, 0x63, 0x28, 0x8C, 0x78, 0x9D, 0x3E, 0xE7, 0x83, 0xC1, 0x95, 0xB7, 0x2F, 0x91, 0x91, 0x14,
0x8D, 0x17, 0x5D, 0xE2, 0x23, 0x29, 0x26, 0xAF, 0x10, 0x24, 0x45, 0xE6, 0xE1, 0x23, 0x29, 0x3E, 0x0F, 0x19, 0x49, 0x0B, 0xE1, 0x61, 0x22, 0x69,
0x51, 0x3C, 0x34, 0x24, 0x2D, 0x90, 0x87, 0x83, 0xA4, 0xC5, 0xF2, 0x10, 0x90, 0xB4, 0x70, 0x9E, 0x6E, 0x24, 0x2D, 0x03, 0x4F, 0x2B, 0x52, 0x8D,
0xF0, 0x56, 0xB3, 0x21, 0xC9, 0x8B, 0x91, 0x37, 0x9B, 0x8D, 0x5D, 0x15, 0xB7, 0x52, 0x2C, 0x7C, 0x70, 0xFC, 0x74, 0xCD, 0xDA, 0x2F, 0x7F, 0x9F,
0x6A, 0x85, 0xAD, 0x2C, 0x9C, 0x99, 0xAC, 0xB0, 0xB2, 0x08, 0x83, 0x20, 0x08, 0x82, 0x00, 0x00, 0xEC, 0xC9, 0xA9, 0x87, 0xF5, 0x73, 0x92, 0xC8,
0x6A, 0x85, 0xAD, 0x2E, 0x2E, 0xD5, 0xA6, 0x67, 0xCA, 0xB2, 0x4B, 0x83, 0x20, 0xF0, 0x3C, 0xCF, 0xF3, 0x3C, 0x25, 0x48, 0x4D, 0x3C, 0x71, 0x61,
0xC4, 0x0B, 0xC3, 0x30, 0x0C, 0x43, 0x79, 0xA4, 0x3E, 0x9E, 0xA0, 0x30, 0xE6, 0x45, 0x97, 0x92, 0x48, 0xAD, 0x3C, 0x00, 0x20, 0x79, 0xCF, 0x2D,
0x86, 0x78, 0x71, 0x59, 0x96, 0xE5, 0xBA, 0xAE, 0x6D, 0xDB, 0x00, 0x10, 0xEC, 0xFE, 0xB8, 0xD6, 0x78, 0xD6, 0x0A, 0x7F, 0x0A, 0xF0, 0xF8, 0xA7,
0x8D, 0xFE, 0xFB, 0x7B, 0x02, 0x92, 0x7D, 0xE7, 0xEF, 0x90, 0x89, 0x59, 0x59, 0xE1, 0x5E, 0x3C, 0x31, 0x64, 0xE2, 0xEA, 0xF5, 0xDE, 0x3D, 0xE9,
0xAD, 0x5F, 0x15, 0x10, 0x4E, 0x5C, 0x6F, 0x92, 0x03, 0x47, 0xA4, 0x76, 0xE9, 0x68, 0x5E, 0xDE, 0xED, 0xAA, 0x7B, 0x73, 0xE6, 0x16, 0xA6, 0xF2,
0x72, 0x21, 0xD1, 0x78, 0x59, 0x85, 0x19, 0x79, 0x19, 0x91, 0x98, 0xBC, 0x4C, 0xC2, 0x5C, 0xBC, 0x54, 0x24, 0x32, 0x2F, 0x5D, 0x28, 0xC0, 0x1B,
0x81, 0xC4, 0xE7, 0xA5, 0x08, 0x85, 0x79, 0x7B, 0x21, 0x1F, 0x9F, 0x38, 0x8B, 0xCC, 0x1B, 0x25, 0x94, 0xE4, 0x25, 0x22, 0x8F, 0x1E, 0xAC, 0x02,
0x7A, 0x25, 0x0B, 0x39, 0xE7, 0xBE, 0xEF, 0x4B, 0xF2, 0x62, 0xA4, 0xEF, 0xFB, 0x9C, 0x73, 0x28, 0xA8, 0x92, 0x85, 0x8C, 0x31, 0xC7, 0x71, 0x2C,
0xCB, 0x92, 0xFF, 0x00, 0xCB, 0xB2, 0x1C, 0xC7, 0x61, 0x8C, 0x95, 0x4B, 0x08, 0x00, 0xB6, 0x6D, 0xBB, 0xAE, 0x2B, 0x89, 0x1C, 0xEA, 0x72, 0x3E,
0xEE, 0x74, 0x4A, 0x24, 0x94, 0x47, 0xFE, 0xDB, 0xC4, 0x5D, 0x78, 0xFD, 0xBC, 0xD5, 0x6D, 0x97, 0x48, 0x28, 0x83, 0x4C, 0xEC, 0x51, 0x3B, 0x7D,
0xBE, 0xBC, 0xB9, 0x86, 0x8C, 0x4C, 0x7F, 0xE3, 0x0B, 0x20, 0x47, 0xB4, 0xE0, 0xF8, 0xC8, 0x4C, 0x5D, 0x5B, 0x2E, 0x64, 0xEA, 0x84, 0x81, 0x8C,
0xCC, 0xDA, 0x79, 0x67, 0x44, 0x66, 0x1C, 0xA0, 0x30, 0x91, 0x39, 0xA6, 0xA7, 0x54, 0x64, 0xAE, 0xF9, 0x10, 0x0D, 0x59, 0xBE, 0x19, 0xFF, 0xC3,
0x53, 0xBE, 0x7D, 0x5B, 0xE4, 0xAB, 0xFB, 0xE2, 0x0A, 0x99, 0x9A, 0x53, 0x20, 0x4C, 0x44, 0x8A, 0xF1, 0x70, 0xA6, 0x0D, 0x91, 0x5F, 0xA2, 0x86,
0xB6, 0xAB, 0x0C, 0x0F, 0x61, 0xBB, 0x12, 0xE1, 0x04, 0x6D, 0xB4, 0x92, 0x00, 0x20, 0xC3, 0x43, 0x58, 0x49, 0x22, 0x93, 0x11, 0xFE, 0x3B, 0x34,
0x48, 0xF3, 0xB4, 0x22, 0x89, 0x92, 0x14, 0xB4, 0x3C, 0x4F, 0x1F, 0x52, 0xCD, 0xC9, 0xCC, 0x8D, 0xED, 0x75, 0x79, 0x5E, 0xF4, 0x4C, 0x5E, 0xDE,
0x7A, 0x51, 0xC6, 0xB3, 0xA7, 0xBB, 0xF3, 0xF5, 0xAA, 0x8A, 0x03, 0x23, 0x46, 0xC8, 0xFD, 0xF9, 0x7A, 0x89, 0xCE, 0x9E, 0xE2, 0xAA, 0x4D, 0xCF,
0xAC, 0x2E, 0x2E, 0x49, 0x22, 0x19, 0x21, 0x8F, 0x8E, 0x9D, 0x3A, 0x39, 0x3B, 0x57, 0xFC, 0xDB, 0x42, 0x07, 0x52, 0x13, 0x0F, 0xD4, 0x26, 0x15,
0x84, 0x91, 0xFA, 0x78, 0xA0, 0x3C, 0x6D, 0x22, 0x80, 0xD4, 0xCA, 0x03, 0x1D, 0x89, 0xA1, 0x5C, 0x48, 0xDD, 0x3C, 0xD0, 0x94, 0xFA, 0xCA, 0x88,
0x44, 0xE0, 0x81, 0xBE, 0xE4, 0x5E, 0x2A, 0x12, 0x87, 0x07, 0x5A, 0xD3, 0x97, 0x23, 0x90, 0x68, 0x3C, 0xD0, 0x9D, 0xA0, 0x4D, 0x44, 0x62, 0xF2,
0x00, 0x21, 0x05, 0x3D, 0x84, 0x44, 0xE6, 0x29, 0xEB, 0xBC, 0x53, 0x2B, 0x8A, 0x85, 0x7D, 0xFF, 0xDD, 0x47, 0xE6, 0xE1, 0x09, 0x23, 0xE4, 0x4E,
0xEF, 0xD7, 0xC2, 0xA1, 0xC3, 0x80, 0x5B, 0xC4, 0xFC, 0x87, 0xD4, 0x08, 0x8D, 0xD0, 0x08, 0x8D, 0xD0, 0x08, 0x8D, 0xF0, 0x3F, 0x10, 0xFE, 0x01,
0x8D, 0xDC, 0xE4, 0x9A, 0x94, 0x50, 0x9C, 0x16, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
]);
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!")
.attach("icon.png", "image/png", function(attachment) {
var chunk = data.subarray(dataOffset, dataOffset + CHUNK_SIZE);
dataOffset += CHUNK_SIZE;
attachment.send(chunk, dataOffset > data.length);
});
Examples
In this example we set the configuration for the SmtpClient and use it to send a text email.
// Configuration
// typically this would be configurable by the user, but we hard-code it here
var cfg = {
from: "appservice@example.com",
fromName: "The App Service",
host: "localhost",
server: "mail.example.com",
username: "appservice@example.com",
password: "pwd"
};
SmtpClient.config(cfg.from, cfg.fromName, cfg.host, cfg.server, cfg.username, cfg.password);
// send email
SmtpClient.sendMail("Test email")
.to("user@example.com")
.body("It works!")
.oncomplete(function(success) {
log("email sent");
})
.onerror(function() {
log("sending email failed");
});
In this example we send an HTML email with a text file and a PNG image as attachments.
// Configuration
var cfg = {
from: "appservice@example.com",
fromName: "The App Service",
host: "localhost",
server: "mail.example.com",
username: "appservice@example.com",
password: "pwd"
};
SmtpClient.config(cfg.from, cfg.fromName, cfg.host, cfg.server, cfg.username, cfg.password);
// Email content
var subject = "Test email";
var to = "user@example.com";
var body = {
mimeType: "text/html",
charset: "UTF-8",
data: "<!DOCTYPE html>"
+ "<html>"
+ "<head></head>"
+ "<body>"
+ "<b>It works</b><br/><br/>"
+ "Best regards<br/>"
+ "<i>Your App Service</i>"
+ "</body>"
+ "</html>"
};
var attachments = [
{
filename: "readme.txt",
mimeType: "text/plain",
data: "README\n\n"
+ "This is a text file"
},
{
filename: "image.png",
mimeType: "image/png",
data: new Uint8Array([
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x4B,
0x08, 0x02, 0x00, 0x00, 0x00, 0xB7, 0x2C, 0xED, 0xBD, 0x00, 0x00, 0x02, 0xF3, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0xDB, 0xCF, 0x6B, 0xD4,
0x40, 0x14, 0x07, 0xF0, 0x37, 0xB3, 0x83, 0xB1, 0xAD, 0xD2, 0x2D, 0x58, 0x6C, 0xF0, 0xE4, 0x61, 0x6F, 0x05, 0xB1, 0x5D, 0x45, 0xB4, 0x8A, 0x57,
0xC1, 0x8A, 0x88, 0x88, 0xB9, 0x18, 0xBC, 0xFA, 0x17, 0xF8, 0x1F, 0xF8, 0x1F, 0x78, 0x13, 0x89, 0x97, 0x80, 0x07, 0x29, 0xF4, 0xE0, 0x49, 0x10,
0xAD, 0xAD, 0xE8, 0xB6, 0x55, 0x58, 0x14, 0xDC, 0x83, 0xDE, 0xA2, 0x28, 0xEC, 0x2E, 0xD5, 0x62, 0xDC, 0x59, 0xD7, 0x43, 0x24, 0x87, 0x35, 0xDD,
0x24, 0xF3, 0xE3, 0x25, 0xAC, 0xF3, 0x6E, 0xB9, 0x64, 0xF9, 0x30, 0x93, 0xCD, 0x7B, 0x3B, 0xDF, 0x25, 0x83, 0xC1, 0x00, 0xC6, 0xBA, 0x28, 0x8C,
0x7B, 0x19, 0xA1, 0x11, 0x1A, 0xA1, 0x11, 0x1A, 0xA1, 0x11, 0x96, 0x49, 0xD8, 0xEA, 0xB6, 0xB7, 0xBE, 0x7D, 0x19, 0x5B, 0x61, 0xAB, 0xDB, 0x5E,
0xDE, 0x5C, 0xBB, 0xF4, 0x66, 0xE3, 0xD5, 0xD7, 0xCF, 0x63, 0x28, 0x8C, 0x78, 0x9D, 0x3E, 0xE7, 0x83, 0xC1, 0x95, 0xB7, 0x2F, 0x91, 0x91, 0x14,
0x8D, 0x17, 0x5D, 0xE2, 0x23, 0x29, 0x26, 0xAF, 0x10, 0x24, 0x45, 0xE6, 0xE1, 0x23, 0x29, 0x3E, 0x0F, 0x19, 0x49, 0x0B, 0xE1, 0x61, 0x22, 0x69,
0x51, 0x3C, 0x34, 0x24, 0x2D, 0x90, 0x87, 0x83, 0xA4, 0xC5, 0xF2, 0x10, 0x90, 0xB4, 0x70, 0x9E, 0x6E, 0x24, 0x2D, 0x03, 0x4F, 0x2B, 0x52, 0x8D,
0xF0, 0x56, 0xB3, 0x21, 0xC9, 0x8B, 0x91, 0x37, 0x9B, 0x8D, 0x5D, 0x15, 0xB7, 0x52, 0x2C, 0x7C, 0x70, 0xFC, 0x74, 0xCD, 0xDA, 0x2F, 0x7F, 0x9F,
0x6A, 0x85, 0xAD, 0x2C, 0x9C, 0x99, 0xAC, 0xB0, 0xB2, 0x08, 0x83, 0x20, 0x08, 0x82, 0x00, 0x00, 0xEC, 0xC9, 0xA9, 0x87, 0xF5, 0x73, 0x92, 0xC8,
0x6A, 0x85, 0xAD, 0x2E, 0x2E, 0xD5, 0xA6, 0x67, 0xCA, 0xB2, 0x4B, 0x83, 0x20, 0xF0, 0x3C, 0xCF, 0xF3, 0x3C, 0x25, 0x48, 0x4D, 0x3C, 0x71, 0x61,
0xC4, 0x0B, 0xC3, 0x30, 0x0C, 0x43, 0x79, 0xA4, 0x3E, 0x9E, 0xA0, 0x30, 0xE6, 0x45, 0x97, 0x92, 0x48, 0xAD, 0x3C, 0x00, 0x20, 0x79, 0xCF, 0x2D,
0x86, 0x78, 0x71, 0x59, 0x96, 0xE5, 0xBA, 0xAE, 0x6D, 0xDB, 0x00, 0x10, 0xEC, 0xFE, 0xB8, 0xD6, 0x78, 0xD6, 0x0A, 0x7F, 0x0A, 0xF0, 0xF8, 0xA7,
0x8D, 0xFE, 0xFB, 0x7B, 0x02, 0x92, 0x7D, 0xE7, 0xEF, 0x90, 0x89, 0x59, 0x59, 0xE1, 0x5E, 0x3C, 0x31, 0x64, 0xE2, 0xEA, 0xF5, 0xDE, 0x3D, 0xE9,
0xAD, 0x5F, 0x15, 0x10, 0x4E, 0x5C, 0x6F, 0x92, 0x03, 0x47, 0xA4, 0x76, 0xE9, 0x68, 0x5E, 0xDE, 0xED, 0xAA, 0x7B, 0x73, 0xE6, 0x16, 0xA6, 0xF2,
0x72, 0x21, 0xD1, 0x78, 0x59, 0x85, 0x19, 0x79, 0x19, 0x91, 0x98, 0xBC, 0x4C, 0xC2, 0x5C, 0xBC, 0x54, 0x24, 0x32, 0x2F, 0x5D, 0x28, 0xC0, 0x1B,
0x81, 0xC4, 0xE7, 0xA5, 0x08, 0x85, 0x79, 0x7B, 0x21, 0x1F, 0x9F, 0x38, 0x8B, 0xCC, 0x1B, 0x25, 0x94, 0xE4, 0x25, 0x22, 0x8F, 0x1E, 0xAC, 0x02,
0x7A, 0x25, 0x0B, 0x39, 0xE7, 0xBE, 0xEF, 0x4B, 0xF2, 0x62, 0xA4, 0xEF, 0xFB, 0x9C, 0x73, 0x28, 0xA8, 0x92, 0x85, 0x8C, 0x31, 0xC7, 0x71, 0x2C,
0xCB, 0x92, 0xFF, 0x00, 0xCB, 0xB2, 0x1C, 0xC7, 0x61, 0x8C, 0x95, 0x4B, 0x08, 0x00, 0xB6, 0x6D, 0xBB, 0xAE, 0x2B, 0x89, 0x1C, 0xEA, 0x72, 0x3E,
0xEE, 0x74, 0x4A, 0x24, 0x94, 0x47, 0xFE, 0xDB, 0xC4, 0x5D, 0x78, 0xFD, 0xBC, 0xD5, 0x6D, 0x97, 0x48, 0x28, 0x83, 0x4C, 0xEC, 0x51, 0x3B, 0x7D,
0xBE, 0xBC, 0xB9, 0x86, 0x8C, 0x4C, 0x7F, 0xE3, 0x0B, 0x20, 0x47, 0xB4, 0xE0, 0xF8, 0xC8, 0x4C, 0x5D, 0x5B, 0x2E, 0x64, 0xEA, 0x84, 0x81, 0x8C,
0xCC, 0xDA, 0x79, 0x67, 0x44, 0x66, 0x1C, 0xA0, 0x30, 0x91, 0x39, 0xA6, 0xA7, 0x54, 0x64, 0xAE, 0xF9, 0x10, 0x0D, 0x59, 0xBE, 0x19, 0xFF, 0xC3,
0x53, 0xBE, 0x7D, 0x5B, 0xE4, 0xAB, 0xFB, 0xE2, 0x0A, 0x99, 0x9A, 0x53, 0x20, 0x4C, 0x44, 0x8A, 0xF1, 0x70, 0xA6, 0x0D, 0x91, 0x5F, 0xA2, 0x86,
0xB6, 0xAB, 0x0C, 0x0F, 0x61, 0xBB, 0x12, 0xE1, 0x04, 0x6D, 0xB4, 0x92, 0x00, 0x20, 0xC3, 0x43, 0x58, 0x49, 0x22, 0x93, 0x11, 0xFE, 0x3B, 0x34,
0x48, 0xF3, 0xB4, 0x22, 0x89, 0x92, 0x14, 0xB4, 0x3C, 0x4F, 0x1F, 0x52, 0xCD, 0xC9, 0xCC, 0x8D, 0xED, 0x75, 0x79, 0x5E, 0xF4, 0x4C, 0x5E, 0xDE,
0x7A, 0x51, 0xC6, 0xB3, 0xA7, 0xBB, 0xF3, 0xF5, 0xAA, 0x8A, 0x03, 0x23, 0x46, 0xC8, 0xFD, 0xF9, 0x7A, 0x89, 0xCE, 0x9E, 0xE2, 0xAA, 0x4D, 0xCF,
0xAC, 0x2E, 0x2E, 0x49, 0x22, 0x19, 0x21, 0x8F, 0x8E, 0x9D, 0x3A, 0x39, 0x3B, 0x57, 0xFC, 0xDB, 0x42, 0x07, 0x52, 0x13, 0x0F, 0xD4, 0x26, 0x15,
0x84, 0x91, 0xFA, 0x78, 0xA0, 0x3C, 0x6D, 0x22, 0x80, 0xD4, 0xCA, 0x03, 0x1D, 0x89, 0xA1, 0x5C, 0x48, 0xDD, 0x3C, 0xD0, 0x94, 0xFA, 0xCA, 0x88,
0x44, 0xE0, 0x81, 0xBE, 0xE4, 0x5E, 0x2A, 0x12, 0x87, 0x07, 0x5A, 0xD3, 0x97, 0x23, 0x90, 0x68, 0x3C, 0xD0, 0x9D, 0xA0, 0x4D, 0x44, 0x62, 0xF2,
0x00, 0x21, 0x05, 0x3D, 0x84, 0x44, 0xE6, 0x29, 0xEB, 0xBC, 0x53, 0x2B, 0x8A, 0x85, 0x7D, 0xFF, 0xDD, 0x47, 0xE6, 0xE1, 0x09, 0x23, 0xE4, 0x4E,
0xEF, 0xD7, 0xC2, 0xA1, 0xC3, 0x80, 0x5B, 0xC4, 0xFC, 0x87, 0xD4, 0x08, 0x8D, 0xD0, 0x08, 0x8D, 0xD0, 0x08, 0x8D, 0xF0, 0x3F, 0x10, 0xFE, 0x01,
0x8D, 0xDC, 0xE4, 0x9A, 0x94, 0x50, 0x9C, 0x16, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
])
}
];
// Send email
var email = SmtpClient
.sendMail(subject)
.to(to)
.body(body.data, body.mimeType, body.charset)
.oncomplete(function () { log("sending email complete"); })
.onerror(function () { log("sending email failed"); });
// Attachments
attachments.forEach(function (file) {
email.attach(file.filename, file.mimeType, function (attachment) {
attachment.send(file.data, true);
});
});