diff --git a/12-csat/code/src/functions/common/constants.ts b/12-csat/code/src/functions/common/constants.ts
index 228747d..4b83e4e 100644
--- a/12-csat/code/src/functions/common/constants.ts
+++ b/12-csat/code/src/functions/common/constants.ts
@@ -19,6 +19,9 @@ export const SurveysSubmitAPIMethodPath = '/surveys.submit';
export const SurveysListAPIMethodPath = '/surveys.list';
export const SurveysSendAPIMethodPath = '/surveys.send';
+// Snap-kit Action
+export const SnapKitActionCreateDeferredAPIMethodPath = '/snap-kit-action.create.deferred';
+
export const EMAIL = 'email';
export const EmailSubject = 'Support experience feedback for ';
export const PLUG = 'plug';
diff --git a/12-csat/code/src/functions/common/utils.ts b/12-csat/code/src/functions/common/utils.ts
index 66d43ea..682de6f 100644
--- a/12-csat/code/src/functions/common/utils.ts
+++ b/12-csat/code/src/functions/common/utils.ts
@@ -8,9 +8,11 @@ import {
WorksGetAPIMethodPath,
} from './constants';
+export const SurveysEmailCsatResponsePath = '/survey-response';
const SnapKitActionID = 'rating';
const SnapInActionName = 'survey';
+export const dispatchIdAndRatingDeliminator = '::';
export async function doDevRevPostAPICall(apiBase: string, method: string, data: object, auth: string) {
const url = apiBase + method;
@@ -51,10 +53,10 @@ interface snapKitButtonJson {
export function getSnapKitBody(objId: string, snap_in_id: string, survey_text_header: string, survey_text: string,
surveyRespScale: string, visibility: string, members: string[], expires_at :string,
- label: string) {
+ dispatchId: string, label: string) {
let buttonsText = getButtonsText(surveyRespScale);
- const buttons = generateButtonJson(buttonsText);
+ const buttons = generateButtonJson(buttonsText, dispatchId);
let snapKitBody: { [key: string]: any } = {};
@@ -137,7 +139,7 @@ function getButtonsText(surveyRespScale: string) {
return buttonsText;
}
-function generateButtonJson(buttonsText: string[]): snapKitButtonJson[] {
+function generateButtonJson(buttonsText: string[], dispatchId: string): snapKitButtonJson[] {
const result: snapKitButtonJson[] = [];
const maxScale = 5;
@@ -151,7 +153,7 @@ function generateButtonJson(buttonsText: string[]): snapKitButtonJson[] {
type: 'plain_text',
},
type: 'button',
- value: (maxScale - i).toString(),
+ value: `${dispatchId}${dispatchIdAndRatingDeliminator}` + (maxScale - i).toString(),
});
}
@@ -205,6 +207,17 @@ export function getTimelineCommentBody(objId: string, bodyText :string, visibili
return timelineBody;
}
+export function getEmailBody(subject: string, sender: string, recipients: string[], htmlBodyStr: string) {
+ return {
+ 'email': {
+ 'subject': subject,
+ 'body': htmlBodyStr,
+ 'recipients': recipients,
+ 'sender': sender,
+ },
+ };
+}
+
export function getSnapKitActionCreateBody(baseObj: string, snapIn: string, channel: string, dispatchedTo: string ) {
return {
'base_object': baseObj,
@@ -223,6 +236,150 @@ export function getExpiryTimestamp(timeInMin : number) {
return new Date(numberOfMlSeconds + addMlSeconds);
}
+// TODO: isTicket, ticketTitle, ticketDescription are the fields which are added for the tiket only. Ideally this is not scalable. But as
+// currently there is no support for HTML given snap-kit this is stop gap solution.
+export function getHtmlSurveyString(apiDomain:string, dispatchId: string, emailId: string, surveyTextHeader: string,
+ surveyText: string, surveyRespScale: string, isTicket: boolean,
+ ticketDisplayId: string, ticketTitle: string, ticketDescription: string): string {
+
+ let buttonsText = getButtonsText(surveyRespScale);
+
+ const apiPrefix = 'https://support.';
+ const hoverText = 'Select this rating';
+
+ const rating1 = `${apiPrefix}${apiDomain}${SurveysEmailCsatResponsePath}?uuid=${dispatchId}&id=${SnapKitActionID}&value=${dispatchId}${dispatchIdAndRatingDeliminator}1`;
+ const rating2 = `${apiPrefix}${apiDomain}${SurveysEmailCsatResponsePath}?uuid=${dispatchId}&id=${SnapKitActionID}&value=${dispatchId}${dispatchIdAndRatingDeliminator}2`;
+ const rating3 = `${apiPrefix}${apiDomain}${SurveysEmailCsatResponsePath}?uuid=${dispatchId}&id=${SnapKitActionID}&value=${dispatchId}${dispatchIdAndRatingDeliminator}3`;
+ const rating4 = `${apiPrefix}${apiDomain}${SurveysEmailCsatResponsePath}?uuid=${dispatchId}&id=${SnapKitActionID}&value=${dispatchId}${dispatchIdAndRatingDeliminator}4`;
+ const rating5 = `${apiPrefix}${apiDomain}${SurveysEmailCsatResponsePath}?uuid=${dispatchId}&id=${SnapKitActionID}&value=${dispatchId}${dispatchIdAndRatingDeliminator}5`;
+
+ return `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+ Your Feedback Matters!
+ |
+  |
+
+
+
+ |
+
+
+
+
+
+
+
+ Hi,
+ ${surveyTextHeader}
+
+
+ ${ticketDisplayId}
+ ${ticketTitle}
+
+ ${ticketDescription}
+
+ |
+
+
+
+
+
+
+
+ ${surveyText}
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ Your response will be recorded. We'll use it only for the purpose of improving our services!
+ This email was sent to ${emailId}. If you're not them, please ignore it.
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+ `;
+}
+
export async function getSurveyId(apiBase: string, auth: string, name: string) {
try {
console.log(`Listing surveys with name: [${name}]`);
diff --git a/12-csat/code/src/functions/post_survey/index.ts b/12-csat/code/src/functions/post_survey/index.ts
index a182bf3..fa4acf4 100644
--- a/12-csat/code/src/functions/post_survey/index.ts
+++ b/12-csat/code/src/functions/post_survey/index.ts
@@ -2,8 +2,11 @@ import {
doDevRevPostAPICall,
getAPIBase,
getSnapKitBody,
+ getEmailBody,
+ getHtmlSurveyString,
getTimelineCommentBody,
getAPIDomain,
+ getSnapKitActionCreateBody,
getExpiryTimestamp,
getSurveyId,
getWork,
@@ -15,28 +18,31 @@ import {
PLUG,
PORTAL,
CHAT,
+ EmailSubject,
INTERNAL,
PRIVATE,
+ SurveysSendAPIMethodPath,
TimelineEntriesCreateAPIMethodPath,
+ SnapKitActionCreateDeferredAPIMethodPath,
DefaultCSATName,
TimelineLabelDisplayCustomerChat,
} from '../common/constants';
-
+
interface Stakeholder {
id?: string;
email_id?: string;
}
-
+
const commentExpireAt2Min = getExpiryTimestamp(2).toISOString();
-
-
+
+
export class PostSurvey {
constructor() {}
-
+
async PostSurvey(event: any) {
- console.log('Creating survey on event payload: ', JSON.stringify(event.payload));
- console.log('Event Context: ', JSON.stringify(event.context));
- try {
+ console.log('Creating survey on event payload: ', JSON.stringify(event.payload));
+ console.log('Event Context: ', JSON.stringify(event.context));
+ try {
const payload = event.payload;
const executionMetadata = event.execution_metadata;
const apiBase = getAPIBase(executionMetadata);
@@ -46,11 +52,11 @@ export class PostSurvey {
let objId = '';
let objDisplayID = '';
let objType = '';
-
+
let isTicket = false;
let ticketTitle = '';
let ticketDescription = '';
-
+
console.log('Event Context auth service account token: ', auth);
// Global configuration values
let surveyExpiresAfterInMin = parseInt(event.input_data.global_values.survey_expires_after);
@@ -59,47 +65,47 @@ export class PostSurvey {
const surveyRespScale = event.input_data.global_values.survey_resp_scale;
const surveyChannels = event.input_data.global_values.survey_channel;
let commandChannel = '';
-
+
if (surveyExpiresAfterInMin < 1) {
- console.log(`Invalid survey expiry time: [${surveyExpiresAfterInMin}min]. Setting to default [1min]`);
- surveyExpiresAfterInMin = 1;
+ console.log(`Invalid survey expiry time: [${surveyExpiresAfterInMin}min]. Setting to default [1min]`);
+ surveyExpiresAfterInMin = 1;
}
-
+
let surveyStakeholders : Stakeholder[] = [];
-
+
// This condition means snap-in is triggered by command.
if (payload.hasOwnProperty('command_id')) {
- objId = payload.source_id;
-
- if (payload.parameters !== '') {
+ objId = payload.source_id;
+
+ if (payload.parameters !== '') {
let commandParams = getCommandParameters(payload.parameters);
if (commandParams == null) {
- let bodyMsgDev = `Unexpected request:\nExpected: chat/email survey question\nReceived: ${payload.parameters}.`;
- let postBodyDev = getTimelineCommentBody(objId, bodyMsgDev, INTERNAL, null, commentExpireAt2Min, null);
- try {
+ let bodyMsgDev = `Unexpected request:\nExpected: chat/email survey question\nReceived: ${payload.parameters}.`;
+ let postBodyDev = getTimelineCommentBody(objId, bodyMsgDev, INTERNAL, null, commentExpireAt2Min, null);
+ try {
console.log('Posting invalid parameters comment on timeline for Dev Org');
const resp = await doDevRevPostAPICall(apiBase, TimelineEntriesCreateAPIMethodPath, postBodyDev, auth);
if (resp.ok) {
- console.log('Successfully added invalid parameters comment on timeline for Dev Org.');
+ console.log('Successfully added invalid parameters comment on timeline for Dev Org.');
} else {
- let body = await resp.text();
- console.error('Error while posting invalid parameters comment on timeline for Dev Org: ', resp.status, body);
- return;
+ let body = await resp.text();
+ console.error('Error while posting invalid parameters comment on timeline for Dev Org: ', resp.status, body);
+ return;
}
console.log('Invalid parameters comment sent successfully to timeline for Dev Org.');
- } catch (error) {
+ } catch (error) {
console.error('Error: ', error);
- }
- return;
+ }
+ return;
}
commandChannel = commandParams[0].toLowerCase();
surveyText = commandParams[1];
- }
-
- if (objId.includes('ticket')) {
+ }
+
+ if (objId.includes('ticket')) {
const work = await getWork(apiBase, auth, objId);
if (work == null) {
- return;
+ return;
}
console.log(`ticket information for object ID: [${objId}] ,`, JSON.stringify(work));
objType = work.type;
@@ -108,36 +114,36 @@ export class PostSurvey {
isTicket = true;
ticketTitle = work.title;
ticketDescription = work.body;
- } else {
+ } else {
const conversation = await getConversation(apiBase, auth, objId);
if (conversation == null) {
- return;
+ return;
}
console.log(`conversation information for object ID: [${objId}] ,`, JSON.stringify(conversation));
objType = conversation.type;
objDisplayID = conversation.display_id;
surveyStakeholders = this.getStakeholders(conversation.members);
- }
+ }
} else {
- let isTypeMatched = false;
- if (payload.hasOwnProperty('conversation_updated')) {
+ let isTypeMatched = false;
+ if (payload.hasOwnProperty('conversation_updated')) {
objType = 'conversation';
let conversation = payload.conversation_updated.conversation;
let old_conversation = payload.conversation_updated.old_conversation;
if (conversation.state != 'closed' || conversation.status != 'closed') {
- console.log(`State: [${conversation.state}], Status: [${conversation.status}]. Conversation is not closed. returning...`);
- return;
+ console.log(`State: [${conversation.state}], Status: [${conversation.status}]. Conversation is not closed. returning...`);
+ return;
}
if (conversation.state == 'closed' && conversation.status == 'closed' &&
- old_conversation.state == 'closed' && old_conversation.status == 'closed') {
- console.log(`State: [${conversation.state}], Status: [${conversation.status}]. Conversation is already closed. returning...`);
- return;
+ old_conversation.state == 'closed' && old_conversation.status == 'closed') {
+ console.log(`State: [${conversation.state}], Status: [${conversation.status}]. Conversation is already closed. returning...`);
+ return;
}
isTypeMatched = true;
objId = conversation.id;
objDisplayID = conversation.display_id;
surveyStakeholders = this.getStakeholders(conversation.members);
- } else if (payload.hasOwnProperty('work_updated')) {
+ } else if (payload.hasOwnProperty('work_updated')) {
let work = payload.work_updated.work;
let stage = work.stage.name;
let state = work.state;
@@ -145,19 +151,19 @@ export class PostSurvey {
let old_stage = old_work.stage.name;
let old_state = old_work.state;
objType = 'ticket';
-
+
let type = work.type.toLowerCase();
if (type != 'ticket') {
- console.log(`Work Type is [${type}]. Not a ticket. returning...`);
- return;
+ console.log(`Work Type is [${type}]. Not a ticket. returning...`);
+ return;
}
if (stage != 'resolved' || state != 'closed') {
- console.log(`Stage: [${stage}], State: [${state}]. Ticket is not resolved. returning...`);
- return;
+ console.log(`Stage: [${stage}], State: [${state}]. Ticket is not resolved. returning...`);
+ return;
}
if (stage == 'resolved' && state == 'closed' && old_stage == 'resolved' && old_state == 'closed') {
- console.log(`Stage: [${stage}], State: [${state}]. Ticket is already resolved. returning...`);
- return;
+ console.log(`Stage: [${stage}], State: [${state}]. Ticket is already resolved. returning...`);
+ return;
}
isTypeMatched = true;
objId = work.id;
@@ -166,118 +172,182 @@ export class PostSurvey {
isTicket = true;
ticketTitle = work.title;
ticketDescription = work.body;
- }
-
- if (!isTypeMatched) {
+ }
+
+ if (!isTypeMatched) {
console.log('Event type is neither [conversation_updated] nor [work_updated]. returning...');
return;
- }
+ }
}
-
+
const surveyId = await getSurveyId(apiBase, auth, DefaultCSATName);
if (surveyId == null) {
- console.log('SurveyId is null cannot proceed with processing. returning...');
- return;
+ console.log('SurveyId is null cannot proceed with processing. returning...');
+ return;
}
-
+
console.log(`Posting survey on survey channels ${surveyChannels} with SurveyId [${surveyId}] for an Object [${objId}].`);
let isSurveySent = false;
for (let i = 0; i < surveyStakeholders.length; i++) {
- // To track on which channels survey is actually sent.
- let surveySentOnChannels : string[] = [];
- for (let channel = 0; channel < surveyChannels.length; channel++) {
+ const deferredUUID = await this.getSnapInExecutionDeferredUUID(apiBase, auth, objId, snapInId,
+ surveyStakeholders[i].id!!);
+ // Just a conservative check in case this happens
+ if (deferredUUID === '') {
+ continue;
+ }
+
+ // To track on which channels survey is actually sent.
+ let surveySentOnChannels : string[] = [];
+ for (let channel = 0; channel < surveyChannels.length; channel++) {
let surveyChannel = surveyChannels[channel].toLowerCase();
-
+
if (payload.hasOwnProperty('command_id')) {
- // In case of commands send survey only on channel described in command
- if (
- ((surveyChannel === PLUG || surveyChannel === PORTAL) && commandChannel !== CHAT)
- ) {
+ // In case of commands send survey only on channel described in command
+ if (
+ ((surveyChannel === PLUG || surveyChannel === PORTAL) && commandChannel !== CHAT) ||
+ (surveyChannel === EMAIL && commandChannel !== EMAIL)
+ ) {
console.log(`Survey is not sent on command as config channel: [${surveyChannel}] and command channel: [${commandChannel}].`);
continue;
- }
+ }
}
-
+
switch (surveyChannel) {
- case PLUG:
- case PORTAL: {
+ case EMAIL: {
+ if (surveyStakeholders[i].email_id !== undefined) {
+ console.log(`Posting survey on survey channel [${surveyChannel}].`);
+ await this.sendEmail(apiBase, auth, deferredUUID, surveyStakeholders[i].email_id!,
+ objDisplayID, surveyTextHeader, surveyText, surveyRespScale, isTicket, ticketTitle,
+ ticketDescription);
+ surveySentOnChannels.push(surveyChannel);
+ }
+ break;
+ }
+ case PLUG:
+ case PORTAL: {
console.log(`Posting survey on survey channel [${surveyChannel}].`);
const expiresAt = getExpiryTimestamp(surveyExpiresAfterInMin);
const snapKitBody = getSnapKitBody(objId, snapInId, surveyTextHeader,
- surveyText, surveyRespScale, PRIVATE, [surveyStakeholders[i].id!], expiresAt.toISOString(), TimelineLabelDisplayCustomerChat);
+ surveyText, surveyRespScale, PRIVATE, [surveyStakeholders[i].id!], expiresAt.toISOString(),
+ deferredUUID, TimelineLabelDisplayCustomerChat);
const resp = await doDevRevPostAPICall(apiBase, TimelineEntriesCreateAPIMethodPath, snapKitBody, auth);
if (resp.ok) {
- console.log(`Successfully posted message on [${objId}] for User [${surveyStakeholders[i].id!}]`);
- surveySentOnChannels.push(surveyChannel);
+ console.log(`Successfully posted message on [${objId}] for User [${surveyStakeholders[i].id!}]`);
+ surveySentOnChannels.push(surveyChannel);
} else {
- let body = await resp.text();
- console.error(`Error while posting message on [${objId}] for User [${surveyStakeholders[i].id!}] `, resp.status, body);
+ let body = await resp.text();
+ console.error(`Error while posting message on [${objId}] for User [${surveyStakeholders[i].id!}] `, resp.status, body);
}
break;
- }
+ }
}
- }
-
- if (surveySentOnChannels.length > 0) {
+ }
+
+ if (surveySentOnChannels.length > 0) {
isSurveySent = true;
- }
+ }
}
-
+
if (isSurveySent) {
- let bodyMsgDev = `Customer feedback has been requested for this ${objType}.`;
- const expiresAt = getExpiryTimestamp(surveyExpiresAfterInMin);
- let postBodyDev = getTimelineCommentBody(objId, bodyMsgDev, INTERNAL, null, expiresAt.toISOString(), TimelineLabelDisplayCustomerChat);
- try {
+ let bodyMsgDev = `Customer feedback has been requested for this ${objType}.`;
+ const expiresAt = getExpiryTimestamp(surveyExpiresAfterInMin);
+ let postBodyDev = getTimelineCommentBody(objId, bodyMsgDev, INTERNAL, null, expiresAt.toISOString(), TimelineLabelDisplayCustomerChat);
+ try {
console.log('Posting survey sent message on timeline for Dev Org');
const resp = await doDevRevPostAPICall(apiBase, TimelineEntriesCreateAPIMethodPath, postBodyDev, auth);
if (resp.ok) {
- console.log('Successfully added survey sent message on timeline for Dev Org.');
+ console.log('Successfully added survey sent message on timeline for Dev Org.');
} else {
- let body = await resp.text();
- console.error('Error while posting survey sent message on timeline for Dev Org: ', resp.status, body);
- return;
+ let body = await resp.text();
+ console.error('Error while posting survey sent message on timeline for Dev Org: ', resp.status, body);
+ return;
}
console.log('Survey sent message successfully to timeline for Dev Org.');
- } catch (error) {
+ } catch (error) {
console.error('Error: ', error);
- }
+ }
}
- } catch (error) {
+ } catch (error) {
console.error('Error: ', error);
- }
+ }
+ }
+
+ async getSnapInExecutionDeferredUUID(apiBase: string, auth: string, objID: string, snapInID: string, stakeholderID: string) {
+ const actionReqBody = getSnapKitActionCreateBody(objID, snapInID, 'App', stakeholderID);
+ const actionResp = await doDevRevPostAPICall(apiBase, SnapKitActionCreateDeferredAPIMethodPath, actionReqBody, auth);
+ if (actionResp.ok) {
+ console.log(`Successfully created deferred UUID for User [${stakeholderID}].`);
+ let respJsonBody = await actionResp.json();
+ if (respJsonBody.hasOwnProperty('execution')) {
+ let execution = respJsonBody.execution;
+ if (execution.hasOwnProperty('id')) {
+ console.log(`Deferred UUID for User [${stakeholderID}] is UUID [${execution.id}]`);
+ return execution.id;
+ } else {
+ console.error(`Missing "ID" in snap-kit-execution-create-deferred response [${respJsonBody}]`);
+ }
+ } else {
+ console.error(`Missing "Execution" in snap-kit-execution-create-deferred response [${respJsonBody}]`);
+ }
+ } else {
+ let body = await actionResp.text();
+ console.error(`Error while creating snap-kit-execution-create-deferred for User [${stakeholderID}] , Response: [${body}]`);
+ }
+ return '';
+ }
+
+ async sendEmail(apiBase: string, auth: string, deferredUUID: string, emailId: string, objDisplayID: string,
+ surveyTextHeader: string, surveyText: string, surveyRespScale: string,
+ isTicket: boolean, ticketTitle: string, ticketDescription: string) {
+ const apiDomain = getAPIDomain(apiBase);
+ const htmlString = getHtmlSurveyString(apiDomain, deferredUUID, emailId, surveyTextHeader, surveyText,
+ surveyRespScale, isTicket, objDisplayID, ticketTitle, ticketDescription);
+ const emailSender = `Support Experience `;
+
+ const htmlBody = getEmailBody(`${EmailSubject} ${objDisplayID}`, emailSender, [emailId], htmlString);
+ if (htmlBody == null) {
+ return;
+ }
+ const resp = await doDevRevPostAPICall(apiBase, SurveysSendAPIMethodPath, htmlBody, auth);
+ if (resp.ok) {
+ console.log(`Successfully sent an email to User [${emailId}]`);
+ } else {
+ let body = await resp.text();
+ console.error(`Error while sending an email to User [${emailId}] `, resp.status, body);
+ }
}
-
+
getStakeholders(stakeholdersFromObj: any[]): Stakeholder[] {
- console.log('stakeholders from object: ', JSON.stringify(stakeholdersFromObj));
- let stakeholders : Stakeholder[] = [];
- for (let i = 0; i < stakeholdersFromObj.length; i++) {
+ console.log('stakeholders from object: ', JSON.stringify(stakeholdersFromObj));
+ let stakeholders : Stakeholder[] = [];
+ for (let i = 0; i < stakeholdersFromObj.length; i++) {
console.log('stakeholders: ', JSON.stringify(stakeholdersFromObj[i]));
const stakeholder : Stakeholder = {};
if (stakeholdersFromObj[i].type == 'rev_user') {
- stakeholder.id = stakeholdersFromObj[i].id;
- if (stakeholdersFromObj[i].hasOwnProperty('email')) {
+ stakeholder.id = stakeholdersFromObj[i].id;
+ if (stakeholdersFromObj[i].hasOwnProperty('email')) {
stakeholder.email_id = stakeholdersFromObj[i].email;
- }
+ }
}
stakeholders.push(stakeholder);
- }
- console.log('stakeholders after filtering: ', JSON.stringify(stakeholders));
- return stakeholders;
+ }
+ console.log('stakeholders after filtering: ', JSON.stringify(stakeholders));
+ return stakeholders;
}
-
-
+
+
}
-
+
export const run = async (events: any[]) => {
-
+
console.log('Running SnapIn for survey - post_survey', events);
-
+
const postSurvey = new PostSurvey();
for (let event of events) {
- await postSurvey.PostSurvey(event);
+ await postSurvey.PostSurvey(event);
}
-
+
console.info('events', events);
};
-
+
export default run;
\ No newline at end of file
diff --git a/12-csat/code/src/functions/process_response/index.ts b/12-csat/code/src/functions/process_response/index.ts
index 9a79041..e68ece8 100644
--- a/12-csat/code/src/functions/process_response/index.ts
+++ b/12-csat/code/src/functions/process_response/index.ts
@@ -1,9 +1,9 @@
import {
- doDevRevGetAPICall,
doDevRevPostAPICall,
getAPIBase, getSurveyId,
getTimelineCommentBody,
getExpiryTimestamp,
+ dispatchIdAndRatingDeliminator,
} from '../common/utils';
import {
@@ -11,7 +11,7 @@ import {
TimelineEntriesCreateAPIMethodPath,
TimelineEntriesDeleteAPIMethodPath,
SurveysSubmitAPIMethodPath,
- RevUsersGetAPIMethodPath, TimelineLabelDisplayCustomerChat,
+ TimelineLabelDisplayCustomerChat,
} from '../common/constants';
@@ -24,13 +24,23 @@ async function ProcessSurveyResponse(event: any) {
const auth = event.context.secrets.service_account_token;
const actorAuth = event.context.secrets.actor_session_token;
const actorId = payload.actor_id;
- const rating = parseInt(payload.action.value);
+ const dispatchIdAndRating = splitDispatchIdAndRating(payload.action.value);
+ let dispatchId = '';
+ let rating = 0;
let privateToRev = [actorId];
const surveyRespText = event.input_data.global_values.survey_resp_text;
let sourceChannel = getSourceChannel(payload);
// Currently hardcoded with 30minutes
const commentExpireAt = getExpiryTimestamp(30).toISOString();
+ if (dispatchIdAndRating) {
+ [dispatchId, rating] = dispatchIdAndRating;
+
+ } else {
+ console.log('Invalid dispatch ID and Rating. returning...');
+ return;
+ }
+
let parentObjId = '';
if (payload.context.hasOwnProperty('parent_core_object_id')) {
parentObjId = payload.context.parent_core_object_id;
@@ -47,7 +57,7 @@ async function ProcessSurveyResponse(event: any) {
console.log(`SurveyId: [${surveyId}]`);
// STEP-1 Submit survey for database storage.
- const postBodyForSurveyResp = getSurveyResponseBody(surveyId, parentObjId, rating, sourceChannel);
+ const postBodyForSurveyResp = getSurveyResponseBody(surveyId, parentObjId, rating, dispatchId, sourceChannel);
try {
console.log('Posting survey response chosen by user to database.');
const resp = await doDevRevPostAPICall(apiBase, SurveysSubmitAPIMethodPath, postBodyForSurveyResp, actorAuth);
@@ -138,7 +148,6 @@ async function ProcessSurveyResponse(event: any) {
}
// STEP-4 Add response score provide by user on timeline for Devs.
- // const donv1RevUser = await donv2ActorToDonv1Actor(apiBase, auth, actorId);
console.log(`Annotating Rev-User : [${actorId}] `);
let bodyMsgDev = `\<${actorId}\> CSAT rating: ${rating}.`;
let postBodyDev = getTimelineCommentBody(parentObjId, bodyMsgDev, INTERNAL, null, commentExpireAt, null);
@@ -164,8 +173,8 @@ function getDeleteTimelineEntryBody(entryId: string) {
};
}
-function getSurveyResponseBody(surveyId: string, objId: string, rating: number, sourceChannel: string) {
- console.log(`SurveyId: [${surveyId}], ObjectId: [${objId}], Rating: [${rating}]`);
+function getSurveyResponseBody(surveyId: string, objId: string, rating: number, dispatchId: string, sourceChannel: string) {
+ console.log(`SurveyId: [${surveyId}], ObjectId: [${objId}], Rating: [${rating}], DispatchId: [${dispatchId}]`);
let respBody: { [key: string]: any } = {};
@@ -175,11 +184,25 @@ function getSurveyResponseBody(surveyId: string, objId: string, rating: number,
'rating': rating,
};
respBody.response_score = rating;
+ respBody.dispatch_id = dispatchId;
respBody.source_channel = sourceChannel;
return respBody;
}
+function splitDispatchIdAndRating(input: string): [string, number] | null {
+ const tokens = input.split(dispatchIdAndRatingDeliminator);
+ //case when only rating is present (for backward compatibility)
+ if (tokens.length === 1) {
+ return ['', parseInt(tokens[0])];
+ }
+ //case when dispatch id and rating is present
+ if (tokens.length === 2) {
+ return [tokens[0], parseInt(tokens[1])];
+ }
+ return null;
+}
+
function getSourceChannel(payload: any) {
let sourceChannel = EMAIL;
if (payload.context.hasOwnProperty('parent_core_object_id')) {