Skip to content
Snippets Groups Projects
process.js 8.94 KiB
Newer Older
S.Listl's avatar
S.Listl committed
import("Document_lib");
import("system.logging");
Johannes Hörmann's avatar
Johannes Hörmann committed
import("system.translate");
import("system.text");
import("system.db");
import("system.util");
import("Communication_lib");
import("DocumentTemplate_lib");
import("system.neon");
import("system.mail");
S.Listl's avatar
S.Listl committed
import("Bulkmail_lib")
Johannes Hörmann's avatar
Johannes Hörmann committed

Johannes Hörmann's avatar
Johannes Hörmann committed

/**
 * creates a new E-Mail-Object and ask for a download of a eml where all fields are prefilled
 * The eml can be open with a mailclient and sent via the mailclient. Each mailclient has a different behaviour:
 * In Outlook the mail is automatically opened in draft-mode
 * In Thunderbird the mail is opened in view mode and you've to manually "edit as new"
 * 
 * @param {String|Array} pToRecipients mailaddresses of the recipients, can either be a 1D-Array with several addresses or a string with one address
 * @param {String} pSenderContactId contactId of the sender. the standard mailadress of the contact is used as sender-address
 * @param {String} [pTemplateId] if a document-template shall be used, give the templateId here
 * @param {String} [pRecipientContactId] contactId of the recipient, required to fill placeholders
 * @param {String} [pBindata] base64 binary data
S.Listl's avatar
S.Listl committed
 * @return {Array} the eml document as array with [filename, base64]
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
S.Listl's avatar
S.Listl committed
EmailWritingUtils.openMailTemplate = function (pToRecipients, pSenderContactId, pTemplateId, pRecipientContactId, pBindata)
Johannes Hörmann's avatar
Johannes Hörmann committed
{
S.Listl's avatar
S.Listl committed
    var email = new Email(pToRecipients, undefined, undefined, undefined, undefined, [EmailWritingUtils.getMailbridgeAddress()]);
S.Listl's avatar
S.Listl committed
    if (pTemplateId || pBindata)
S.Listl's avatar
S.Listl committed
        email.setTemplate(pTemplateId, pRecipientContactId, pBindata);
    email.setSender(pSenderContactId);
Johannes Hörmann's avatar
Johannes Hörmann committed

S.Listl's avatar
S.Listl committed
    return email.downloadEML();
Johannes Hörmann's avatar
Johannes Hörmann committed
}

/**
 * opens a view where a new mail can be sent. In the view the use CAN select a DocumentTemplate if needed
 * 
 * @param {String} pToContactId contactId with contacts to filter the communication-addresses
 * @param {String} [pToEmailAddress] email address as string that shall be used as recipient-preset
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
EmailWritingUtils.openNewMail = function (pToContactId, pToEmailAddress)
Johannes Hörmann's avatar
Johannes Hörmann committed
{
    var params = {
        "ContactId_param" : pToContactId
    };
    if (pToEmailAddress)
        params.Recipient_param = pToEmailAddress;
        
Johannes Hörmann's avatar
Johannes Hörmann committed
    neon.openContext("Email", "EmailEdit_view", null, neon.OPERATINGSTATE_NEW, params);
}

S.Listl's avatar
S.Listl committed
EmailWritingUtils.getMailbridgeAddress = function ()
{
    return "mailbridge@domain.local"; //TODO: not hardcoded
}

Johannes Hörmann's avatar
Johannes Hörmann committed
/**
 * object for handling emails
 * 
 * @param {String|Array} [pToRecipients=[]] recipient email address or array of recipient email addresses
 * @param {String} [pSender=null] email address of the sender
 * @param {String} [pSubject=null] subject
 * @param {String} [pBody=null] mail body
 * @param {Array} [pCcRecipients=[]] array of recipient cc addresses
 * @param {Array} [pBccRecipients=[]] array of recipient bcc addresses
 * @class
 */
