MIME を使って SSJS で HTML メールを作成

/*
 * 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!)
 *  
 * 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.setBB( "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] };
    this._to = to;
  };
  this.setCC = function( to:String ) {
    if (typeof to === "string") { to = [to] };
    this._cc = to;    
  }
  this.setBCC = function( to:String ) {
    if (typeof to === "string") { to = [to] };
    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;
     
    //set to
    if (this._to.length>0) {
      mimeHeader = mimeRoot.createHeader("To");
      mimeHeader.setHeaderVal( this._to.join(","));
    }
    //set cc
    if (this._cc.length>0) {
      mimeHeader = mimeRoot.createHeader("CC");
      mimeHeader.setHeaderVal( this._cc.join(","));
    }
    //set bcc
    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.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" );
       
    }
     
  };
     
}





使用方法についてはこのクラスの上部にある記述を参照するか私のブログをご覧ください:

http://linqed.eu/?p=45

JavaScript (Server)
katoman
August 18, 2015 at 11:09 AM
Rating
0





No comments yetLogin first to comment...