Skip to content
Snippets Groups Projects
Commit d8fedf67 authored by Martin Groppe's avatar Martin Groppe
Browse files

Merge branch 'm_1080682_emailBounces' into '2021.1'

M 1080682 email bounces

See merge request xrm/basic!1066
parents e0f81c07 146bf430
No related branches found
No related tags found
No related merge requests found
Showing
with 258 additions and 32 deletions
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="s.listl" id="5ba15adf-e9c9-46ee-989e-7ee02a3a61b7">
<addColumn tableName="EMAIL_FILTER_HANDLING">
<column name="ACTION_TYPE" type="VARCHAR(36)"/>
<column name="WORKFLOWSIGNAL_NAME" type="NVARCHAR(250)"/>
</addColumn>
</changeSet>
</databaseChangeLog>
\ No newline at end of file
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="s.listl" id="286b9086-b5a3-4ffc-b747-c8836d874666">
<insert tableName="AB_KEYWORD_ENTRY">
<column name="AB_KEYWORD_ENTRYID" value="f79c7bad-9ff5-45d5-b93e-4ce52bf88c2d"/>
<column name="AB_KEYWORD_CATEGORY_ID" value="25cb446a-24cd-4ebd-aad2-320da20830da"/>
<column name="KEYID" value="EMAILBOUNCED_SOFT"/>
<column name="TITLE" value="Bounce (Soft)"/>
<column name="CONTAINER" value="BulkMailRecipientStatus"/>
<column name="SORTING" valueNumeric="4"/>
<column name="ISACTIVE" valueNumeric="1"/>
<column name="ISESSENTIAL" valueNumeric="1"/>
</insert>
<insert tableName="AB_KEYWORD_ENTRY">
<column name="AB_KEYWORD_ENTRYID" value="f42932ab-935a-46e9-957c-dd4e7f82daa8"/>
<column name="AB_KEYWORD_CATEGORY_ID" value="25cb446a-24cd-4ebd-aad2-320da20830da"/>
<column name="KEYID" value="EMAILBOUNCED_HARD"/>
<column name="TITLE" value="Bounce (Hard)"/>
<column name="CONTAINER" value="BulkMailRecipientStatus"/>
<column name="SORTING" valueNumeric="5"/>
<column name="ISACTIVE" valueNumeric="1"/>
<column name="ISESSENTIAL" valueNumeric="1"/>
</insert>
</changeSet>
</databaseChangeLog>
\ No newline at end of file
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<include relativeToChangelogFile="true" file="EmailFilter/alter_emailFilterHandling.xml"/>
<include relativeToChangelogFile="true" file="EmailFilter/insert_recipientStatusBounced.xml"/>
</databaseChangeLog>
\ No newline at end of file
......@@ -24,6 +24,7 @@
<include relativeToChangelogFile="true" file="basic/2021.0.2/changelog.xml"/>
<include relativeToChangelogFile="true" file="basic/2021.0.3/changelog.xml"/>
<include relativeToChangelogFile="true" file="basic/2021.1.0/changelog.xml"/>
<include relativeToChangelogFile="true" file="basic/2021.1.1/changelog.xml"/>
<include relativeToChangelogFile="true" file="basic/workflows/changelog.xml" context="workflow"/>
<!--enable this only when you definetly want to overwrite the existing data with demo records:-->
......
......@@ -226,6 +226,10 @@
<name>Interest</name>
<kind v="10077" />
</entityNode>
<entityNode>
<name>EmailFilterHandling</name>
<kind v="10077" />
</entityNode>
</childNodes>
</entityNode>
<entityNode>
......
......@@ -161,12 +161,14 @@
<title>Use for test run</title>
<onActionProcess>%aditoprj%/entity/BulkMailRecipient_entity/entityfields/testrunactions/children/settestrecipient/onActionProcess.js</onActionProcess>
<isObjectAction v="false" />
<iconId>VAADIN:CHECK</iconId>
</entityActionField>
<entityActionField>
<name>removeTestRecipient</name>
<title>Don't use for test run</title>
<onActionProcess>%aditoprj%/entity/BulkMailRecipient_entity/entityfields/testrunactions/children/removetestrecipient/onActionProcess.js</onActionProcess>
<isObjectAction v="false" />
<iconId>VAADIN:CLOSE</iconId>
</entityActionField>
</children>
</entityActionGroup>
......
......@@ -336,6 +336,7 @@
</entityConsumer>
<entityConsumer>
<name>BulkMailTestRecipients</name>
<selectionMode>MULTI</selectionMode>
<stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/bulkmailtestrecipients/stateProcess.js</stateProcess>
<dependency>
<name>dependency</name>
......
......@@ -36,6 +36,10 @@
<name>BODY_REGEX</name>
<title>Email body (Regular expression)</title>
</entityField>
<entityField>
<name>SENDERROR</name>
<title>Error</title>
</entityField>
</entityFields>
<recordContainers>
<jDitoRecordContainer>
......@@ -66,6 +70,10 @@
<name>ATTACHMENTCOUNT.value</name>
<isFilterable v="true" />
</jDitoRecordFieldMapping>
<jDitoRecordFieldMapping>
<name>SENDERROR.value</name>
<isFilterable v="true" />
</jDitoRecordFieldMapping>
</recordFieldMappings>
</jDitoRecordContainer>
</recordContainers>
......
......@@ -33,7 +33,7 @@
<name>WORKFLOWDEFINITION_KEY</name>
<title>Workflow</title>
<consumer>Workflows</consumer>
<displayValueProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/displayValueProcess.js</displayValueProcess>
<stateProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/stateProcess.js</stateProcess>
</entityField>
<entityConsumer>
<name>FilterTypeKeyword</name>
......@@ -82,6 +82,7 @@
<entityField>
<name>WORKFLOWSIGNAL_NAME</name>
<title>Signal</title>
<stateProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/workflowsignal_name/stateProcess.js</stateProcess>
</entityField>
<entityField>
<name>ACTION_TYPE</name>
......@@ -89,9 +90,24 @@
</entityField>
<entityField>
<name>ISFALLTHROUGH</name>
<title>Continue</title>
<contentType>BOOLEAN</contentType>
<valueProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/isfallthrough/valueProcess.js</valueProcess>
</entityField>
<entityConsumer>
<name>ActionTypeKeyword</name>
<dependency>
<name>dependency</name>
<entityName>KeywordEntry_entity</entityName>
<fieldName>SpecificContainerKeywords</fieldName>
</dependency>
<children>
<entityParameter>
<name>ContainerName_param</name>
<valueProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/actiontypekeyword/children/containername_param/valueProcess.js</valueProcess>
</entityParameter>
</children>
</entityConsumer>
</entityFields>
<recordContainers>
<dbRecordContainer>
......@@ -138,6 +154,13 @@
<name>ISFALLTHROUGH.value</name>
<recordfield>EMAIL_FILTER_HANDLING.ISFALLTHROUGH</recordfield>
</dbRecordFieldMapping>
<dbRecordFieldMapping>
<name>DESCRIPTION.value</name>
<recordfield>EMAIL_FILTER_HANDLING.DESCRIPTION</recordfield>
</dbRecordFieldMapping>
<dbRecordFieldMapping>
<name>WORKFLOWSIGNAL_NAME.value</name>
</dbRecordFieldMapping>
</recordFieldMappings>
<linkInformation>
<linkInformation>
......
import("KeywordRegistry_basic");
import("system.result");
result.string($KeywordRegistry.weblinkActionType());
\ No newline at end of file
import("system.vars");
import("system.result");
if (vars.get("$field.WORKFLOWDEFINITION_KEY"))
result.string("Werbeeinstellung setzen")
\ No newline at end of file
import("system.result");
import("system.vars");
import("KeywordRegistry_basic");
import("system.neon");
var actionType = vars.get("$field.ACTION_TYPE");
result.string(actionType == $KeywordRegistry.weblinkActionType$sendWorkflowSignal() ? neon.COMPONENTSTATE_EDITABLE : neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
import("system.db");
import("system.result");
result.object({
"PRIORITY": db.ASCENDING
});
\ No newline at end of file
......@@ -14,5 +14,28 @@
<titleField>TITLE</titleField>
<subtitleField>FILTER_TYPE</subtitleField>
</cardViewTemplate>
<genericViewTemplate>
<name>Generic</name>
<showDrawer v="true" />
<drawerCaption>Details</drawerCaption>
<fields>
<entityFieldLink>
<name>a71ac88f-f0c3-4de7-9d1f-a989212bed71</name>
<entityField>ISACTIVE</entityField>
</entityFieldLink>
<entityFieldLink>
<name>6cbad6d9-8434-4328-8d82-6010240a5a7f</name>
<entityField>ISFALLTHROUGH</entityField>
</entityFieldLink>
<entityFieldLink>
<name>2adc5e19-553a-41e6-8bd0-40e3b7fc98f6</name>
<entityField>ACTION_TYPE</entityField>
</entityFieldLink>
<entityFieldLink>
<name>560c1795-60ff-4ea6-b17b-19f49610bc8f</name>
<entityField>WORKFLOWDEFINITION_KEY</entityField>
</entityFieldLink>
</fields>
</genericViewTemplate>
</children>
</neonView>
......@@ -117,10 +117,9 @@ BulkMailAnalysisSql.countSelects =
CLICKCOUNT:"count(distinct WEBLINK_CLICK.WEBLINK_CLICKID)",
UNIQUECLICKCOUNT:"count(distinct WEBLINK_CLICK.MAIL_LOG_ID)",
OPENERCOUNT:"count(distinct MAIL_LOG.OPENER_LINK_CLICK_ID)",
//todo: Keywordregistry verwenden wenn bounces mit drin sind.
BOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS in ('EMAILBOUNCED_HARD','EMAILBOUNCED_SOFT') then MAIL_LOG.MAIL_LOGID else null end)",
SOFTBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='EMAILBOUNCED_SOFT' then MAIL_LOG.MAIL_LOGID else null end)",
HARDBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='EMAILBOUNCED_HARD' then MAIL_LOG.MAIL_LOGID else null end)",
BOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS in ('"+$KeywordRegistry.bulkMailRecipientStatus$softBounce()+"','"+$KeywordRegistry.bulkMailRecipientStatus$hardBounce()+"') then MAIL_LOG.MAIL_LOGID else null end)",
SOFTBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='"+$KeywordRegistry.bulkMailRecipientStatus$softBounce()+"' then MAIL_LOG.MAIL_LOGID else null end)",
HARDBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='"+$KeywordRegistry.bulkMailRecipientStatus$hardBounce()+"' then MAIL_LOG.MAIL_LOGID else null end)",
SENDCOUNT:"count (distinct MAIL_LOG.MAIL_LOGID)",
RECEIVEDCOUNT:"count (distinct case when MAIL_LOG.STATUS='"+$KeywordRegistry.bulkMailRecipientStatus$sent()+"' then MAIL_LOG.MAIL_LOGID else null end)",
UNSUBSCRIBECOUNT:"count (distinct case when WEBLINK_CLICK.WEBLINK_ID = '"+newSelect(["WEBLINK.WEBLINKID"]).from("WEBLINK").where("WEBLINK.PLACEHOLDER","rejectEmail").cell()+"' then WEBLINK_CLICK.MAIL_LOG_ID else null end)"
......
import("CommunicationBlacklist_lib");
import("EmailFilterHandling_lib");
import("system.logging");
import("system.entities");
import("MarketingCondition_lib");
......@@ -97,6 +99,8 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
recipientData = entities.getRows(recipientLoadConfig);
var blacklist = new CommunicationBlacklist().loadBlacklistRecipients(pBulkMailId);
if (pIsTestRun)
{
testRecipientData = newSelect("BULKMAILTESTRECIPIENT.CONTACT_ID, BULKMAILTESTRECIPIENT.EMAIL_ADDRESS")
......@@ -152,6 +156,8 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
var successIds = [];
var failedIds = [];
var bouncedSoftIds = [];
var bouncedHardIds = [];
var sentDate = vars.get("$sys.date");
var mails = template.getReplacedEmailsByContactIds(contactIds, additionalPlaceholders);
......@@ -160,11 +166,15 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
var bulkMailLink = [["BulkMail", pBulkMailId]];
var activitySubject = translate.withArguments("Bulk mail \"%0\" sent", [bulkMailName]);
var emailFilterProcessor = new IncomingEmailFilterProcessor().loadFilters();
if (!pIsTestRun)
{
recipientData.forEach(function (recipient)
{
let isSuccess = false;
let bouncedStatus = null;
let recipientId = recipient["BULKMAILRECIPIENTID"];
let contactId = recipient["CONTACT_ID"];
let emailAddress = recipient["EMAIL_ADDRESS"];
......@@ -172,6 +182,7 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
let organisationId = recipient["ORGANISATION_ID"];
let email = mails[contactId];
let mailLogId = mailLogIds.get(contactId);
let recipientStatus = $KeywordRegistry.bulkMailRecipientStatus$sent();
if (email !== undefined && emailAddress)
{
email.toRecipients = [emailAddress];
......@@ -180,6 +191,17 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
BulkMailUtils.storeEmlFile(pBulkMailId, mailrunId, mailLogId,email.getEML());
isSuccess = email.send();
if (!isSuccess)
{
var errorMessage = logging.toLogString(email.getMailError(), true);
var filterType = emailFilterProcessor.processError(errorMessage, contactId, emailAddress);
if (filterType == $KeywordRegistry.emailFilterType$bounceHard())
bouncedStatus = $KeywordRegistry.bulkMailRecipientStatus$hardBounce();
else if (filterType == $KeywordRegistry.emailFilterType$bounceSoft())
bouncedStatus = $KeywordRegistry.bulkMailRecipientStatus$softBounce();
recipientStatus = bouncedStatus || $KeywordRegistry.bulkMailRecipientStatus$failed();
}
}
//set the recipient status to 'sent' or 'failed'
......@@ -189,7 +211,7 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
"MAIL_LOGID": mailLogId,
"MAIL_RUN_ID": mailrunId,
"CONTACT_ID": contactId,
"STATUS": isSuccess ? $KeywordRegistry.bulkMailRecipientStatus$sent() : $KeywordRegistry.bulkMailRecipientStatus$failed(),
"STATUS": recipientStatus,
"SENDER_EMAIL": emailSender,
"RECIPIENT_EMAIL": emailAddress,
"MAILING_SUBJECT": subjects[contactId],
......@@ -197,7 +219,22 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
});
//TODO: Klären was von alter Logik noch bleiben soll. Status macht nur Sinn wenn jede Bulkmail nur einmal gesendet wird. Bleiben Activitys?
Array.prototype.push.call(isSuccess ? successIds : failedIds, recipientId);
if (isSuccess)
{
sucessIds.push(recipientId);
}
else if (bouncedStatus == $KeywordRegistry.bulkMailRecipientStatus$softBounce())
{
bouncedSoftIds.push(recipientId);
}
else if (bouncedStatus == $KeywordRegistry.bulkMailRecipientStatus$hardBounce())
{
bouncedHardIds.push(recipientId);
}
else
{
failedIds.push(recipientId);
}
if (isSuccess && createActivity == "1")
{
let activityData = {
......@@ -223,6 +260,18 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
"SENTDATE": sentDate
});
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", bouncedSoftIds, SqlBuilder.IN())
.updateFields({
"STATUS": $KeywordRegistry.bulkMailRecipientStatus$softBounce(),
"SENTDATE": sentDate
});
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", bouncedHardIds, SqlBuilder.IN())
.updateFields({
"STATUS": $KeywordRegistry.bulkMailRecipientStatus$hardBounce(),
"SENTDATE": sentDate
});
newWhere("MAIL_RUN.MAIL_RUNID", mailrunId)
.updateFields({
"STATUS": $KeywordRegistry.bulkMailStatus$sent(),
......
import("KeywordRegistry_basic");
import("system.entities");
import("Util_lib");
import("Sql_lib");
import("system.vars");
......@@ -5,17 +7,18 @@ import("system.vars");
function CommunicationBlacklist ()
{
this.filter = null;
this.filter = CommunicationBlacklist.getMailRecipientBlacklistFilter();
this.blacklistContactIds = new Set();
}
/**
* @return {CommunicationBlacklist}
*/
CommunicationBlacklist.getMailRecipientBlacklist = function ()
CommunicationBlacklist.getMailRecipientBlacklistFilter = function ()
{
var filters = newSelect("FILTER")
.from("EMAIL_FILTER_HANDLING")
.where("COMMUNICATIONBLACKLIST.BLACKLIST_TYPE", $KeywordRegistry.communicationBlacklistType$emailRecipientFilter())
.where("EMAIL_FILTER_HANDLING.FILTER_TYPE", $KeywordRegistry.emailFilterType$blacklist())
.table();
var filterMappingFn = function ([blacklistFilter])
......@@ -27,19 +30,34 @@ CommunicationBlacklist.getMailRecipientBlacklist = function ()
return blacklistFilter.filter;
};
var blacklist = new CommunicationBlacklist();
blacklist.filter = {
return {
type: "group",
operator: "AND",
childs: filters.map(filterMappingFn).filter(Utils.isObject)
};
return blacklist;
}
CommunicationBlacklist.prototype.getCondition = function ()
CommunicationBlacklist.prototype.getFilter = function ()
{
return new FilterSqlTranslator()
.filter(this.filter)
.table("BULKMAILRECIPIENT")
.getSqlCondition();
}
\ No newline at end of file
return this.filter;
}
CommunicationBlacklist.prototype.loadBlacklistRecipients = function (pBulkMailId)
{
var blacklistLoadConfig = entities.createConfigForLoadingRows()
.fields(["CONTACT_ID"])
.entity("BulkmailRecipient_entity")
.provider("RecipientsToBeMailed")
.addParameter("BulkMailId_param", pBulkMailId)
.filter(JSON.stringify(this.filter));
var blacklist = entities.getRows(blacklistLoadConfig);
blacklist.forEach(function (recipient)
{
this.blacklistContactIds.add(recipient["CONTACT_ID"]);
}, this);
}
CommunicationBlacklist.prototype.hasContactId = function (pContactId)
{
return this.blacklistContactIds.has(pContactId);
}
......@@ -18,8 +18,8 @@ IncomingEmailFilterProcessor.prototype.loadFilters = function ()
var bounceFilters = newSelect(["TITLE", "FILTER_TYPE", "FILTER", "WORKFLOWDEFINITION_KEY"])
.from("EMAIL_FILTER_HANDLING")
.where("EMAIL_FILTER_HANDLING.ISACTIVE", "1")
.and(newWhere("EMAIL_FILTER.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceSoft())
.or("EMAIL_FILTER.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceHard()))
.and(newWhere("EMAIL_FILTER_HANDLING.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceSoft())
.or("EMAIL_FILTER_HANDLING.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceHard()))
.orderBy("PRIORITY asc")
.table();
......@@ -27,6 +27,7 @@ IncomingEmailFilterProcessor.prototype.loadFilters = function ()
{
return new IncomingEmailFilter(title, type, filterJson, workflowKey);
});
return this;
}
/**
......@@ -34,13 +35,30 @@ IncomingEmailFilterProcessor.prototype.loadFilters = function ()
*/
IncomingEmailFilterProcessor.prototype.process = function (pEmail)
{
var bouncedStatus = null;
this.emailFilters.forEach(function (emailFilter)
{
if (emailFilter.checkEmail(pEmail))
{
emailFilter.startWorkflow();
bouncedStatus = emailFilter.type;
}
});
return bouncedStatus;
}
IncomingEmailFilterProcessor.prototype.processError = function (pErrorMessage, pContactId, pEmailAddress)
{
var bouncedStatus = null;
this.emailFilters.forEach(function (emailFilter)
{
if (emailFilter.checkEmailError(pErrorMessage))
{
emailFilter.startWorkflow(pContactId, pEmailAddress);
bouncedStatus = emailFilter.type;
}
});
return bouncedStatus;
}
/**
......@@ -52,7 +70,7 @@ function IncomingEmailFilter (pTitle, pType, pFilterJson, pWorkflowKey)
this.type = pType;
this.filter = new JditoFilter()
.filterJSON(pFilterJson)
.fieldOrder(["SENDER", "SUBJECT", "BODY_PLAIN", "BODY_REGEX", "ATTACHMENTCOUNT"])
.fieldOrder(["SENDER", "SUBJECT", "BODY_PLAIN", "BODY_REGEX", "ATTACHMENTCOUNT", "SENDERROR"])
.addSpecialCheckFn("BODY_REGEX", function (rowValue, filterValue, operator)
{
var regExParts = filterValue.match(new RegExp('^/(.*?)/([gimy]*)$'));
......@@ -64,7 +82,7 @@ function IncomingEmailFilter (pTitle, pType, pFilterJson, pWorkflowKey)
return regEx.test(rowValue);
}, this);
this.workflowKey = pWorkflowKey;
this.isFallthrough = pIsFallthrough;
this.isFallthrough = false;
}
/**
......@@ -79,11 +97,17 @@ IncomingEmailFilter.prototype.checkEmail = function (pEmail)
var subject = pEmail[mail.MAIL_SUBJECT];
var body = pEmail[mail.MAIL_TEXT];
var attachmentCount = pEmail[mail.MAIL_ATTACHMENTCOUNT];
var emailRecord = [sender, subject, body, body, attachmentCount];
var emailRecord = [sender, subject, body, body, attachmentCount, ""];
return this.filter.checkRecord(emailRecord);
}
IncomingEmailFilter.prototype.checkEmailError = function (pError)
{
var emailRecord = ["", "", "", "", "", pError];
return this.filter.checkRecord(emailRecord);
}
/**
* Inserts an entry into the MAIL_LOG table to protocol the received email.
*
......@@ -94,18 +118,22 @@ IncomingEmailFilter.prototype.writeMailLog = function (pEmail)
{
new SqlBuilder.insertFields({
"MAIL_LOGID": util.getNewUUID()
}, pTableName);
}
/**
* Starts the workflow that has been defined for the email filter.
*/
IncomingEmailFilter.prototype.startWorkflow = function ()
IncomingEmailFilter.prototype.startWorkflow = function (pContactId, pEmailAddress)
{
if (this.workflowKey)
{
workflow.startProcessByKey(this.workflowKey, {
contactId: pContactId,
emailAddress: pEmailAddress,
channelType: $KeywordRegistry.communicationChannelType$communication(),
medium: $KeywordRegistry.communicationMediumCampaign$mail()
});
}
}
......
......@@ -169,6 +169,7 @@ function Email(pBody)
this.bccRecipients = [];
this.attachmentTemplates = [];
this.emlFile = null;
this._error = null; //caches the error if sending fails
}
/**
......@@ -409,12 +410,24 @@ Email.prototype.send = function (pUser)
question.showMessage(translate.withArguments("Mailbridge failed: user '%0' is unknown, contact an administrator.", [mailbridgeTitle]), question.ERROR, translate.text("Error"));
}
// remove from cache
mail.deleteMail(mailId)
mail.deleteMail(mailId);
this._error = null;
return sentMails > 0;
}
catch (ex)
{
this._error = ex;
logging.log(ex);
return false;
}
}
/**
* Returns the error from sending the email
*
* @return {Error} error if sending failed, or null if it was sucessful
*/
Email.prototype.getMailError = function ()
{
return this._error;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment