@dereekb/nestjs 13.0.0 → 13.0.1
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/index.cjs.default.js +1 -0
- package/index.cjs.js +136 -118
- package/index.cjs.mjs +2 -0
- package/index.esm.js +136 -118
- package/mailgun/index.cjs.default.js +1 -0
- package/mailgun/index.cjs.js +496 -503
- package/mailgun/index.cjs.mjs +2 -0
- package/mailgun/index.esm.js +496 -503
- package/mailgun/package.json +19 -20
- package/openai/index.cjs.default.js +1 -0
- package/openai/index.cjs.js +194 -161
- package/openai/index.cjs.mjs +2 -0
- package/openai/index.esm.js +194 -161
- package/openai/package.json +19 -20
- package/package.json +32 -55
- package/stripe/index.cjs.default.js +1 -0
- package/stripe/index.cjs.js +158 -128
- package/stripe/index.cjs.mjs +2 -0
- package/stripe/index.esm.js +158 -128
- package/stripe/package.json +19 -20
- package/typeform/index.cjs.default.js +1 -0
- package/typeform/index.cjs.js +257 -240
- package/typeform/index.cjs.mjs +2 -0
- package/typeform/index.esm.js +257 -240
- package/typeform/package.json +19 -20
- package/vapiai/index.cjs.default.js +1 -0
- package/vapiai/index.cjs.js +203 -190
- package/vapiai/index.cjs.mjs +2 -0
- package/vapiai/index.esm.js +203 -190
- package/vapiai/package.json +19 -20
package/vapiai/index.cjs.js
CHANGED
|
@@ -14,32 +14,32 @@ var serverSdk = require('@vapi-ai/server-sdk');
|
|
|
14
14
|
* @returns
|
|
15
15
|
*/
|
|
16
16
|
function vapiAiWebhookEvent(event) {
|
|
17
|
-
|
|
17
|
+
return event;
|
|
18
18
|
}
|
|
19
|
-
const vapiaiEventHandlerFactory = util.handlerFactory(x => x.type, {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
const vapiaiEventHandlerFactory = util.handlerFactory((x) => x.type, {
|
|
20
|
+
defaultResult: {
|
|
21
|
+
handled: true,
|
|
22
|
+
response: undefined
|
|
23
|
+
},
|
|
24
|
+
negativeResult: {
|
|
25
|
+
handled: true,
|
|
26
|
+
response: undefined
|
|
27
|
+
}
|
|
28
28
|
});
|
|
29
29
|
const vapiaiEventHandlerConfigurerFactory = util.handlerConfigurerFactory({
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
30
|
+
configurerForAccessor: (accessor) => {
|
|
31
|
+
// eslint-disable-next-line
|
|
32
|
+
const fnWithKey = util.handlerMappedSetFunctionFactory(accessor, vapiAiWebhookEvent);
|
|
33
|
+
const configurer = {
|
|
34
|
+
...accessor,
|
|
35
|
+
handleAssistantRequest: fnWithKey('assistant-request'),
|
|
36
|
+
handleStatusUpdate: fnWithKey('status-update'),
|
|
37
|
+
handleFunctionCall: fnWithKey('function-call'),
|
|
38
|
+
handleEndOfCallReport: fnWithKey('end-of-call-report'),
|
|
39
|
+
handleHang: fnWithKey('hang')
|
|
40
|
+
};
|
|
41
|
+
return configurer;
|
|
42
|
+
}
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
/******************************************************************************
|
|
@@ -86,55 +86,42 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
86
86
|
* @returns A function that verifies a VapiAi webhook event.
|
|
87
87
|
*/
|
|
88
88
|
function vapiAiWebhookEventVerifier(config) {
|
|
89
|
-
|
|
90
|
-
verificationType:
|
|
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
|
-
const verify = verificationType === 'hmac' ? verifyHmac : verificationType === 'secret' ? verifySecret : verifyNone;
|
|
125
|
-
return async (request, rawBody) => {
|
|
126
|
-
const requestBodyString = String(request.body);
|
|
127
|
-
const valid = verify({
|
|
128
|
-
request,
|
|
129
|
-
requestBodyString
|
|
130
|
-
});
|
|
131
|
-
const requestBody = JSON.parse(requestBodyString);
|
|
132
|
-
const result = {
|
|
133
|
-
valid,
|
|
134
|
-
event: requestBody.message
|
|
89
|
+
const { verificationType: inputVerificationType, secret: inputSecret, hmacSecret: inputHmacSecret, signaturePrefix: inputSignaturePrefix } = config;
|
|
90
|
+
const verificationType = inputVerificationType ?? (inputHmacSecret != null ? 'hmac' : 'secret'); // default to secret always, never default to none
|
|
91
|
+
const secretToken = (verificationType === 'hmac' ? (inputHmacSecret ?? inputSecret) : inputSecret) ?? '';
|
|
92
|
+
const signaturePrefix = inputSignaturePrefix ?? '';
|
|
93
|
+
function verifyNone(input) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
function verifySecret(input) {
|
|
97
|
+
const { request } = input;
|
|
98
|
+
const headers = request.headers;
|
|
99
|
+
const vapiSecret = headers['x-vapi-secret'];
|
|
100
|
+
const valid = vapiSecret === secretToken;
|
|
101
|
+
return valid;
|
|
102
|
+
}
|
|
103
|
+
function verifyHmac(input) {
|
|
104
|
+
const { request, requestBodyString } = input;
|
|
105
|
+
const headers = request.headers;
|
|
106
|
+
const timestamp = headers['x-timestamp'];
|
|
107
|
+
const vapiSignature = headers['x-signature'];
|
|
108
|
+
const message = `${timestamp}.${requestBodyString}`;
|
|
109
|
+
const hashForVerify = crypto.createHmac('sha256', secretToken).update(message).digest('hex');
|
|
110
|
+
const signature = `${signaturePrefix}${hashForVerify}`;
|
|
111
|
+
const valid = vapiSignature === signature;
|
|
112
|
+
return valid;
|
|
113
|
+
}
|
|
114
|
+
const verify = verificationType === 'hmac' ? verifyHmac : verificationType === 'secret' ? verifySecret : verifyNone;
|
|
115
|
+
return async (request, rawBody) => {
|
|
116
|
+
const requestBodyString = String(request.body);
|
|
117
|
+
const valid = verify({ request, requestBodyString });
|
|
118
|
+
const requestBody = JSON.parse(requestBodyString);
|
|
119
|
+
const result = {
|
|
120
|
+
valid,
|
|
121
|
+
event: requestBody.message
|
|
122
|
+
};
|
|
123
|
+
return result;
|
|
135
124
|
};
|
|
136
|
-
return result;
|
|
137
|
-
};
|
|
138
125
|
}
|
|
139
126
|
|
|
140
127
|
const VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_TOKEN';
|
|
@@ -145,156 +132,182 @@ const VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR = 'VAPI_AI_WEBHOOK_SIGNATURE_PREF
|
|
|
145
132
|
* Configuration for VapiAiService
|
|
146
133
|
*/
|
|
147
134
|
class VapiAiWebhookServiceConfig {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
135
|
+
webhookConfig;
|
|
136
|
+
static assertValidConfig(config) {
|
|
137
|
+
if (!config.webhookConfig.secret && !config.webhookConfig.hmacSecret) {
|
|
138
|
+
throw new Error('No Vapi.ai webhook secret token specified.');
|
|
139
|
+
}
|
|
152
140
|
}
|
|
153
|
-
}
|
|
154
141
|
}
|
|
155
142
|
|
|
156
143
|
/**
|
|
157
144
|
* Service that makes system changes based on VapiAi webhook events.
|
|
158
145
|
*/
|
|
159
146
|
exports.VapiAiWebhookService = class VapiAiWebhookService {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
async updateForWebhook(req, rawBody) {
|
|
168
|
-
const {
|
|
169
|
-
valid,
|
|
170
|
-
event
|
|
171
|
-
} = await this._verifier(req, rawBody);
|
|
172
|
-
let result = {
|
|
173
|
-
handled: false
|
|
174
|
-
};
|
|
175
|
-
if (!valid) {
|
|
176
|
-
this.logger.warn('Received invalid Vapi.ai event: ', event);
|
|
177
|
-
} else {
|
|
178
|
-
result = await this.updateForVapiAiEvent(event);
|
|
147
|
+
logger = new common.Logger('VapiAiWebhookService');
|
|
148
|
+
_verifier;
|
|
149
|
+
handler = vapiaiEventHandlerFactory();
|
|
150
|
+
configure = vapiaiEventHandlerConfigurerFactory(this.handler);
|
|
151
|
+
constructor(vapiAiWebhookServiceConfig) {
|
|
152
|
+
this._verifier = vapiAiWebhookEventVerifier(vapiAiWebhookServiceConfig.webhookConfig);
|
|
179
153
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
154
|
+
async updateForWebhook(req, rawBody) {
|
|
155
|
+
const { valid, event } = await this._verifier(req, rawBody);
|
|
156
|
+
let result = {
|
|
157
|
+
handled: false
|
|
158
|
+
};
|
|
159
|
+
if (!valid) {
|
|
160
|
+
this.logger.warn('Received invalid Vapi.ai event: ', event);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
result = await this.updateForVapiAiEvent(event);
|
|
164
|
+
}
|
|
165
|
+
const response = {
|
|
166
|
+
valid,
|
|
167
|
+
event,
|
|
168
|
+
...result
|
|
169
|
+
};
|
|
170
|
+
return response;
|
|
171
|
+
}
|
|
172
|
+
async updateForVapiAiEvent(event) {
|
|
173
|
+
const result = await this.handler(event);
|
|
174
|
+
if (!result.handled) {
|
|
175
|
+
this.logger.warn('Received unexpected/unhandled Vapi.ai event: ', event);
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
191
178
|
}
|
|
192
|
-
return result;
|
|
193
|
-
}
|
|
194
179
|
};
|
|
195
|
-
exports.VapiAiWebhookService = __decorate([
|
|
180
|
+
exports.VapiAiWebhookService = __decorate([
|
|
181
|
+
common.Injectable(),
|
|
182
|
+
__param(0, common.Inject(VapiAiWebhookServiceConfig)),
|
|
183
|
+
__metadata("design:paramtypes", [VapiAiWebhookServiceConfig])
|
|
184
|
+
], exports.VapiAiWebhookService);
|
|
196
185
|
|
|
197
186
|
exports.VapiAiWebhookController = class VapiAiWebhookController {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
response.json({});
|
|
187
|
+
_vapiaiWebhookService;
|
|
188
|
+
constructor(vapiaiWebhookService) {
|
|
189
|
+
this._vapiaiWebhookService = vapiaiWebhookService;
|
|
190
|
+
}
|
|
191
|
+
async handleVapiAiWebhook(res, req, rawBody) {
|
|
192
|
+
const { valid, response: responseData } = await this._vapiaiWebhookService.updateForWebhook(req, rawBody);
|
|
193
|
+
const response = res.status(200); // always return a 200 status code
|
|
194
|
+
if (valid && responseData) {
|
|
195
|
+
response.json(responseData);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
response.json({});
|
|
199
|
+
}
|
|
212
200
|
}
|
|
213
|
-
}
|
|
214
201
|
};
|
|
215
|
-
__decorate([
|
|
216
|
-
|
|
202
|
+
__decorate([
|
|
203
|
+
common.Post(),
|
|
204
|
+
__param(0, common.Res()),
|
|
205
|
+
__param(1, common.Req()),
|
|
206
|
+
__param(2, nestjs.RawBody()),
|
|
207
|
+
__metadata("design:type", Function),
|
|
208
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
209
|
+
__metadata("design:returntype", Promise)
|
|
210
|
+
], exports.VapiAiWebhookController.prototype, "handleVapiAiWebhook", null);
|
|
211
|
+
exports.VapiAiWebhookController = __decorate([
|
|
212
|
+
common.Controller('/webhook/vapiai'),
|
|
213
|
+
__param(0, common.Inject(exports.VapiAiWebhookService)),
|
|
214
|
+
__metadata("design:paramtypes", [exports.VapiAiWebhookService])
|
|
215
|
+
], exports.VapiAiWebhookController);
|
|
217
216
|
|
|
218
217
|
function vapiaiWebhookServiceConfigFactory(configService) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
218
|
+
const config = {
|
|
219
|
+
webhookConfig: {
|
|
220
|
+
secret: configService.get(VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR),
|
|
221
|
+
hmacSecret: configService.get(VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR),
|
|
222
|
+
verificationType: configService.get(VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR),
|
|
223
|
+
signaturePrefix: configService.get(VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR)
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
VapiAiWebhookServiceConfig.assertValidConfig(config);
|
|
227
|
+
return config;
|
|
229
228
|
}
|
|
230
|
-
exports.VapiAiWebhookModule = class VapiAiWebhookModule {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
229
|
+
exports.VapiAiWebhookModule = class VapiAiWebhookModule {
|
|
230
|
+
};
|
|
231
|
+
exports.VapiAiWebhookModule = __decorate([
|
|
232
|
+
common.Module({
|
|
233
|
+
imports: [config.ConfigModule],
|
|
234
|
+
controllers: [exports.VapiAiWebhookController],
|
|
235
|
+
providers: [
|
|
236
|
+
{
|
|
237
|
+
provide: VapiAiWebhookServiceConfig,
|
|
238
|
+
inject: [config.ConfigService],
|
|
239
|
+
useFactory: vapiaiWebhookServiceConfigFactory
|
|
240
|
+
},
|
|
241
|
+
exports.VapiAiWebhookService
|
|
242
|
+
],
|
|
243
|
+
exports: [exports.VapiAiWebhookService]
|
|
244
|
+
})
|
|
245
|
+
], exports.VapiAiWebhookModule);
|
|
241
246
|
|
|
242
247
|
const VAPI_AI_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_SECRET_TOKEN';
|
|
243
248
|
/**
|
|
244
249
|
* Configuration for VapiAiService
|
|
245
250
|
*/
|
|
246
251
|
class VapiAiServiceConfig {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
252
|
+
vapiai;
|
|
253
|
+
static assertValidConfig(config) {
|
|
254
|
+
if (!config.vapiai.config.token) {
|
|
255
|
+
throw new Error('No Vapi.ai secret/token specified.');
|
|
256
|
+
}
|
|
251
257
|
}
|
|
252
|
-
}
|
|
253
258
|
}
|
|
254
259
|
|
|
255
260
|
exports.VapiAiApi = class VapiAiApi {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
});
|
|
273
|
-
}
|
|
261
|
+
config;
|
|
262
|
+
vapiClient;
|
|
263
|
+
constructor(config) {
|
|
264
|
+
this.config = config;
|
|
265
|
+
this.vapiClient = new serverSdk.VapiClient(config.vapiai.config);
|
|
266
|
+
}
|
|
267
|
+
// MARK: Accessors
|
|
268
|
+
/**
|
|
269
|
+
* Gets a call by ID.
|
|
270
|
+
*
|
|
271
|
+
* @param callId
|
|
272
|
+
* @returns
|
|
273
|
+
*/
|
|
274
|
+
getCall(callId) {
|
|
275
|
+
return this.vapiClient.calls.get({ id: callId });
|
|
276
|
+
}
|
|
274
277
|
};
|
|
275
|
-
exports.VapiAiApi = __decorate([
|
|
278
|
+
exports.VapiAiApi = __decorate([
|
|
279
|
+
common.Injectable(),
|
|
280
|
+
__param(0, common.Inject(VapiAiServiceConfig)),
|
|
281
|
+
__metadata("design:paramtypes", [VapiAiServiceConfig])
|
|
282
|
+
], exports.VapiAiApi);
|
|
276
283
|
|
|
277
284
|
function vapiaiServiceConfigFactory(configService) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
const config = {
|
|
286
|
+
vapiai: {
|
|
287
|
+
config: {
|
|
288
|
+
token: configService.get(VAPI_AI_SECRET_TOKEN_ENV_VAR)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
VapiAiServiceConfig.assertValidConfig(config);
|
|
293
|
+
return config;
|
|
287
294
|
}
|
|
288
|
-
exports.VapiAiModule = class VapiAiModule {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
295
|
+
exports.VapiAiModule = class VapiAiModule {
|
|
296
|
+
};
|
|
297
|
+
exports.VapiAiModule = __decorate([
|
|
298
|
+
common.Module({
|
|
299
|
+
imports: [config.ConfigModule],
|
|
300
|
+
providers: [
|
|
301
|
+
{
|
|
302
|
+
provide: VapiAiServiceConfig,
|
|
303
|
+
inject: [config.ConfigService],
|
|
304
|
+
useFactory: vapiaiServiceConfigFactory
|
|
305
|
+
},
|
|
306
|
+
exports.VapiAiApi
|
|
307
|
+
],
|
|
308
|
+
exports: [exports.VapiAiApi]
|
|
309
|
+
})
|
|
310
|
+
], exports.VapiAiModule);
|
|
298
311
|
|
|
299
312
|
exports.VAPI_AI_SECRET_TOKEN_ENV_VAR = VAPI_AI_SECRET_TOKEN_ENV_VAR;
|
|
300
313
|
exports.VapiAiServiceConfig = VapiAiServiceConfig;
|