function Email (pToRecipients, pSender, pSubject, pBody, pCcRecipients, pBccRecipients)
{
    if (pToRecipients && typeof(pToRecipients) == "string")
        pToRecipients = [pToRecipients];
    
    this.sender = pSender;
    this.subject = pSubject;
    this.body = pBody;
    this.toRecipients = pToRecipients || [];
    this.ccRecipients = pCcRecipients || [];
    this.bccRecipients = pBccRecipients || [];
}

S.Listl's avatar
S.Listl committed
 * makes an Email object from a RFC
 * 
 * @param {String} pBase64RFC the RFC mail, base64 encoded
 * @return {Email} a new Email object
 */
Email.fromRFC = function (pBase64RFC)
{
    var mailData = mail.parseRFC(util.decodeBase64String(pBase64RFC));
    var body = mailData[mail.MAIL_HTMLTEXT];
    var sender = mailData[mail.MAIL_SENDER];
    var subject = mailData[mail.MAIL_SUBJECT];
    
    return new Email(null, sender, subject, body);
}

Johannes Hörmann's avatar
Johannes Hörmann committed
/**
 * loads a document template into the mail body
 * 
 * @param {String} pTemplateId the id of the template
 * @param {String} pContactId the id of the template
 * @param {String} pBindata binary data as base64
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
S.Listl's avatar
S.Listl committed
Email.prototype.setTemplate = function (pTemplateId, pContactId, pBindata)
Johannes Hörmann's avatar
Johannes Hörmann committed
{
S.Listl's avatar
S.Listl committed
    var template;
    if (pBindata && pBindata.isFilled())
    {
        if (BulkMailUtils.isValidMimeType(pBindata.mimeType))
        {
S.Listl's avatar
S.Listl committed
            template = new DocumentTemplate(pBindata.bindata, DocumentTemplate.types.fromMimeType(pBindata.mimeType), pBindata.filename);
S.Listl's avatar
S.Listl committed
        }
    }
    else
        template = DocumentTemplate.loadTemplate(pTemplateId);
    var email = template.getReplacedEmailsByContactIds([pContactId])[pContactId];
    this.sender = email.sender;
    this.body = email.body;
    this.subject = email.subject;
Johannes Hörmann's avatar
Johannes Hörmann committed
}

/**
 * sets the sender of the mail
 * 
 * @param {String} pContactId the contactId of the sender
 */
Email.prototype.setSender = function (pContactId)
{
    this.sender = CommUtil.getStandardMail(pContactId);
}

/**
 * generates a 'mailto:' URL from the email object
 */
Email.prototype.getMailtoUrl = function ()
{
    var url = [];
    
    if (this.toRecipients.length)
        url.push("to=" + this.toRecipients.join());
    
    if (this.ccRecipients.length)
        url.push("cc=" + this.ccRecipients.join());
    
    if (this.bccRecipients.length)
        url.push("bcc=" + this.bccRecipients.join());
    
    if (this.subject)
        url.push("subject=" + this.subject);
    
    if (this.body)
        url.push("body=" + text.html2text(this.body));
    
    url = "mailto:?" + url.join("&");
    
    return encodeURI(url);
}

/**
 * generates a eml-element from the email object
 */
Email.prototype.getRFCmail = function ()
{
    var ENCODING = "UTF-8";
    var mailId;
    try 
    {
        mailId = mail.newMail();
    }
    catch(ex)
    {
        //TODO: fix this dirty workaround [waiting for #1038963], since newMail causes an error on the first call after a user logged in
        logging.log(ex);
        util.sleep(1500);
        mailId = mail.newMail();
    }
S.Listl's avatar
S.Listl committed
    
Johannes Hörmann's avatar
Johannes Hörmann committed

    if (this.toRecipients.length)
        mail.addRecipients(mailId, mail.RECIPIENT_TO, this.toRecipients);

    if (this.ccRecipients.length)
        mail.addRecipients(mailId, mail.RECIPIENT_CC, this.ccRecipients);

    if (this.bccRecipients.length)
        mail.addRecipients(mailId, mail.RECIPIENT_BCC, this.bccRecipients);

S.Listl's avatar
S.Listl committed
    mail.setSubject(mailId, this.subject || "", ENCODING);
Johannes Hörmann's avatar
Johannes Hörmann committed
    if (this.body)
        mail.addText(mailId, this.body, "text/html", ENCODING, null);
    else
        mail.addText(mailId, "", "text/html", ENCODING, null);
    
    //"X-Unsent" is a very badly, non-standardised header to gently ask the mail client that the mail should open in a compose-mode
    //this is mainly done for Microsoft Outlook for Windows. 
    //Thunderbird has a dinosaur-request (it's from the year 2002) to also support this: https://bugzilla.mozilla.org/show_bug.cgi?id=166541 
    mail.addHeader(mailId, "X-Unsent", "1");
    
    //accoding to this entry: https://stackoverflow.com/questions/11330628/os-x-mail-open-eml-files-in-compose-mode/33224913
    //something similar exists for OS X Mail
    //X-Uniform-Type-Identifier: com.apple.mail-draft
    //this could be added later if needed

    var mailObj = mail.getCachedMail(mailId);
    return mail.toRFC(mailObj);
}

/**
 * opens the email
 */
Email.prototype.openMail = function ()
{
    neon.openUrl(this.getMailtoUrl(), false);
}

/**
 * ask for a download of the email
S.Listl's avatar
S.Listl committed
 * 
 * @return {Array} array of [filename, EML (base64)]
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
S.Listl's avatar
S.Listl committed
Email.prototype.downloadEML = function ()
{
    var eml = this.getEML();
    var filename = (this.subject || translate.text("Email Template")) + ".eml";
    neon.download(eml, filename);
    return [filename, eml];
}

/**
S.Listl's avatar
S.Listl committed
 * @return {String} RFC mail (base64 encoded)
S.Listl's avatar
S.Listl committed
 */
S.Listl's avatar
S.Listl committed
Email.prototype.getEML = function ()
Johannes Hörmann's avatar
Johannes Hörmann committed
{
S.Listl's avatar
S.Listl committed
    return util.encodeBase64String(this.getRFCmail(), null);
Johannes Hörmann's avatar
Johannes Hörmann committed
}

/**
 * sends the email object
 * 
 * @return {boolean} true, if the mail was sent sucessfully
 */
S.Listl's avatar
S.Listl committed
Email.prototype.send = function (pUser)
{
    var ENCODING = "UTF-8";
    var mailId;
    try
    {
S.Listl's avatar
S.Listl committed
        try 
        {
            mailId = mail.newMail();
        }
        catch(ex)
        {
            //TODO: fix this dirty workaround [waiting for #1038963], since newMail causes an error on the first call after a user logged in
            logging.log(ex);
            util.sleep(1500);
            mailId = mail.newMail();
        }
S.Listl's avatar
S.Listl committed
        
        if (this.sender)
            mail.setSender(mailId, this.sender);
        
S.Listl's avatar
S.Listl committed
        if (this.toRecipients.length)
            mail.addRecipients(mailId, mail.RECIPIENT_TO, this.toRecipients);

        if (this.ccRecipients.length)
            mail.addRecipients(mailId, mail.RECIPIENT_CC, this.ccRecipients);

        if (this.bccRecipients.length)
            mail.addRecipients(mailId, mail.RECIPIENT_BCC, this.bccRecipients);

S.Listl's avatar
S.Listl committed
        mail.setSubject(mailId, this.subject || "", ENCODING);
S.Listl's avatar
S.Listl committed

        if (this.body)
            mail.addText(mailId, this.body, "text/html", ENCODING, null);
        else
            mail.addText(mailId, "", "text/html", ENCODING, null);
    
S.Listl's avatar
S.Listl committed
        return mail.sendMailAs(pUser || "mailbridge", mailId) > 0;
        logging.log(ex);
        return false;
    }
}