@iexec/web3mail 1.6.0-nightly-b2a0e93 → 1.7.0
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.
- package/dist/utils/subgraphQuery.js +1 -2
- package/dist/utils/subgraphQuery.js.map +1 -1
- package/dist/utils/validators.d.ts +35 -0
- package/dist/utils/validators.js +45 -1
- package/dist/utils/validators.js.map +1 -1
- package/dist/web3mail/IExecWeb3mail.d.ts +4 -2
- package/dist/web3mail/IExecWeb3mail.js +24 -1
- package/dist/web3mail/IExecWeb3mail.js.map +1 -1
- package/dist/web3mail/fetchMyContacts.js +2 -1
- package/dist/web3mail/fetchMyContacts.js.map +1 -1
- package/dist/web3mail/fetchUserContacts.js +1 -1
- package/dist/web3mail/fetchUserContacts.js.map +1 -1
- package/dist/web3mail/internalTypes.d.ts +4 -4
- package/dist/web3mail/prepareEmailCampaign.d.ts +4 -0
- package/dist/web3mail/prepareEmailCampaign.js +106 -0
- package/dist/web3mail/prepareEmailCampaign.js.map +1 -0
- package/dist/web3mail/sendEmail.d.ts +2 -2
- package/dist/web3mail/sendEmail.js +191 -135
- package/dist/web3mail/sendEmail.js.map +1 -1
- package/dist/web3mail/sendEmailCampaign.d.ts +4 -0
- package/dist/web3mail/sendEmailCampaign.js +43 -0
- package/dist/web3mail/sendEmailCampaign.js.map +1 -0
- package/dist/web3mail/types.d.ts +83 -24
- package/package.json +3 -4
- package/src/utils/subgraphQuery.ts +1 -2
- package/src/utils/validators.ts +68 -1
- package/src/web3mail/IExecWeb3mail.ts +38 -5
- package/src/web3mail/fetchMyContacts.ts +2 -1
- package/src/web3mail/fetchUserContacts.ts +7 -5
- package/src/web3mail/internalTypes.ts +5 -3
- package/src/web3mail/prepareEmailCampaign.ts +170 -0
- package/src/web3mail/sendEmail.ts +246 -150
- package/src/web3mail/sendEmailCampaign.ts +69 -0
- package/src/web3mail/types.ts +88 -26
package/src/utils/validators.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isAddress } from 'ethers';
|
|
2
2
|
import { IExec } from 'iexec';
|
|
3
|
-
import {
|
|
3
|
+
import { NULL_ADDRESS } from 'iexec/utils';
|
|
4
|
+
import { ValidationError, boolean, number, object, string } from 'yup';
|
|
4
5
|
|
|
5
6
|
export const isValidProvider = async (iexec: IExec) => {
|
|
6
7
|
const client = await iexec.config.resolveContractsClient();
|
|
@@ -61,3 +62,69 @@ export const positiveNumberSchema = () =>
|
|
|
61
62
|
|
|
62
63
|
export const booleanSchema = () =>
|
|
63
64
|
boolean().strict().typeError('${path} should be a boolean');
|
|
65
|
+
|
|
66
|
+
const isPositiveIntegerStringTest = (value: string) => /^\d+$/.test(value);
|
|
67
|
+
|
|
68
|
+
const stringSchema = () =>
|
|
69
|
+
string().strict().typeError('${path} should be a string');
|
|
70
|
+
|
|
71
|
+
const positiveIntegerStringSchema = () =>
|
|
72
|
+
string().test(
|
|
73
|
+
'is-positive-int',
|
|
74
|
+
'${path} should be a positive integer',
|
|
75
|
+
(value) => isUndefined(value) || isPositiveIntegerStringTest(value)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const positiveStrictIntegerStringSchema = () =>
|
|
79
|
+
string().test(
|
|
80
|
+
'is-positive-strict-int',
|
|
81
|
+
'${path} should be a strictly positive integer',
|
|
82
|
+
(value) =>
|
|
83
|
+
isUndefined(value) ||
|
|
84
|
+
(value !== '0' && isPositiveIntegerStringTest(value))
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
export const campaignRequestSchema = () =>
|
|
88
|
+
object({
|
|
89
|
+
app: addressSchema().required(),
|
|
90
|
+
appmaxprice: positiveIntegerStringSchema().required(),
|
|
91
|
+
workerpool: addressSchema().required(),
|
|
92
|
+
workerpoolmaxprice: positiveIntegerStringSchema().required(),
|
|
93
|
+
dataset: addressSchema().oneOf([NULL_ADDRESS]).required(),
|
|
94
|
+
datasetmaxprice: positiveIntegerStringSchema().oneOf(['0']).required(),
|
|
95
|
+
params: stringSchema()
|
|
96
|
+
.test(
|
|
97
|
+
'is-valid-bulk-params',
|
|
98
|
+
'${path} should be a valid JSON string with bulk_cid field',
|
|
99
|
+
(value) => {
|
|
100
|
+
try {
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
102
|
+
const { bulk_cid } = JSON.parse(value);
|
|
103
|
+
if (typeof bulk_cid === 'string') {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
} catch {}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
.required(),
|
|
111
|
+
requester: addressSchema().required(),
|
|
112
|
+
beneficiary: addressSchema().required(),
|
|
113
|
+
callback: addressSchema().required(),
|
|
114
|
+
category: positiveIntegerStringSchema().required(),
|
|
115
|
+
volume: positiveStrictIntegerStringSchema().required(),
|
|
116
|
+
tag: stringSchema().required(),
|
|
117
|
+
trust: positiveIntegerStringSchema().required(),
|
|
118
|
+
salt: stringSchema().required(),
|
|
119
|
+
sign: stringSchema().required(),
|
|
120
|
+
})
|
|
121
|
+
.strict()
|
|
122
|
+
.typeError('${path} should be a BulkRequest object')
|
|
123
|
+
.test('is-defined', '${path} is required', (value) => {
|
|
124
|
+
// Check if value is undefined, null, or an empty object (which would be coerced from undefined)
|
|
125
|
+
return (
|
|
126
|
+
value !== undefined &&
|
|
127
|
+
value !== null &&
|
|
128
|
+
!(typeof value === 'object' && Object.keys(value).length === 0)
|
|
129
|
+
);
|
|
130
|
+
});
|
|
@@ -5,6 +5,8 @@ import { GraphQLClient } from 'graphql-request';
|
|
|
5
5
|
import { fetchUserContacts } from './fetchUserContacts.js';
|
|
6
6
|
import { fetchMyContacts } from './fetchMyContacts.js';
|
|
7
7
|
import { sendEmail } from './sendEmail.js';
|
|
8
|
+
import { prepareEmailCampaign } from './prepareEmailCampaign.js';
|
|
9
|
+
import { sendEmailCampaign } from './sendEmailCampaign.js';
|
|
8
10
|
import {
|
|
9
11
|
Contact,
|
|
10
12
|
FetchUserContactsParams,
|
|
@@ -14,6 +16,10 @@ import {
|
|
|
14
16
|
SendEmailResponse,
|
|
15
17
|
Web3SignerProvider,
|
|
16
18
|
FetchMyContactsParams,
|
|
19
|
+
PrepareEmailCampaignParams,
|
|
20
|
+
PrepareEmailCampaignResponse,
|
|
21
|
+
SendEmailCampaignParams,
|
|
22
|
+
SendEmailCampaignResponse,
|
|
17
23
|
} from './types.js';
|
|
18
24
|
import { isValidProvider } from '../utils/validators.js';
|
|
19
25
|
import { getChainIdFromProvider } from '../utils/getChainId.js';
|
|
@@ -110,9 +116,7 @@ export class IExecWeb3mail {
|
|
|
110
116
|
});
|
|
111
117
|
}
|
|
112
118
|
|
|
113
|
-
async sendEmail
|
|
114
|
-
args: Params
|
|
115
|
-
): Promise<SendEmailResponse<Params>> {
|
|
119
|
+
async sendEmail(args: SendEmailParams): Promise<SendEmailResponse> {
|
|
116
120
|
await this.init();
|
|
117
121
|
await isValidProvider(this.iexec);
|
|
118
122
|
return sendEmail({
|
|
@@ -120,13 +124,42 @@ export class IExecWeb3mail {
|
|
|
120
124
|
workerpoolAddressOrEns:
|
|
121
125
|
args.workerpoolAddressOrEns || this.defaultWorkerpool,
|
|
122
126
|
iexec: this.iexec,
|
|
123
|
-
dataProtector: this.dataProtector,
|
|
124
127
|
ipfsNode: this.ipfsNode,
|
|
125
128
|
ipfsGateway: this.ipfsGateway,
|
|
126
129
|
dappAddressOrENS: this.dappAddressOrENS,
|
|
127
130
|
dappWhitelistAddress: this.dappWhitelistAddress,
|
|
128
131
|
graphQLClient: this.graphQLClient,
|
|
129
|
-
})
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async prepareEmailCampaign(
|
|
136
|
+
args: PrepareEmailCampaignParams
|
|
137
|
+
): Promise<PrepareEmailCampaignResponse> {
|
|
138
|
+
await this.init();
|
|
139
|
+
await isValidProvider(this.iexec);
|
|
140
|
+
return prepareEmailCampaign({
|
|
141
|
+
...args,
|
|
142
|
+
workerpoolAddressOrEns:
|
|
143
|
+
args.workerpoolAddressOrEns || this.defaultWorkerpool,
|
|
144
|
+
iexec: this.iexec,
|
|
145
|
+
dataProtector: this.dataProtector,
|
|
146
|
+
ipfsNode: this.ipfsNode,
|
|
147
|
+
ipfsGateway: this.ipfsGateway,
|
|
148
|
+
dappAddressOrENS: this.dappAddressOrENS,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async sendEmailCampaign(
|
|
153
|
+
args: SendEmailCampaignParams
|
|
154
|
+
): Promise<SendEmailCampaignResponse> {
|
|
155
|
+
await this.init();
|
|
156
|
+
await isValidProvider(this.iexec);
|
|
157
|
+
return sendEmailCampaign({
|
|
158
|
+
...args,
|
|
159
|
+
workerpoolAddressOrEns:
|
|
160
|
+
args.workerpoolAddressOrEns || this.defaultWorkerpool,
|
|
161
|
+
dataProtector: this.dataProtector,
|
|
162
|
+
});
|
|
130
163
|
}
|
|
131
164
|
|
|
132
165
|
private async resolveConfig(): Promise<Web3mailResolvedConfig> {
|
|
@@ -25,6 +25,7 @@ export const fetchMyContacts = async ({
|
|
|
25
25
|
const vIsUserStrict = booleanSchema()
|
|
26
26
|
.label('isUserStrict')
|
|
27
27
|
.validateSync(isUserStrict);
|
|
28
|
+
const vBulkOnly = booleanSchema().label('bulkOnly').validateSync(bulkOnly);
|
|
28
29
|
|
|
29
30
|
const userAddress = await iexec.wallet.getAddress();
|
|
30
31
|
return fetchUserContacts({
|
|
@@ -34,6 +35,6 @@ export const fetchMyContacts = async ({
|
|
|
34
35
|
dappWhitelistAddress,
|
|
35
36
|
userAddress,
|
|
36
37
|
isUserStrict: vIsUserStrict,
|
|
37
|
-
bulkOnly,
|
|
38
|
+
bulkOnly: vBulkOnly,
|
|
38
39
|
});
|
|
39
40
|
};
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isEnsTest,
|
|
13
13
|
throwIfMissing,
|
|
14
14
|
} from '../utils/validators.js';
|
|
15
|
-
import { Contact, FetchUserContactsParams
|
|
15
|
+
import { Contact, FetchUserContactsParams } from './types.js';
|
|
16
16
|
import {
|
|
17
17
|
DappAddressConsumer,
|
|
18
18
|
DappWhitelistAddressConsumer,
|
|
@@ -67,6 +67,7 @@ export const fetchUserContacts = async ({
|
|
|
67
67
|
bulkOnly: vBulkOnly,
|
|
68
68
|
}),
|
|
69
69
|
]);
|
|
70
|
+
|
|
70
71
|
const orders = dappOrders.concat(whitelistOrders);
|
|
71
72
|
const myContacts: Omit<Contact, 'name'>[] = [];
|
|
72
73
|
let web3DappResolvedAddress = vDappAddressOrENS;
|
|
@@ -80,7 +81,7 @@ export const fetchUserContacts = async ({
|
|
|
80
81
|
order.order.apprestrict.toLowerCase() ===
|
|
81
82
|
vDappWhitelistAddress.toLowerCase()
|
|
82
83
|
) {
|
|
83
|
-
const contact
|
|
84
|
+
const contact = {
|
|
84
85
|
address: order.order.dataset.toLowerCase(),
|
|
85
86
|
owner: order.signer.toLowerCase(),
|
|
86
87
|
remainingAccess: order.remaining,
|
|
@@ -91,14 +92,14 @@ export const fetchUserContacts = async ({
|
|
|
91
92
|
dataset: order.order.dataset,
|
|
92
93
|
datasetprice: order.order.datasetprice.toString(),
|
|
93
94
|
volume: order.order.volume.toString(),
|
|
94
|
-
tag: order.order.tag,
|
|
95
|
+
tag: order.order.tag.toString(),
|
|
95
96
|
apprestrict: order.order.apprestrict,
|
|
96
97
|
workerpoolrestrict: order.order.workerpoolrestrict,
|
|
97
98
|
requesterrestrict: order.order.requesterrestrict,
|
|
98
99
|
salt: order.order.salt,
|
|
99
100
|
sign: order.order.sign,
|
|
100
101
|
remainingAccess: order.remaining,
|
|
101
|
-
}
|
|
102
|
+
},
|
|
102
103
|
};
|
|
103
104
|
myContacts.push(contact);
|
|
104
105
|
}
|
|
@@ -109,6 +110,7 @@ export const fetchUserContacts = async ({
|
|
|
109
110
|
return await getValidContact(graphQLClient, myContacts);
|
|
110
111
|
} catch (error) {
|
|
111
112
|
handleIfProtocolError(error);
|
|
113
|
+
|
|
112
114
|
throw new WorkflowError({
|
|
113
115
|
message: 'Failed to fetch user contacts',
|
|
114
116
|
errorCause: error,
|
|
@@ -127,7 +129,7 @@ async function fetchAllOrdersByApp({
|
|
|
127
129
|
userAddress: string;
|
|
128
130
|
appAddress: string;
|
|
129
131
|
isUserStrict: boolean;
|
|
130
|
-
bulkOnly
|
|
132
|
+
bulkOnly: boolean;
|
|
131
133
|
}): Promise<PublishedDatasetorder[]> {
|
|
132
134
|
const ordersFirstPage = iexec.orderbook.fetchDatasetOrderbook({
|
|
133
135
|
dataset: ANY_DATASET_ADDRESS,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IExec } from 'iexec';
|
|
2
|
+
import { IExecDataProtectorCore } from '@iexec/dataprotector';
|
|
2
3
|
import { AddressOrENS } from './types.js';
|
|
3
4
|
import { GraphQLClient } from 'graphql-request';
|
|
4
|
-
import { IExecDataProtectorCore } from '@iexec/dataprotector';
|
|
5
5
|
|
|
6
6
|
export type ProtectedDataQuery = {
|
|
7
7
|
id: string;
|
|
@@ -32,8 +32,10 @@ export type IExecConsumer = {
|
|
|
32
32
|
iexec: IExec;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
export type DataProtectorConsumer = { dataProtector: IExecDataProtectorCore };
|
|
36
|
-
|
|
37
35
|
export type SubgraphConsumer = {
|
|
38
36
|
graphQLClient: GraphQLClient;
|
|
39
37
|
};
|
|
38
|
+
|
|
39
|
+
export type DataProtectorConsumer = {
|
|
40
|
+
dataProtector: IExecDataProtectorCore;
|
|
41
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_CONTENT_TYPE,
|
|
4
|
+
MAX_DESIRED_APP_ORDER_PRICE,
|
|
5
|
+
MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
|
|
6
|
+
} from '../config/config.js';
|
|
7
|
+
import { handleIfProtocolError, WorkflowError } from '../utils/errors.js';
|
|
8
|
+
import * as ipfs from '../utils/ipfs-service.js';
|
|
9
|
+
import {
|
|
10
|
+
addressOrEnsSchema,
|
|
11
|
+
contentTypeSchema,
|
|
12
|
+
emailContentSchema,
|
|
13
|
+
emailSubjectSchema,
|
|
14
|
+
labelSchema,
|
|
15
|
+
positiveNumberSchema,
|
|
16
|
+
senderNameSchema,
|
|
17
|
+
throwIfMissing,
|
|
18
|
+
} from '../utils/validators.js';
|
|
19
|
+
import {
|
|
20
|
+
PrepareEmailCampaignParams,
|
|
21
|
+
PrepareEmailCampaignResponse,
|
|
22
|
+
} from './types.js';
|
|
23
|
+
import {
|
|
24
|
+
DappAddressConsumer,
|
|
25
|
+
DataProtectorConsumer,
|
|
26
|
+
IExecConsumer,
|
|
27
|
+
IpfsGatewayConfigConsumer,
|
|
28
|
+
IpfsNodeConfigConsumer,
|
|
29
|
+
} from './internalTypes.js';
|
|
30
|
+
|
|
31
|
+
export type PrepareEmailCampaign = typeof prepareEmailCampaign;
|
|
32
|
+
|
|
33
|
+
export const prepareEmailCampaign = async ({
|
|
34
|
+
iexec = throwIfMissing(),
|
|
35
|
+
dataProtector = throwIfMissing(),
|
|
36
|
+
workerpoolAddressOrEns,
|
|
37
|
+
dappAddressOrENS,
|
|
38
|
+
ipfsNode,
|
|
39
|
+
ipfsGateway,
|
|
40
|
+
senderName,
|
|
41
|
+
emailSubject,
|
|
42
|
+
emailContent,
|
|
43
|
+
contentType = DEFAULT_CONTENT_TYPE,
|
|
44
|
+
label,
|
|
45
|
+
appMaxPrice = MAX_DESIRED_APP_ORDER_PRICE,
|
|
46
|
+
workerpoolMaxPrice = MAX_DESIRED_WORKERPOOL_ORDER_PRICE,
|
|
47
|
+
grantedAccesses,
|
|
48
|
+
maxProtectedDataPerTask,
|
|
49
|
+
}: IExecConsumer &
|
|
50
|
+
DappAddressConsumer &
|
|
51
|
+
IpfsNodeConfigConsumer &
|
|
52
|
+
IpfsGatewayConfigConsumer &
|
|
53
|
+
DataProtectorConsumer &
|
|
54
|
+
PrepareEmailCampaignParams): Promise<PrepareEmailCampaignResponse> => {
|
|
55
|
+
try {
|
|
56
|
+
const vWorkerpoolAddressOrEns = addressOrEnsSchema()
|
|
57
|
+
.label('WorkerpoolAddressOrEns')
|
|
58
|
+
.validateSync(workerpoolAddressOrEns);
|
|
59
|
+
|
|
60
|
+
const vSenderName = senderNameSchema()
|
|
61
|
+
.label('senderName')
|
|
62
|
+
.validateSync(senderName);
|
|
63
|
+
|
|
64
|
+
const vEmailSubject = emailSubjectSchema()
|
|
65
|
+
.required()
|
|
66
|
+
.label('emailSubject')
|
|
67
|
+
.validateSync(emailSubject);
|
|
68
|
+
|
|
69
|
+
const vEmailContent = emailContentSchema()
|
|
70
|
+
.required()
|
|
71
|
+
.label('emailContent')
|
|
72
|
+
.validateSync(emailContent);
|
|
73
|
+
|
|
74
|
+
const vContentType = contentTypeSchema()
|
|
75
|
+
.label('contentType')
|
|
76
|
+
.validateSync(contentType);
|
|
77
|
+
|
|
78
|
+
const vLabel = labelSchema().label('label').validateSync(label);
|
|
79
|
+
|
|
80
|
+
const vDappAddressOrENS = addressOrEnsSchema()
|
|
81
|
+
.required()
|
|
82
|
+
.label('dappAddressOrENS')
|
|
83
|
+
.validateSync(dappAddressOrENS);
|
|
84
|
+
|
|
85
|
+
const vAppMaxPrice = positiveNumberSchema()
|
|
86
|
+
.label('appMaxPrice')
|
|
87
|
+
.validateSync(appMaxPrice);
|
|
88
|
+
|
|
89
|
+
const vWorkerpoolMaxPrice = positiveNumberSchema()
|
|
90
|
+
.label('workerpoolMaxPrice')
|
|
91
|
+
.validateSync(workerpoolMaxPrice);
|
|
92
|
+
|
|
93
|
+
const vMaxProtectedDataPerTask = positiveNumberSchema()
|
|
94
|
+
.label('maxProtectedDataPerTask')
|
|
95
|
+
.validateSync(maxProtectedDataPerTask);
|
|
96
|
+
|
|
97
|
+
// TODO: factor this
|
|
98
|
+
// Encrypt email content
|
|
99
|
+
const emailContentEncryptionKey = iexec.dataset.generateEncryptionKey();
|
|
100
|
+
const encryptedFile = await iexec.dataset
|
|
101
|
+
.encrypt(Buffer.from(vEmailContent, 'utf8'), emailContentEncryptionKey)
|
|
102
|
+
.catch((e) => {
|
|
103
|
+
throw new WorkflowError({
|
|
104
|
+
message: 'Failed to encrypt email content',
|
|
105
|
+
errorCause: e,
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Push email content to IPFS
|
|
110
|
+
const cid = await ipfs
|
|
111
|
+
.add(encryptedFile, {
|
|
112
|
+
ipfsNode,
|
|
113
|
+
ipfsGateway,
|
|
114
|
+
})
|
|
115
|
+
.catch((e) => {
|
|
116
|
+
throw new WorkflowError({
|
|
117
|
+
message: 'Failed to upload encrypted email content',
|
|
118
|
+
errorCause: e,
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const multiaddr = `/ipfs/${cid}`;
|
|
123
|
+
|
|
124
|
+
// Prepare secrets for the requester
|
|
125
|
+
// Use a positive integer as secret ID (required by iexec)
|
|
126
|
+
// Using "1" as a fixed ID for the requester secret
|
|
127
|
+
const requesterSecretId = 1;
|
|
128
|
+
const secrets = {
|
|
129
|
+
[requesterSecretId]: JSON.stringify({
|
|
130
|
+
emailSubject: vEmailSubject,
|
|
131
|
+
emailContentMultiAddr: multiaddr,
|
|
132
|
+
contentType: vContentType,
|
|
133
|
+
senderName: vSenderName,
|
|
134
|
+
emailContentEncryptionKey,
|
|
135
|
+
useCallback: true,
|
|
136
|
+
}),
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// TODO: end factor this
|
|
140
|
+
const { bulkRequest: campaignRequest } =
|
|
141
|
+
await dataProtector.prepareBulkRequest({
|
|
142
|
+
app: vDappAddressOrENS,
|
|
143
|
+
appMaxPrice: vAppMaxPrice,
|
|
144
|
+
workerpoolMaxPrice: vWorkerpoolMaxPrice,
|
|
145
|
+
workerpool: vWorkerpoolAddressOrEns,
|
|
146
|
+
args: vLabel,
|
|
147
|
+
inputFiles: [],
|
|
148
|
+
secrets,
|
|
149
|
+
bulkAccesses: grantedAccesses,
|
|
150
|
+
maxProtectedDataPerTask: vMaxProtectedDataPerTask,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return { campaignRequest };
|
|
154
|
+
} catch (error) {
|
|
155
|
+
// Protocol error detected, re-throwing as-is
|
|
156
|
+
if ((error as any)?.isProtocolError === true) {
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Handle protocol errors - this will throw if it's an ApiCallError
|
|
161
|
+
// handleIfProtocolError transforms ApiCallError into a WorkflowError with isProtocolError=true
|
|
162
|
+
handleIfProtocolError(error);
|
|
163
|
+
|
|
164
|
+
// For all other errors
|
|
165
|
+
throw new WorkflowError({
|
|
166
|
+
message: 'Failed to prepareEmailCampaign',
|
|
167
|
+
errorCause: error,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
};
|