Skip to content

Instantly share code, notes, and snippets.

@katio
Last active October 31, 2015 08:26
Show Gist options
  • Save katio/95a673a3d14a4147ed0c to your computer and use it in GitHub Desktop.
Save katio/95a673a3d14a4147ed0c to your computer and use it in GitHub Desktop.
Class to generate HTML e-mail messages from IBM Domino XPages SSJS by Mark Leusink (Twitter @markleusink). This is a small modification to solve a problem when you use the mime header "To" and the length in characters of a recipient is greater than or equal to 79, as can be the case in a long canonical name. This is solved here using the item "S…
/*
* Took from:
* http://openntf.org/XSnippets.nsf/snippet.xsp?id=create-html-mails-in-ssjs-using-mime
*
* Class to generate HTML e-mail messages from SSJS
*
* Author: Mark Leusink (m.leusink@gmail.com)
*
* Version: 2012-11-20
*
* History:
* 2011-12-07 initial version
* 2011-12-08 added support for inline images
* 2011-12-19 fixed wrong method name in usage samples
* 2012-11-20 added code to set JSON contents
changed setHeaderVal() to addValText() to set the sender with the correct encoding
* 2013-01-08 small bug fix in _addAttachments() function
* 2013-11-20 option to set a different reply to address (thanks Ken Behrens!)
* 2014-01-02 changed setHeaderVal() to addValText() for better Subject header encoding (thanks Egor Margineanu!)
* 2014-03-05 modification to solve a problem when you use the mime header "To" and the length in characters of a recipient is greater than or equal to 79, as can be the case in a long canonical name. This is solved here using the item "SendTo" in the NotesDocument instead of the mime header. @Katio, @Abrupto.
*
* Usage example (simple):
*
* var mail = new HTMLMail();
* mail.setTo( "m.leusink@gmail.com")
* mail.setSubject("Your notification");
* mail.addHTML("<b>Hello world</b>");
* mail.send();
*
* Usage example (extended):
*
* var mail = new HTMLMail();
* mail.setTo( "m.leusink@gmail.com")
* mail.setCC( ["user@domain.com", "anotheruser@domaino.com"] );
* mail.setBCC( "user3@domaino.com");
* mail.setSubject("Your notification");
* mail.addHTML("<h1>Hi!</h1>");
* mail.addHTML("<table><tbody><tr><td>contents in a table here</td></tr></tbody></table>");
* mail.addDocAttachment( "DC9126E84C59093FC1257953003C13E6", "jellyfish.jpg")
* mail.addFileAttachment( "c:/temp/report.pdf");
* mail.setSender("m.leusink@gmail.com", "Mark Leusink");
* mail.send();
*/
var HTMLMail = function() {
this._to = [];
this._cc = [];
this._bcc = [];
this._fromEmail = null;
this._fromName = null;
this._reply = [];
this._subject = "";
this._contentsHTML = [];
this._contentsText = [];
this._contentsJSON = null;
this._attachments = [];
/*
* set "to", "CC" and/ or "BCC" addresses
* to = string or array of strings containing either e-mail addresses or Notes names
*/
this.setTo = function( to:String ) {
//if (typeof to === "string") { to = [to] };
if (typeof to === "string") { to = to.split(",") };
this._to = to;
};
this.setCC = function( to:String ) {
//if (typeof to === "string") { to = [to] };
if (typeof to === "string") { to = to.split(",") };
this._cc = to;
}
this.setBCC = function( to:String ) {
//if (typeof to === "string") { to = [to] };
if (typeof to === "string") { to = to.split(",") };
this._bcc = to;
}
this.setReply = function( to:String ) {
if (typeof to === "string") { to = [to] };
this._reply = to;
}
//set the subject of the message
this.setSubject = function( subject:String ) {
this._subject = subject;
}
this.addHTML = function( content:String ) {
this._contentsHTML.push(content);
//create a plain text representation of the HTML contents:
//remove all HTML tags and add a line break
var plainText = content.replace( /<[a-zA-Z\/][^>]*>/g, "");
this._contentsText.push( plainText + "\n" );
}
this.addText = function( content:String ) {
this._contentsText.push( content );
//add html part by replacing all line breaks with a <br /> tag
var htmlText = @ReplaceSubstring(content, @Char(13), "<br />");
this._contentsHTML.push(htmlText);
}
this.setJSON = function( content:String ) {
this._contentsJSON = content;
}
//set the sender of the message
//fromEmail is required, fromName is optional
this.setSender = function( fromEmail:String, fromName:String ) {
if ( fromEmail.length > 0 ) {
this._fromEmail = fromEmail;
this._fromName = fromName;
}
}
/*
* add an attachment on a document to the mail message
*
* unid (string) = unid of the document in the current database that contains the file to be send
* fileName (string) = well... guess...
* inlineImage (boolean, defaults to false): if set to true, this image is marked as "inline" (used in the content)
*/
this.addDocAttachment = function( unid:String , fileName:String, inlineImage:boolean) {
var contentId = @Unique().toLowerCase();
if (typeof inlineImage=="undefined") { inlineImage = false; }
this._attachments.push( { type : "document", unid: unid, fileName : fileName, contentId : contentId, inline : inlineImage } );
return "cid:" + contentId;
}
/*
* add an OS file to the mail message
*
* path (string): path of the file on the server
* fileName (string): fileName of the file
* inlineImage (boolean, defaults to false): if set to true, this image is marked as "inline" (used in the content)
*/
this.addFileAttachment = function( path:String, fileName:String, inlineImage:boolean ) {
var contentId = @Unique().toLowerCase();
if (typeof inlineImage=="undefined") { inlineImage = false; }
this._attachments.push( { type : "file", path : path, fileName : fileName, contentId : contentId, inline : inlineImage } );
return "cid:" + contentId;
}
this.send = function() {
session.setConvertMime(false);
var doc:NotesDocument = database.createDocument();
doc.replaceItemValue("RecNoOutOfOffice", "1"); //no replies from out of office agents
var mimeRoot:NotesMIMEEntity = doc.createMIMEEntity("Body");
var mimeHeader:NotesMIMEHeader;
/* Not TO, CC, & BCC as mime header anymore.
if (this._to.length>0) {
mimeHeader = mimeRoot.createHeader("To");
mimeHeader.setHeaderVal( this._to.join(","));
}
if (this._cc.length>0) {
mimeHeader = mimeRoot.createHeader("CC");
mimeHeader.setHeaderVal( this._cc.join(","));
}
if (this._bcc.length>0) {
mimeHeader = mimeRoot.createHeader("BCC");
mimeHeader.setHeaderVal( this._bcc.join(","));
}*/
//set subject
mimeHeader = mimeRoot.createHeader("Subject");
mimeHeader.addValText(this._subject, "UTF-8");
var mimeBoundary = doc.getUniversalID().toLowerCase();
var stream:NotesStream;
var mimeEntity:NotesMIMEEntity;
//create text/alternative directive: text/plain and text/html part will be childs of this entity
var mimeRootChild = mimeRoot.createChildEntity();
mimeHeader = mimeRootChild.createHeader("Content-Type");
mimeHeader.setHeaderVal( "multipart/alternative; boundary=\"" + mimeBoundary + "\"" );
//create plain text part
if (this._contentsText.length>0) {
mimeEntity = mimeRootChild.createChildEntity();
stream = session.createStream();
stream.writeText(this._contentsText.join(""));
mimeEntity.setContentFromText(stream, "text/plain; charset=\"UTF-8\"", NotesMIMEEntity.ENC_NONE);
stream.close();
}
//create HTML part
if (this._contentsHTML.length>0) {
mimeEntity = mimeRootChild.createChildEntity();
stream = session.createStream();
stream.writeText(this._contentsHTML.join("\n"));
mimeEntity.setContentFromText(stream, "text/html; charset=\"UTF-8\"", NotesMIMEEntity.ENC_NONE);
stream.close();
}
//create embedded JSON part
if (this._contentsJSON) {
mimeEntity = mimeRootChild.createChildEntity();
stream = session.createStream();
var json = "{\"url\" : \"" + this._contentsJSON + "\"}\n";
stream.writeText(json);
mimeEntity.setContentFromText(stream, "application/embed+json; charset=\"UTF-8\"", NotesMIMEEntity.ENC_NONE);
stream.close();
}
//add attachments
this._addAttachments(mimeRoot);
//set the sender
this._setSender(mimeRoot);
//send the e-mail
doc.replaceItemValue("SendTo", this._to)
doc.replaceItemValue("CopyTo", this._cc)
doc.replaceItemValue("BlindCopyTo", this._bcc)
doc.send();
session.setConvertMime(true);
};
//retrieve a file from a document that should be added to the message
this._addAttachments = function( mimeRoot:NotesMIMEEntity ) {
var streamFile:NotesStream = null;
//process document attachments
for (var i=0; i<this._attachments.length; i++) {
var att = this._attachments[i];
is = null;
//get content type for file
var contentType = "application/octet-stream";
var extension = @LowerCase(@RightBack( att.fileName, "."));
if (extension=="gif") {
contentType = "image/gif";
} else if (extension=="jpg" || extension=="jpeg") {
contentType = "image/jpeg";
} else if (extension=="png") {
contentType = "image/png";
}
contentType += "; name=\"" + att.fileName + "\"";
var eo:NotesEmbeddedObject = null;
var is = null;
try {
if ( att.type.equals("document")) {
//retrieve the document containing the attachment to send from the current database
var docFile:NotesDocument = database.getDocumentByUNID( att.unid );
if (null != docFile) {
eo = docFile.getAttachment(att.fileName);
is = eo.getInputStream();
}
} else {
is = new java.io.FileInputStream( att.path + att.fileName );
}
if (is != null) {
var mimeChild = mimeRoot.createChildEntity();
var mimeHeader = mimeChild.createHeader("Content-Disposition");
if (att.inline) {
mimeHeader.setHeaderVal("inline; filename=\"" + att.fileName + "\"");
} else {
mimeHeader.setHeaderVal("attachment; filename=\"" + att.fileName + "\"");
}
mimeHeader = mimeChild.createHeader("Content-ID");
mimeHeader.setHeaderVal( "<" + att.contentId + ">" );
streamFile = session.createStream();
streamFile.setContents(is);
mimeChild.setContentFromBytes(streamFile, contentType, NotesMIMEEntity.ENC_IDENTITY_BINARY);
}
} catch (e) {
print("error while adding attachment: " + e.toString());
} finally {
if (is != null) { is.close(); }
if (eo != null) { eo.recycle(); }
}
}
}
//change the sender of an e-mail
this._setSender = function( mimeRoot:NotesMIMEEntity ) {
if (this._fromEmail==null) {
return;
}
var mimeHeader:NotesMIMEHeader = null;
//set reply address
if (this._reply.length>0) {
mimeHeader = mimeRoot.createHeader("Reply-To");
mimeHeader.setHeaderVal( this._reply.join(","));
} else {
mimeHeader = mimeRoot.createHeader("Reply-To");
mimeHeader.setHeaderVal(this._fromEmail);
}
mimeHeader = mimeRoot.createHeader("Return-Path");
mimeHeader.setHeaderVal(this._fromEmail);
if (this._fromName==null) {
mimeHeader = mimeRoot.createHeader("From");
mimeHeader.setHeaderVal(this._fromEmail);
mimeHeader = mimeRoot.createHeader("Sender");
mimeHeader.setHeaderVal(this._fromEmail);
} else {
mimeHeader = mimeRoot.createHeader("From");
mimeHeader.addValText( "\"" + this._fromName + "\" <" + this._fromEmail + ">", "UTF-8" );
mimeHeader = mimeRoot.createHeader("Sender");
mimeHeader.addValText( "\"" + this._fromName + "\" <" + this._fromEmail + ">", "UTF-8" );
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment