-
Notifications
You must be signed in to change notification settings - Fork 36
/
TransactionalEmail.js
253 lines (239 loc) · 9.55 KB
/
TransactionalEmail.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
'use strict';
import TransactionalMessage from './TransactionalMessage.js';
import Journey from './Journey.js';
import { Util } from '../util/util.js';
import cache from '../util/cache.js';
/**
* @typedef {import('../../types/mcdev.d.js').BuObject} BuObject
* @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract
* @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj
* @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap
* @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj
* @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams
* @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap
*/
/**
* TransactionalEmail MetadataType
*
* @augments TransactionalMessage
*/
class TransactionalEmail extends TransactionalMessage {
static subType = 'email';
/** @type {Array} */
static _createdJourneyKeys;
/**
* Updates a single item
*
* @param {MetadataTypeItem} metadata how the item shall look after the update
* @returns {Promise} Promise
*/
static update(metadata) {
if (metadata.options?.createJourney) {
// only send this during create or else we might end up with an unexpected outcome
Util.logger.warn(
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
metadata[this.definition.keyField]
}): Cannot update journey link during update. If you need to relink this item to a new journey please delete and recreate it.`
);
delete metadata.options.createJourney;
}
return super.update(metadata);
}
/**
* prepares for deployment
*
* @param {MetadataTypeItem} metadata a single item
* @returns {Promise.<MetadataTypeItem>} -
*/
static async preDeployTasks(metadata) {
// asset
if (metadata.r__asset_key) {
// we merely want to be able to show an error if it does not exist
metadata.content = {
customerKey: cache.searchForField(
'asset',
metadata.r__asset_key,
'customerKey',
'customerKey'
),
};
delete metadata.r__asset_key;
}
// subscriptions: dataExtension
if (metadata.subscriptions?.r__dataExtension_key) {
// we merely want to be able to show an error if it does not exist
metadata.subscriptions.dataExtension = cache.searchForField(
'dataExtension',
metadata.subscriptions.r__dataExtension_key,
'CustomerKey',
'CustomerKey'
);
}
// subscriptions: list
if (metadata.subscriptions?.r__list_PathName) {
metadata.subscriptions.list = cache.getListObjectId(
metadata.subscriptions.r__list_PathName,
'CustomerKey'
);
delete metadata.subscriptions.r__list_PathName;
}
// journey
// ! update & create enpoints dont accept journey.interactionKey. They only allow to create a new journey
metadata.options ||= {};
metadata.options.createJourney = true; // only send this during create or else we might end up with an unexpected outcome
return metadata;
}
/**
* helper for {@link TransactionalEmail.createREST}
*
* @param {MetadataTypeItem} _ not used
* @param {object} apiResponse varies depending on the API call
* @returns {Promise.<void>} -
*/
static async postCreateTasks(_, apiResponse) {
if (apiResponse.journey?.interactionKey) {
Util.logger.warn(
` - created journey: ${apiResponse.journey.interactionKey} (auto-created when ${this.definition.type} ${apiResponse.definitionKey} was created)`
);
// when we create new transactionalEmails, we should also download the new journey that was created with it
this._createdJourneyKeys ||= [];
this._createdJourneyKeys.push(apiResponse.journey?.interactionKey);
// do what postRetrieveTasks won't be able to do without spending lots of time on caching
apiResponse.r__journey_key = apiResponse.journey.interactionKey;
delete apiResponse.journey;
}
}
/**
* Gets executed after deployment of metadata type
*
* @returns {void}
*/
static postDeployTasks() {
if (this._createdJourneyKeys?.length) {
Util.logger.warn(
`Please download related journeys via: mcdev r ${this.buObject.credential}/${
this.buObject.businessUnit
} journey "${this._createdJourneyKeys.join(',')}"`
);
}
delete this._createdJourneyKeys;
}
/**
* manages post retrieve steps
*
* @param {MetadataTypeItem} metadata a single item
* @returns {MetadataTypeItem} a single item
*/
static postRetrieveTasks(metadata) {
// asset
if (metadata.content?.customerKey) {
metadata.r__asset_key = metadata.content.customerKey;
try {
// we merely want to be able to show an error if it does not exist
cache.searchForField(
'asset',
metadata.content.customerKey,
'customerKey',
'customerKey'
);
} catch (ex) {
Util.logger.warn(
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
metadata[this.definition.keyField]
}): ${ex.message}.`
);
}
delete metadata.content;
}
// subscriptions: dataExtension
if (metadata.subscriptions?.dataExtension) {
metadata.subscriptions.r__dataExtension_key = metadata.subscriptions.dataExtension;
try {
// we merely want to be able to show a warning if it does not exist
cache.searchForField(
'dataExtension',
metadata.subscriptions.dataExtension,
'CustomerKey',
'CustomerKey'
);
} catch (ex) {
Util.logger.warn(
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
metadata[this.definition.keyField]
}): ${ex.message}.`
);
}
delete metadata.subscriptions.dataExtension;
}
// subscriptions: list
if (metadata.subscriptions?.list) {
try {
// List
metadata.subscriptions.r__list_PathName = cache.getListPathName(
metadata.subscriptions.list,
'CustomerKey'
);
delete metadata.subscriptions.list;
} catch (ex) {
Util.logger.warn(
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
metadata[this.definition.keyField]
}): ${ex.message}.`
);
}
}
// journey
if (metadata.journey?.interactionKey) {
metadata.r__journey_key = metadata.journey.interactionKey;
try {
// we merely want to be able to show a warning if it does not exist
metadata.r__journey_key = cache.searchForField(
'journey',
metadata.journey.interactionKey,
'key',
'key'
);
} catch (ex) {
Util.logger.warn(
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
metadata[this.definition.keyField]
}): ${ex.message}.`
);
}
delete metadata.journey;
}
return metadata;
}
/**
* Delete a metadata item from the specified business unit
*
* @param {string} key Identifier of item
* @returns {Promise.<boolean>} deletion success status
*/
static async deleteByKey(key) {
const metadataMapObj = await this.retrieveForCache(null, null, key);
const journeyKey = metadataMapObj?.metadata?.[key]?.journey?.interactionKey;
const isDeleted = await super.deleteByKeyREST(
'/messaging/v1/' + this.subType + '/definitions/' + key,
key,
false
);
if (isDeleted && journeyKey) {
Util.logger.info(
` - deleted ${Journey.definition.type}: ${journeyKey} (SFMC auto-deletes the related journey of ${this.definition.type} ${key})`
);
Journey.buObject = this.buObject;
Journey.properties = this.properties;
Journey.client = this.client;
Journey.postDeleteTasks(journeyKey);
}
return isDeleted;
}
}
// Assign definition to static attributes
import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
TransactionalEmail.definition = MetadataTypeDefinitions.transactionalEmail;
export default TransactionalEmail;