@segment/action-destinations 3.259.0-staging-3c51bd971 → 3.259.0-staging-3faa5cf21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/destinations/amazon-ads/index.js +3 -1
  2. package/dist/destinations/amazon-ads/index.js.map +1 -1
  3. package/dist/destinations/customerio/utils.d.ts +1 -1
  4. package/dist/destinations/engage/sendgrid/Profile.d.ts +6 -0
  5. package/dist/destinations/{engage-messaging-twilio/sendWhatsApp/generated-types.js → engage/sendgrid/Profile.js} +1 -1
  6. package/dist/destinations/engage/sendgrid/Profile.js.map +1 -0
  7. package/dist/destinations/engage/sendgrid/previewApiLookup/api-lookups.d.ts +21 -0
  8. package/dist/destinations/engage/sendgrid/previewApiLookup/api-lookups.js +174 -0
  9. package/dist/destinations/engage/sendgrid/previewApiLookup/api-lookups.js.map +1 -0
  10. package/dist/destinations/engage/utils/track.d.ts +9 -9
  11. package/dist/destinations/marketo-static-lists/addToList/index.js +4 -2
  12. package/dist/destinations/marketo-static-lists/addToList/index.js.map +1 -1
  13. package/dist/destinations/responsys/asyncMergePetRecords/generated-types.d.ts +14 -0
  14. package/dist/destinations/responsys/asyncMergePetRecords/generated-types.js.map +1 -0
  15. package/dist/destinations/responsys/asyncMergePetRecords/index.js +113 -0
  16. package/dist/destinations/responsys/asyncMergePetRecords/index.js.map +1 -0
  17. package/dist/destinations/responsys/asyncMergeProfileListMembers/generated-types.d.ts +20 -0
  18. package/dist/destinations/responsys/asyncMergeProfileListMembers/generated-types.js.map +1 -0
  19. package/dist/destinations/{engage-messaging-twilio/sendSms → responsys/asyncMergeProfileListMembers}/index.d.ts +1 -1
  20. package/dist/destinations/responsys/asyncMergeProfileListMembers/index.js +174 -0
  21. package/dist/destinations/responsys/asyncMergeProfileListMembers/index.js.map +1 -0
  22. package/dist/destinations/responsys/rsp-operations.d.ts +14 -0
  23. package/dist/destinations/responsys/rsp-operations.js +33 -0
  24. package/dist/destinations/responsys/rsp-operations.js.map +1 -0
  25. package/dist/destinations/responsys/rsp-properties.d.ts +4 -0
  26. package/dist/destinations/responsys/rsp-properties.js +27 -0
  27. package/dist/destinations/responsys/rsp-properties.js.map +1 -0
  28. package/dist/destinations/snap-conversions-api/_tests_/capiV2tests.d.ts +1 -0
  29. package/dist/destinations/snap-conversions-api/_tests_/capiV2tests.js +381 -0
  30. package/dist/destinations/snap-conversions-api/_tests_/capiV2tests.js.map +1 -0
  31. package/dist/destinations/snap-conversions-api/_tests_/capiV3tests.d.ts +1 -0
  32. package/dist/destinations/snap-conversions-api/_tests_/capiV3tests.js +581 -0
  33. package/dist/destinations/snap-conversions-api/_tests_/capiV3tests.js.map +1 -0
  34. package/dist/destinations/snap-conversions-api/reportConversionEvent/snap-capi-v2.d.ts +4 -0
  35. package/dist/destinations/snap-conversions-api/reportConversionEvent/snap-capi-v2.js +97 -0
  36. package/dist/destinations/snap-conversions-api/reportConversionEvent/snap-capi-v2.js.map +1 -0
  37. package/dist/destinations/tiktok-offline-conversions/reportOfflineEvent/formatter.d.ts +3 -0
  38. package/dist/destinations/tiktok-offline-conversions/reportOfflineEvent/formatter.js +43 -0
  39. package/dist/destinations/tiktok-offline-conversions/reportOfflineEvent/formatter.js.map +1 -0
  40. package/package.json +2 -2
  41. package/dist/destinations/engage-messaging-sendgrid/sendEmail/generated-types.d.ts +0 -36
  42. package/dist/destinations/engage-messaging-sendgrid/sendEmail/generated-types.js.map +0 -1
  43. package/dist/destinations/engage-messaging-sendgrid/sendEmail/index.js +0 -452
  44. package/dist/destinations/engage-messaging-sendgrid/sendEmail/index.js.map +0 -1
  45. package/dist/destinations/engage-messaging-twilio/sendSms/generated-types.d.ts +0 -22
  46. package/dist/destinations/engage-messaging-twilio/sendSms/generated-types.js.map +0 -1
  47. package/dist/destinations/engage-messaging-twilio/sendSms/index.js +0 -131
  48. package/dist/destinations/engage-messaging-twilio/sendSms/index.js.map +0 -1
  49. package/dist/destinations/engage-messaging-twilio/sendSms/sms-sender.d.ts +0 -23
  50. package/dist/destinations/engage-messaging-twilio/sendSms/sms-sender.js +0 -131
  51. package/dist/destinations/engage-messaging-twilio/sendSms/sms-sender.js.map +0 -1
  52. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/generated-types.d.ts +0 -24
  53. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/generated-types.js.map +0 -1
  54. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/index.d.ts +0 -5
  55. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/index.js +0 -133
  56. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/index.js.map +0 -1
  57. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/whatsapp-sender.d.ts +0 -21
  58. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/whatsapp-sender.js +0 -75
  59. package/dist/destinations/engage-messaging-twilio/sendWhatsApp/whatsapp-sender.js.map +0 -1
  60. package/dist/destinations/engage-messaging-twilio/utils/message-sender.d.ts +0 -24
  61. package/dist/destinations/engage-messaging-twilio/utils/message-sender.js +0 -111
  62. package/dist/destinations/engage-messaging-twilio/utils/message-sender.js.map +0 -1
  63. package/dist/destinations/hubspot/helperFunctions.d.ts +0 -7
  64. package/dist/destinations/hubspot/helperFunctions.js +0 -27
  65. package/dist/destinations/hubspot/helperFunctions.js.map +0 -1
  66. package/dist/destinations/vernst-test/generated-types.d.ts +0 -2
  67. package/dist/destinations/vernst-test/generated-types.js +0 -3
  68. package/dist/destinations/vernst-test/generated-types.js.map +0 -1
  69. package/dist/destinations/vernst-test/index.d.ts +0 -4
  70. package/dist/destinations/vernst-test/index.js +0 -20
  71. package/dist/destinations/vernst-test/index.js.map +0 -1
  72. package/dist/destinations/vernst-test/pingWebhook/generated-types.d.ts +0 -3
  73. package/dist/destinations/vernst-test/pingWebhook/generated-types.js +0 -3
  74. package/dist/destinations/vernst-test/pingWebhook/generated-types.js.map +0 -1
  75. package/dist/destinations/vernst-test/pingWebhook/index.d.ts +0 -5
  76. package/dist/destinations/vernst-test/pingWebhook/index.js +0 -21
  77. package/dist/destinations/vernst-test/pingWebhook/index.js.map +0 -1
  78. /package/dist/destinations/{engage-messaging-sendgrid/sendEmail → responsys/asyncMergePetRecords}/generated-types.js +0 -0
  79. /package/dist/destinations/{engage-messaging-sendgrid/sendEmail → responsys/asyncMergePetRecords}/index.d.ts +0 -0
  80. /package/dist/destinations/{engage-messaging-twilio/sendSms → responsys/asyncMergeProfileListMembers}/generated-types.js +0 -0
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.performSnapCAPIv2 = void 0;
4
+ const actions_core_1 = require("@segment/actions-core");
5
+ const snap_capi_properties_1 = require("../snap-capi-properties");
6
+ const utils_1 = require("./utils");
7
+ const conversionType = (oldSettings, event_conversion_type) => {
8
+ const settings = { ...oldSettings };
9
+ if (event_conversion_type === 'MOBILE_APP') {
10
+ if (!settings?.snap_app_id || !settings?.app_id) {
11
+ throw new actions_core_1.IntegrationError('If event conversion type is "MOBILE_APP" then Snap App ID and App ID must be defined', 'Misconfigured required field', 400);
12
+ }
13
+ delete settings?.pixel_id;
14
+ }
15
+ else {
16
+ if (!settings?.pixel_id) {
17
+ throw new actions_core_1.IntegrationError(`If event conversion type is "${event_conversion_type}" then Pixel ID must be defined`, 'Misconfigured required field', 400);
18
+ }
19
+ delete settings?.snap_app_id;
20
+ delete settings?.app_id;
21
+ }
22
+ return settings;
23
+ };
24
+ const formatPayload = (oldPayload) => {
25
+ const payload = { ...oldPayload };
26
+ if (payload.email) {
27
+ payload.email = payload.email.replace(/\s/g, '').toLowerCase();
28
+ }
29
+ if (payload.phone_number) {
30
+ payload.phone_number = payload.phone_number.replace(/\D|^0+/g, '');
31
+ }
32
+ if (payload.mobile_ad_id) {
33
+ payload.mobile_ad_id = payload.mobile_ad_id.toLowerCase();
34
+ }
35
+ let item_ids = undefined;
36
+ let item_category = undefined;
37
+ let brands = undefined;
38
+ const p = payload?.products;
39
+ if (p && Array.isArray(p) && p.length > 0) {
40
+ item_ids = utils_1.transformProperty('item_id', p);
41
+ item_category = utils_1.transformProperty('item_category', p);
42
+ brands = p.map((product) => product.brand ?? '');
43
+ }
44
+ return {
45
+ event_type: payload?.event_type,
46
+ event_conversion_type: payload?.event_conversion_type,
47
+ event_tag: payload?.event_tag,
48
+ timestamp: Date.parse(payload?.timestamp),
49
+ hashed_email: utils_1.isHashedEmail(String(payload?.email)) ? payload?.email : utils_1.hash(payload?.email),
50
+ hashed_mobile_ad_id: utils_1.hash(payload?.mobile_ad_id),
51
+ uuid_c1: payload?.uuid_c1,
52
+ hashed_idfv: utils_1.hash(payload?.idfv),
53
+ hashed_phone_number: utils_1.hash(payload?.phone_number),
54
+ user_agent: payload?.user_agent,
55
+ hashed_ip_address: utils_1.hash(payload?.ip_address),
56
+ item_category: item_category ?? payload?.item_category,
57
+ brands: brands ?? payload?.brands,
58
+ item_ids: item_ids ?? payload?.item_ids,
59
+ description: payload?.description,
60
+ number_items: payload?.number_items,
61
+ price: payload?.price,
62
+ currency: payload?.currency,
63
+ transaction_id: payload?.transaction_id,
64
+ level: payload?.level,
65
+ client_dedup_id: payload?.client_dedup_id,
66
+ search_string: payload?.search_string,
67
+ page_url: payload?.page_url,
68
+ sign_up_method: payload?.sign_up_method,
69
+ device_model: payload?.device_model,
70
+ os_version: payload?.os_version,
71
+ click_id: payload?.click_id
72
+ };
73
+ };
74
+ const CONVERSION_EVENT_URL = 'https://tr.snapchat.com/v2/conversion';
75
+ const performSnapCAPIv2 = (request, data) => {
76
+ if (data.payload.currency && !snap_capi_properties_1.CURRENCY_ISO_4217_CODES.has(data.payload.currency.toUpperCase())) {
77
+ throw new actions_core_1.IntegrationError(`${data.payload.currency} is not a valid currency code.`, 'Misconfigured required field', 400);
78
+ }
79
+ if (!data.payload.email &&
80
+ !data.payload.phone_number &&
81
+ !data.payload.mobile_ad_id &&
82
+ (!data.payload.ip_address || !data.payload.user_agent)) {
83
+ throw new actions_core_1.IntegrationError(`Payload must contain values for Email or Phone Number or Mobile Ad Identifier or both IP Address and User Agent fields`, 'Misconfigured required field', 400);
84
+ }
85
+ const payload = formatPayload(data.payload);
86
+ const settings = conversionType(data.settings, data.payload.event_conversion_type);
87
+ return request(CONVERSION_EVENT_URL, {
88
+ method: 'post',
89
+ json: {
90
+ integration: 'segment',
91
+ ...payload,
92
+ ...settings
93
+ }
94
+ });
95
+ };
96
+ exports.performSnapCAPIv2 = performSnapCAPIv2;
97
+ //# sourceMappingURL=snap-capi-v2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snap-capi-v2.js","sourceRoot":"","sources":["../../../../src/destinations/snap-conversions-api/reportConversionEvent/snap-capi-v2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const formatEmails: (email_addresses: string[] | undefined) => string[];
2
+ export declare function formatUserIds(userIds: string[] | undefined): string[];
3
+ export declare const formatPhones: (phone_numbers: string[] | undefined) => string[];
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatPhones = exports.formatUserIds = exports.formatEmails = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const formatEmails = (email_addresses) => {
6
+ const result = [];
7
+ if (email_addresses) {
8
+ email_addresses.forEach((email) => {
9
+ result.push(hashAndEncode(email.toLowerCase()));
10
+ });
11
+ }
12
+ return result;
13
+ };
14
+ exports.formatEmails = formatEmails;
15
+ function formatUserIds(userIds) {
16
+ const result = [];
17
+ if (userIds) {
18
+ userIds.forEach((userId) => {
19
+ result.push(hashAndEncode(userId.toLowerCase()));
20
+ });
21
+ }
22
+ return result;
23
+ }
24
+ exports.formatUserIds = formatUserIds;
25
+ const formatPhones = (phone_numbers) => {
26
+ const result = [];
27
+ if (!phone_numbers)
28
+ return result;
29
+ phone_numbers.forEach((phone) => {
30
+ const validatedPhone = phone.match(/[0-9]{0,14}/g);
31
+ if (validatedPhone === null) {
32
+ throw new Error(`${phone} is not a valid E.164 phone number.`);
33
+ }
34
+ const formattedPhone = `+${phone.replace(/[^0-9]/g, '')}`;
35
+ result.push(hashAndEncode(formattedPhone.substring(0, 15)));
36
+ });
37
+ return result;
38
+ };
39
+ exports.formatPhones = formatPhones;
40
+ function hashAndEncode(property) {
41
+ return crypto_1.createHash('sha256').update(property).digest('hex');
42
+ }
43
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../../../src/destinations/tiktok-offline-conversions/reportOfflineEvent/formatter.ts"],"names":[],"mappings":";;;AAAA,mCAAmC;AAK5B,MAAM,YAAY,GAAG,CAAC,eAAqC,EAAY,EAAE;IAC9E,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,eAAe,EAAE;QACnB,eAAe,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE;YACxC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;QACjD,CAAC,CAAC,CAAA;KACH;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AARY,QAAA,YAAY,gBAQxB;AAOD,SAAgB,aAAa,CAAC,OAA6B;IACzD,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,OAAO,EAAE;QACX,OAAO,CAAC,OAAO,CAAC,CAAC,MAAc,EAAE,EAAE;YACjC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;KACH;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AARD,sCAQC;AAOM,MAAM,YAAY,GAAG,CAAC,aAAmC,EAAY,EAAE;IAC5E,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,CAAC,aAAa;QAAE,OAAO,MAAM,CAAA;IAEjC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE;QACtC,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;QAClD,IAAI,cAAc,KAAK,IAAI,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qCAAqC,CAAC,CAAA;SAC/D;QAED,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAA;QAEzD,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAhBY,QAAA,YAAY,gBAgBxB;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,mBAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC5D,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@segment/action-destinations",
3
3
  "description": "Destination Actions engine and definitions.",
4
- "version": "3.259.0-staging-3c51bd971",
4
+ "version": "3.259.0-staging-3faa5cf21",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/segmentio/action-destinations",
@@ -43,7 +43,7 @@
43
43
  "@bufbuild/protobuf": "^1.4.2",
44
44
  "@bufbuild/protoc-gen-es": "^1.4.2",
45
45
  "@segment/a1-notation": "^2.1.4",
46
- "@segment/actions-core": "3.106.0-staging-3c51bd971",
46
+ "@segment/actions-core": "3.106.0-staging-5f3508561",
47
47
  "@segment/actions-shared": "^1.87.0",
48
48
  "@types/node": "^18.11.15",
49
49
  "ajv-formats": "^2.1.1",
@@ -1,36 +0,0 @@
1
- export interface Payload {
2
- send?: boolean;
3
- traitEnrichment?: boolean;
4
- userId?: string;
5
- toEmail?: string;
6
- fromDomain?: string | null;
7
- fromEmail: string;
8
- fromName: string;
9
- replyToEqualsFrom?: boolean;
10
- replyToEmail: string;
11
- replyToName: string;
12
- bcc: string;
13
- previewText?: string;
14
- subject: string;
15
- body?: string;
16
- bodyUrl?: string;
17
- bodyType: string;
18
- bodyHtml?: string;
19
- groupId?: string;
20
- externalIds?: {
21
- id?: string;
22
- type?: string;
23
- subscriptionStatus?: string;
24
- groups?: {
25
- id?: string;
26
- isSubscribed?: boolean;
27
- }[];
28
- }[];
29
- customArgs?: {
30
- [k: string]: unknown;
31
- };
32
- traits?: {
33
- [k: string]: unknown;
34
- };
35
- eventOccurredTS?: string;
36
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"generated-types.js","sourceRoot":"","sources":["../../../../src/destinations/engage-messaging-sendgrid/sendEmail/generated-types.ts"],"names":[],"mappings":""}
@@ -1,452 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const actions_core_1 = require("@segment/actions-core");
7
- const liquidjs_1 = require("liquidjs");
8
- const cheerio_1 = __importDefault(require("cheerio"));
9
- const escape_goat_1 = require("escape-goat");
10
- const Liquid = new liquidjs_1.Liquid();
11
- const insertEmailPreviewText = (html, previewText) => {
12
- const $ = cheerio_1.default.load(html);
13
- $('body').prepend(`
14
- <div style='display: none; max-height: 0px; overflow: hidden;'>
15
- ${escape_goat_1.htmlEscape(previewText)}
16
- </div>
17
-
18
- <div style='display: none; max-height: 0px; overflow: hidden;'>
19
- ${'&nbsp;&zwnj;'.repeat(13)}&nbsp;
20
- </div>
21
- `);
22
- return $.html();
23
- };
24
- const getProfileApiEndpoint = (environment, region) => {
25
- const domainName = region === 'eu-west-1' ? 'profiles.euw1.segment' : 'profiles.segment';
26
- const topLevelName = environment === 'production' ? 'com' : 'build';
27
- return `https://${domainName}.${topLevelName}`;
28
- };
29
- const fetchProfileTraits = async (request, settings, profileId, statsClient, tags, logger) => {
30
- try {
31
- const endpoint = getProfileApiEndpoint(settings.profileApiEnvironment, settings.region);
32
- const response = await request(`${endpoint}/v1/spaces/${settings.spaceId}/collections/users/profiles/user_id:${profileId}/traits?limit=200`, {
33
- headers: {
34
- authorization: `Basic ${Buffer.from(settings.profileApiAccessToken + ':').toString('base64')}`,
35
- 'content-type': 'application/json'
36
- }
37
- });
38
- tags.push(`profile_status_code:${response.status}`);
39
- statsClient?.incr('actions-personas-messaging-sendgrid.profile_invoked', 1, tags);
40
- const body = await response.json();
41
- return body.traits;
42
- }
43
- catch (error) {
44
- logger?.error(`TE Messaging: Email profile traits request failure - ${settings.spaceId} - [${error}]`);
45
- tags.push('reason:profile_error');
46
- statsClient?.incr('actions-personas-messaging-sendgrid.error', 1, tags);
47
- throw new actions_core_1.IntegrationError('Unable to get profile traits for the email message', 'Email trait fetch failure', 500);
48
- }
49
- };
50
- const isRestrictedDomain = (email) => {
51
- const restricted = ['gmailx.com', 'yahoox.com', 'aolx.com', 'hotmailx.com'];
52
- const matches = /^.+@(.+)$/.exec(email.toLowerCase());
53
- if (!matches) {
54
- return false;
55
- }
56
- const domain = matches[1];
57
- return restricted.includes(domain);
58
- };
59
- const generateEmailHtml = async (request, settings, design, statsClient, tags, logger) => {
60
- try {
61
- statsClient?.incr('actions-personas-messaging-sendgrid.unlayer_request', 1, tags);
62
- const response = await request('https://api.unlayer.com/v2/export/html', {
63
- method: 'POST',
64
- headers: {
65
- authorization: `Basic ${Buffer.from(`${settings.unlayerApiKey}:`).toString('base64')}`,
66
- 'content-type': 'application/json'
67
- },
68
- body: JSON.stringify({
69
- displayMode: 'email',
70
- design: JSON.parse(design)
71
- })
72
- });
73
- const body = await response.json();
74
- return body.data.html;
75
- }
76
- catch (error) {
77
- logger?.error(`TE Messaging: Email export request failure - ${settings.spaceId} - [${error}]`);
78
- tags.push('reason:generate_email_html');
79
- statsClient?.incr('actions-personas-messaging-sendgrid.error', 1, tags);
80
- throw new actions_core_1.IntegrationError('Unable to export email as HTML', 'Export HTML failure', 400);
81
- }
82
- };
83
- const parseTemplating = async (content, profile, contentType, statsClient, tags, settings, logger) => {
84
- try {
85
- const parsedContent = await Liquid.parseAndRender(content, { profile });
86
- return parsedContent;
87
- }
88
- catch (error) {
89
- logger?.error(`TE Messaging: Email templating parse failure - ${settings.spaceId} - [${error}]`);
90
- tags.push('reason:parse_templating');
91
- statsClient?.incr('actions-personas-messaging-sendgrid.error', 1, tags);
92
- throw new actions_core_1.IntegrationError(`Unable to parse templating in email ${contentType}`, `${contentType} templating parse failure`, 400);
93
- }
94
- };
95
- const EXTERNAL_ID_KEY = 'email';
96
- const action = {
97
- title: 'Send Email',
98
- description: 'Sends Email to a user powered by SendGrid',
99
- defaultSubscription: 'type = "track" and event = "Audience Entered"',
100
- fields: {
101
- send: {
102
- label: 'Send Message',
103
- description: 'Whether or not the message should actually get sent.',
104
- type: 'boolean',
105
- required: false,
106
- default: false
107
- },
108
- traitEnrichment: {
109
- label: 'Trait Enrich',
110
- description: 'Whether or not trait enrich from event (i.e without profile api call)',
111
- type: 'boolean',
112
- required: false,
113
- default: true
114
- },
115
- userId: {
116
- label: 'User ID',
117
- description: 'User ID in Segment',
118
- type: 'string',
119
- required: false,
120
- default: { '@path': '$.userId' }
121
- },
122
- toEmail: {
123
- label: 'Test Email',
124
- description: 'Email to send to when testing',
125
- type: 'string'
126
- },
127
- fromDomain: {
128
- label: 'From Domain',
129
- description: 'Verified domain in Sendgrid',
130
- type: 'string',
131
- allowNull: true
132
- },
133
- fromEmail: {
134
- label: 'From Email',
135
- description: 'From Email',
136
- type: 'string',
137
- required: true
138
- },
139
- fromName: {
140
- label: 'From Name',
141
- description: 'From Name displayed to end user email',
142
- type: 'string',
143
- required: true
144
- },
145
- replyToEqualsFrom: {
146
- label: 'Reply To Equals From',
147
- description: 'Whether "reply to" settings are the same as "from"',
148
- type: 'boolean'
149
- },
150
- replyToEmail: {
151
- label: 'Reply To Email',
152
- description: 'The Email used by user to Reply To',
153
- type: 'string',
154
- required: true
155
- },
156
- replyToName: {
157
- label: 'Reply To Name',
158
- description: 'The Name used by user to Reply To',
159
- type: 'string',
160
- required: true
161
- },
162
- bcc: {
163
- label: 'BCC',
164
- description: 'BCC list of emails',
165
- type: 'string',
166
- required: true
167
- },
168
- previewText: {
169
- label: 'Preview Text',
170
- description: 'Preview Text',
171
- type: 'string'
172
- },
173
- subject: {
174
- label: 'Subject',
175
- description: 'Subject for the email to be sent',
176
- type: 'string',
177
- required: true
178
- },
179
- body: {
180
- label: 'Body',
181
- description: 'The message body',
182
- type: 'text'
183
- },
184
- bodyUrl: {
185
- label: 'Body URL',
186
- description: 'URL to the message body',
187
- type: 'text'
188
- },
189
- bodyType: {
190
- label: 'Body Type',
191
- description: 'The type of body which is used generally html | design',
192
- type: 'string',
193
- required: true
194
- },
195
- bodyHtml: {
196
- label: 'Body Html',
197
- description: 'The HTML content of the body',
198
- type: 'string'
199
- },
200
- groupId: {
201
- label: 'Group ID',
202
- description: 'Subscription group ID',
203
- type: 'string'
204
- },
205
- externalIds: {
206
- label: 'External IDs',
207
- description: 'An array of user profile identity information.',
208
- type: 'object',
209
- multiple: true,
210
- properties: {
211
- id: {
212
- label: 'ID',
213
- description: 'A unique identifier for the collection.',
214
- type: 'string'
215
- },
216
- type: {
217
- label: 'type',
218
- description: 'The external ID contact type.',
219
- type: 'string'
220
- },
221
- subscriptionStatus: {
222
- label: 'ID',
223
- description: 'The subscription status for the identity.',
224
- type: 'string'
225
- },
226
- groups: {
227
- label: 'Subscription Groups',
228
- description: 'Subscription groups and their statuses for this id.',
229
- type: 'object',
230
- multiple: true,
231
- properties: {
232
- id: {
233
- label: 'Subscription group id',
234
- type: 'string'
235
- },
236
- isSubscribed: {
237
- label: 'status',
238
- description: 'Group subscription status true is subscribed, false is unsubscribed or did-not-subscribe',
239
- type: 'boolean'
240
- }
241
- }
242
- }
243
- },
244
- default: {
245
- '@arrayPath': [
246
- '$.external_ids',
247
- {
248
- id: {
249
- '@path': '$.id'
250
- },
251
- type: {
252
- '@path': '$.type'
253
- },
254
- subscriptionStatus: {
255
- '@path': '$.isSubscribed'
256
- },
257
- groups: {
258
- '@path': '$.groups'
259
- }
260
- }
261
- ]
262
- }
263
- },
264
- customArgs: {
265
- label: 'Custom Args',
266
- description: 'Additional custom args that we be passed back opaquely on webhook events',
267
- type: 'object',
268
- required: false
269
- },
270
- traits: {
271
- label: 'Traits',
272
- description: "A user profile's traits",
273
- type: 'object',
274
- required: false,
275
- default: { '@path': '$.properties' }
276
- },
277
- eventOccurredTS: {
278
- label: 'Event Timestamp',
279
- description: 'Time of when the actual event happened.',
280
- type: 'string',
281
- required: false,
282
- default: {
283
- '@path': '$.timestamp'
284
- }
285
- }
286
- },
287
- perform: async (request, { settings, payload, statsContext, logger }) => {
288
- const statsClient = statsContext?.statsClient;
289
- const tags = statsContext?.tags ?? [];
290
- if (!settings.region) {
291
- settings.region = 'us-west-2';
292
- }
293
- tags.push(`space_id:${settings.spaceId}`, `projectid:${settings.sourceId}`, `region:${settings.region}`);
294
- if (!payload.send) {
295
- logger?.info(`TE Messaging: Email send disabled - ${settings.spaceId}`);
296
- statsClient?.incr('actions-personas-messaging-sendgrid.send-disabled', 1, tags);
297
- return;
298
- }
299
- const emailProfile = payload?.externalIds?.find((meta) => meta.type === 'email');
300
- if (!emailProfile?.subscriptionStatus ||
301
- ['unsubscribed', 'did not subscribed', 'false'].includes(emailProfile.subscriptionStatus)) {
302
- logger?.info(`TE Messaging: Email recipient not subscribed or external ids were omitted from request - ${settings.spaceId}`);
303
- statsClient?.incr('actions-personas-messaging-sendgrid.notsubscribed', 1, tags);
304
- return;
305
- }
306
- else if (['subscribed', 'true'].includes(emailProfile?.subscriptionStatus)) {
307
- statsClient?.incr('actions-personas-messaging-sendgrid.subscribed', 1, tags);
308
- if (payload.groupId && payload.groupId.length !== 0) {
309
- const group = (payload.externalIds ?? [])
310
- .flatMap((externalId) => externalId.groups)
311
- .find((group) => group?.id === payload.groupId);
312
- if (!group) {
313
- statsClient?.incr('actions-personas-messaging-sendgrid.group_notfound', 1, tags);
314
- return;
315
- }
316
- else if (!group.isSubscribed) {
317
- statsClient?.incr('actions-personas-messaging-sendgrid.group_notsubscribed', 1, tags);
318
- return;
319
- }
320
- statsClient?.incr('actions-personas-messaging-sendgrid.group_subscribed', 1, tags);
321
- }
322
- let traits;
323
- if (payload.traitEnrichment) {
324
- traits = payload?.traits ? payload?.traits : JSON.parse('{}');
325
- }
326
- else {
327
- if (!payload.userId) {
328
- logger?.error(`TE Messaging: Unable to process email, no userId provided and trait enrichment disabled - ${settings.spaceId}`);
329
- tags.push('reason:missing_user_id');
330
- statsClient?.incr('actions-personas-messaging-sendgrid.error', 1, tags);
331
- throw new actions_core_1.IntegrationError('Unable to process email, no userId provided and trait enrichment disabled', 'Invalid parameters', 400);
332
- }
333
- traits = await fetchProfileTraits(request, settings, payload.userId, statsClient, tags, logger);
334
- }
335
- const profile = {
336
- email: emailProfile.id,
337
- traits
338
- };
339
- const toEmail = payload.toEmail || profile.email;
340
- if (!toEmail) {
341
- return;
342
- }
343
- if (isRestrictedDomain(toEmail)) {
344
- logger?.error(`TE Messaging: Emails with gmailx.com, yahoox.com, aolx.com, and hotmailx.com domains are blocked - ${settings.spaceId}`);
345
- tags.push('reason:restricted_domain');
346
- statsClient?.incr('actions-personas-messaging-sendgrid.error', 1, tags);
347
- throw new actions_core_1.IntegrationError('Emails with gmailx.com, yahoox.com, aolx.com, and hotmailx.com domains are blocked.', 'Invalid input', 400);
348
- }
349
- let name;
350
- if (traits.first_name && traits.last_name) {
351
- name = `${traits.first_name} ${traits.last_name}`;
352
- }
353
- else if (traits.firstName && traits.lastName) {
354
- name = `${traits.firstName} ${traits.lastName}`;
355
- }
356
- else if (traits.name) {
357
- name = traits.name;
358
- }
359
- else {
360
- name = traits.first_name || traits.last_name || traits.firstName || traits.lastName || 'User';
361
- }
362
- const bcc = JSON.parse(payload.bcc ?? '[]');
363
- const parsedSubject = await parseTemplating(payload.subject, profile, 'Subject', statsClient, tags, settings, logger);
364
- let parsedBodyHtml;
365
- if (payload.bodyUrl && settings.unlayerApiKey) {
366
- const { content: body } = await request(payload.bodyUrl, { method: 'GET', skipResponseCloning: true });
367
- const bodyHtml = payload.bodyType === 'html'
368
- ? body
369
- : await generateEmailHtml(request, settings, body, statsClient, tags, logger);
370
- parsedBodyHtml = await parseTemplating(bodyHtml, profile, 'Body', statsClient, tags, settings, logger);
371
- }
372
- else {
373
- parsedBodyHtml = await parseTemplating(payload.bodyHtml ?? '', profile, 'Body HTML', statsClient, tags, settings, logger);
374
- }
375
- if (payload.bodyType === 'design' && payload.previewText) {
376
- const parsedPreviewText = await parseTemplating(payload.previewText, profile, 'Preview text', statsClient, tags, settings, logger);
377
- parsedBodyHtml = insertEmailPreviewText(parsedBodyHtml, parsedPreviewText);
378
- }
379
- try {
380
- statsClient?.incr('actions-personas-messaging-sendgrid.request', 1, tags);
381
- const req = {
382
- method: 'post',
383
- headers: {
384
- authorization: `Bearer ${settings.sendGridApiKey}`
385
- },
386
- json: {
387
- personalizations: [
388
- {
389
- to: [
390
- {
391
- email: toEmail,
392
- name: name
393
- }
394
- ],
395
- bcc: bcc.length > 0 ? bcc : undefined,
396
- custom_args: {
397
- ...payload.customArgs,
398
- source_id: settings.sourceId,
399
- space_id: settings.spaceId,
400
- user_id: payload.userId ?? undefined,
401
- __segment_internal_external_id_key__: EXTERNAL_ID_KEY,
402
- __segment_internal_external_id_value__: profile[EXTERNAL_ID_KEY]
403
- }
404
- }
405
- ],
406
- from: {
407
- email: payload.fromEmail,
408
- name: payload.fromName
409
- },
410
- reply_to: {
411
- email: payload.replyToEmail,
412
- name: payload.replyToName
413
- },
414
- subject: parsedSubject,
415
- content: [
416
- {
417
- type: 'text/html',
418
- value: parsedBodyHtml
419
- }
420
- ],
421
- tracking_settings: {
422
- subscription_tracking: {
423
- enable: true,
424
- substitution_tag: '[unsubscribe]'
425
- }
426
- }
427
- }
428
- };
429
- statsClient?.set('actions-personas-messaging-sendgrid.request_body_size', JSON.stringify(req).length, tags);
430
- const response = await request('https://api.sendgrid.com/v3/mail/send', req);
431
- tags.push(`sendgrid_status_code:${response.status}`);
432
- statsClient?.incr('actions-personas-messaging-sendgrid.response', 1, tags);
433
- if (payload?.eventOccurredTS != undefined) {
434
- statsClient?.histogram('actions-personas-messaging-sendgrid.eventDeliveryTS', Date.now() - new Date(payload?.eventOccurredTS).getTime(), tags);
435
- }
436
- return response;
437
- }
438
- catch (error) {
439
- logger?.error(`TE Messaging: Email message request failure - ${settings.spaceId} - [${error}]`);
440
- statsClient?.incr('actions-personas-messaging-sendgrid.request-failure', 1, tags);
441
- throw new actions_core_1.IntegrationError('Unable to send email message', 'SendGrid API request failure', 500);
442
- }
443
- }
444
- else {
445
- logger?.error(`TE Messaging: Email subscription status invalid "${emailProfile.subscriptionStatus}" - ${settings.spaceId}`);
446
- statsClient?.incr('actions-personas-messaging-sendgrid.sendgrid-error', 1, tags);
447
- throw new actions_core_1.IntegrationError(`Failed to process the subscription state: "${emailProfile.subscriptionStatus}"`, 'Invalid subscriptionStatus value', 400);
448
- }
449
- }
450
- };
451
- exports.default = action;
452
- //# sourceMappingURL=index.js.map