@dereekb/nestjs 12.6.21 → 13.0.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/LICENSE +1 -1
- package/index.cjs.js +292 -0
- package/index.d.ts +1 -0
- package/index.esm.js +270 -0
- package/mailgun/index.cjs.js +646 -0
- package/mailgun/index.d.ts +1 -0
- package/mailgun/index.esm.js +633 -0
- package/mailgun/package.json +24 -3
- package/mailgun/src/lib/mailgun.d.ts +2 -2
- package/mailgun/src/lib/mailgun.type.d.ts +1 -1
- package/mailgun/src/lib/mailgun.util.d.ts +22 -17
- package/openai/index.cjs.js +310 -0
- package/openai/index.d.ts +1 -0
- package/openai/index.esm.js +293 -0
- package/openai/package.json +24 -5
- package/openai/src/lib/index.d.ts +0 -1
- package/openai/src/lib/webhook/webhook.openai.controller.d.ts +1 -1
- package/openai/src/lib/webhook/webhook.openai.d.ts +2 -2
- package/openai/src/lib/webhook/webhook.openai.service.d.ts +1 -1
- package/package.json +58 -28
- package/stripe/index.cjs.js +223 -0
- package/stripe/index.d.ts +1 -0
- package/stripe/index.esm.js +215 -0
- package/stripe/package.json +24 -5
- package/stripe/src/lib/index.d.ts +1 -1
- package/stripe/src/lib/stripe.module.d.ts +2 -2
- package/stripe/src/lib/webhook/webhook.stripe.controller.d.ts +1 -1
- package/typeform/index.cjs.js +378 -0
- package/typeform/index.d.ts +1 -0
- package/typeform/index.esm.js +363 -0
- package/typeform/package.json +24 -5
- package/typeform/src/lib/index.d.ts +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.controller.d.ts +1 -1
- package/vapiai/index.cjs.js +306 -0
- package/vapiai/index.d.ts +1 -0
- package/vapiai/index.esm.js +297 -0
- package/vapiai/package.json +24 -5
- package/vapiai/src/lib/index.d.ts +0 -1
- package/vapiai/src/lib/vapiai.type.d.ts +3 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.controller.d.ts +1 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.d.ts +1 -9
- package/vapiai/src/lib/webhook/webhook.vapiai.types.d.ts +6 -34
- package/CHANGELOG.md +0 -1997
- package/mailgun/LICENSE +0 -21
- package/mailgun/src/index.js +0 -5
- package/mailgun/src/index.js.map +0 -1
- package/mailgun/src/lib/index.js +0 -10
- package/mailgun/src/lib/index.js.map +0 -1
- package/mailgun/src/lib/mailgun.api.js +0 -37
- package/mailgun/src/lib/mailgun.api.js.map +0 -1
- package/mailgun/src/lib/mailgun.config.js +0 -45
- package/mailgun/src/lib/mailgun.config.js.map +0 -1
- package/mailgun/src/lib/mailgun.js +0 -205
- package/mailgun/src/lib/mailgun.js.map +0 -1
- package/mailgun/src/lib/mailgun.service.js +0 -53
- package/mailgun/src/lib/mailgun.service.js.map +0 -1
- package/mailgun/src/lib/mailgun.service.module.js +0 -84
- package/mailgun/src/lib/mailgun.service.module.js.map +0 -1
- package/mailgun/src/lib/mailgun.type.js +0 -3
- package/mailgun/src/lib/mailgun.type.js.map +0 -1
- package/mailgun/src/lib/mailgun.util.js +0 -206
- package/mailgun/src/lib/mailgun.util.js.map +0 -1
- package/openai/LICENSE +0 -21
- package/openai/src/index.js +0 -5
- package/openai/src/index.js.map +0 -1
- package/openai/src/lib/index.js +0 -11
- package/openai/src/lib/index.js.map +0 -1
- package/openai/src/lib/openai.api.js +0 -22
- package/openai/src/lib/openai.api.js.map +0 -1
- package/openai/src/lib/openai.config.js +0 -29
- package/openai/src/lib/openai.config.js.map +0 -1
- package/openai/src/lib/openai.module.js +0 -41
- package/openai/src/lib/openai.module.js.map +0 -1
- package/openai/src/lib/openai.type.js +0 -3
- package/openai/src/lib/openai.type.js.map +0 -1
- package/openai/src/lib/openai.util.js +0 -48
- package/openai/src/lib/openai.util.js.map +0 -1
- package/openai/src/lib/webhook/index.js +0 -10
- package/openai/src/lib/webhook/index.js.map +0 -1
- package/openai/src/lib/webhook/webhook.openai.config.js +0 -17
- package/openai/src/lib/webhook/webhook.openai.config.js.map +0 -1
- package/openai/src/lib/webhook/webhook.openai.controller.js +0 -30
- package/openai/src/lib/webhook/webhook.openai.controller.js.map +0 -1
- package/openai/src/lib/webhook/webhook.openai.js +0 -41
- package/openai/src/lib/webhook/webhook.openai.js.map +0 -1
- package/openai/src/lib/webhook/webhook.openai.module.js +0 -39
- package/openai/src/lib/webhook/webhook.openai.module.js.map +0 -1
- package/openai/src/lib/webhook/webhook.openai.service.js +0 -48
- package/openai/src/lib/webhook/webhook.openai.service.js.map +0 -1
- package/openai/src/lib/webhook/webhook.openai.verify.js +0 -37
- package/openai/src/lib/webhook/webhook.openai.verify.js.map +0 -1
- package/src/index.js +0 -5
- package/src/index.js.map +0 -1
- package/src/lib/decorators/index.js +0 -6
- package/src/lib/decorators/index.js.map +0 -1
- package/src/lib/decorators/local.decorator.js +0 -17
- package/src/lib/decorators/local.decorator.js.map +0 -1
- package/src/lib/decorators/rawbody.js +0 -44
- package/src/lib/decorators/rawbody.js.map +0 -1
- package/src/lib/index.js +0 -7
- package/src/lib/index.js.map +0 -1
- package/src/lib/middlewares/index.js +0 -7
- package/src/lib/middlewares/index.js.map +0 -1
- package/src/lib/middlewares/json.middleware.js +0 -16
- package/src/lib/middlewares/json.middleware.js.map +0 -1
- package/src/lib/middlewares/rawbody.middleware.js +0 -16
- package/src/lib/middlewares/rawbody.middleware.js.map +0 -1
- package/src/lib/middlewares/webhook.js +0 -51
- package/src/lib/middlewares/webhook.js.map +0 -1
- package/src/lib/module/client/client.config.js +0 -13
- package/src/lib/module/client/client.config.js.map +0 -1
- package/src/lib/module/client/client.js +0 -8
- package/src/lib/module/client/client.js.map +0 -1
- package/src/lib/module/client/client.module.js +0 -36
- package/src/lib/module/client/client.module.js.map +0 -1
- package/src/lib/module/client/client.service.js +0 -30
- package/src/lib/module/client/client.service.js.map +0 -1
- package/src/lib/module/client/index.js +0 -8
- package/src/lib/module/client/index.js.map +0 -1
- package/src/lib/module/env/env.config.js +0 -14
- package/src/lib/module/env/env.config.js.map +0 -1
- package/src/lib/module/env/env.js +0 -10
- package/src/lib/module/env/env.js.map +0 -1
- package/src/lib/module/env/env.nest.js +0 -16
- package/src/lib/module/env/env.nest.js.map +0 -1
- package/src/lib/module/env/env.service.js +0 -33
- package/src/lib/module/env/env.service.js.map +0 -1
- package/src/lib/module/env/index.js +0 -8
- package/src/lib/module/env/index.js.map +0 -1
- package/src/lib/module/index.js +0 -7
- package/src/lib/module/index.js.map +0 -1
- package/src/lib/module/module.js +0 -26
- package/src/lib/module/module.js.map +0 -1
- package/stripe/LICENSE +0 -21
- package/stripe/src/index.js +0 -5
- package/stripe/src/index.js.map +0 -1
- package/stripe/src/lib/index.js +0 -8
- package/stripe/src/lib/index.js.map +0 -1
- package/stripe/src/lib/stripe.api.js +0 -40
- package/stripe/src/lib/stripe.api.js.map +0 -1
- package/stripe/src/lib/stripe.config.js +0 -19
- package/stripe/src/lib/stripe.config.js.map +0 -1
- package/stripe/src/lib/stripe.module.js +0 -41
- package/stripe/src/lib/stripe.module.js.map +0 -1
- package/stripe/src/lib/stripe.type.js +0 -4
- package/stripe/src/lib/stripe.type.js.map +0 -1
- package/stripe/src/lib/webhook/index.js +0 -8
- package/stripe/src/lib/webhook/index.js.map +0 -1
- package/stripe/src/lib/webhook/webhook.stripe.controller.js +0 -30
- package/stripe/src/lib/webhook/webhook.stripe.controller.js.map +0 -1
- package/stripe/src/lib/webhook/webhook.stripe.js +0 -67
- package/stripe/src/lib/webhook/webhook.stripe.js.map +0 -1
- package/stripe/src/lib/webhook/webhook.stripe.module.js +0 -20
- package/stripe/src/lib/webhook/webhook.stripe.module.js.map +0 -1
- package/stripe/src/lib/webhook/webhook.stripe.service.js +0 -36
- package/stripe/src/lib/webhook/webhook.stripe.service.js.map +0 -1
- package/typeform/LICENSE +0 -21
- package/typeform/src/index.js +0 -5
- package/typeform/src/index.js.map +0 -1
- package/typeform/src/lib/index.js +0 -11
- package/typeform/src/lib/index.js.map +0 -1
- package/typeform/src/lib/typeform.api.js +0 -22
- package/typeform/src/lib/typeform.api.js.map +0 -1
- package/typeform/src/lib/typeform.config.js +0 -21
- package/typeform/src/lib/typeform.config.js.map +0 -1
- package/typeform/src/lib/typeform.module.js +0 -39
- package/typeform/src/lib/typeform.module.js.map +0 -1
- package/typeform/src/lib/typeform.type.js +0 -3
- package/typeform/src/lib/typeform.type.js.map +0 -1
- package/typeform/src/lib/typeform.util.js +0 -26
- package/typeform/src/lib/typeform.util.js.map +0 -1
- package/typeform/src/lib/webhook/index.js +0 -12
- package/typeform/src/lib/webhook/index.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.config.js +0 -17
- package/typeform/src/lib/webhook/webhook.typeform.config.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.controller.js +0 -30
- package/typeform/src/lib/webhook/webhook.typeform.controller.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.form.js +0 -113
- package/typeform/src/lib/webhook/webhook.typeform.form.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.js +0 -27
- package/typeform/src/lib/webhook/webhook.typeform.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.module.js +0 -38
- package/typeform/src/lib/webhook/webhook.typeform.module.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.service.js +0 -45
- package/typeform/src/lib/webhook/webhook.typeform.service.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.type.js +0 -3
- package/typeform/src/lib/webhook/webhook.typeform.type.js.map +0 -1
- package/typeform/src/lib/webhook/webhook.typeform.verify.js +0 -28
- package/typeform/src/lib/webhook/webhook.typeform.verify.js.map +0 -1
- package/vapiai/LICENSE +0 -21
- package/vapiai/src/index.js +0 -5
- package/vapiai/src/index.js.map +0 -1
- package/vapiai/src/lib/index.js +0 -10
- package/vapiai/src/lib/index.js.map +0 -1
- package/vapiai/src/lib/vapiai.api.js +0 -32
- package/vapiai/src/lib/vapiai.api.js.map +0 -1
- package/vapiai/src/lib/vapiai.config.js +0 -17
- package/vapiai/src/lib/vapiai.config.js.map +0 -1
- package/vapiai/src/lib/vapiai.module.js +0 -38
- package/vapiai/src/lib/vapiai.module.js.map +0 -1
- package/vapiai/src/lib/vapiai.type.js +0 -3
- package/vapiai/src/lib/vapiai.type.js.map +0 -1
- package/vapiai/src/lib/webhook/index.js +0 -10
- package/vapiai/src/lib/webhook/index.js.map +0 -1
- package/vapiai/src/lib/webhook/webhook.vapi.config.js +0 -20
- package/vapiai/src/lib/webhook/webhook.vapi.config.js.map +0 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.controller.js +0 -38
- package/vapiai/src/lib/webhook/webhook.vapiai.controller.js.map +0 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.js +0 -42
- package/vapiai/src/lib/webhook/webhook.vapiai.js.map +0 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.module.js +0 -41
- package/vapiai/src/lib/webhook/webhook.vapiai.module.js.map +0 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.service.js +0 -52
- package/vapiai/src/lib/webhook/webhook.vapiai.service.js.map +0 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.types.js +0 -25
- package/vapiai/src/lib/webhook/webhook.vapiai.types.js.map +0 -1
- package/vapiai/src/lib/webhook/webhook.vapiai.verify.js +0 -49
- package/vapiai/src/lib/webhook/webhook.vapiai.verify.js.map +0 -1
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var util = require('@dereekb/util');
|
|
4
|
+
var nestjs = require('@dereekb/nestjs');
|
|
5
|
+
var common = require('@nestjs/common');
|
|
6
|
+
var crypto = require('crypto');
|
|
7
|
+
var config = require('@nestjs/config');
|
|
8
|
+
var serverSdk = require('@vapi-ai/server-sdk');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a VapiAiWebhookEvent and treats the data as the input type.
|
|
12
|
+
*
|
|
13
|
+
* @param event
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
function vapiAiWebhookEvent(event) {
|
|
17
|
+
return event;
|
|
18
|
+
}
|
|
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
|
+
});
|
|
29
|
+
const vapiaiEventHandlerConfigurerFactory = util.handlerConfigurerFactory({
|
|
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
|
+
});
|
|
44
|
+
|
|
45
|
+
/******************************************************************************
|
|
46
|
+
Copyright (c) Microsoft Corporation.
|
|
47
|
+
|
|
48
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
49
|
+
purpose with or without fee is hereby granted.
|
|
50
|
+
|
|
51
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
52
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
53
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
54
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
55
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
56
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
57
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
58
|
+
***************************************************************************** */
|
|
59
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
function __decorate(decorators, target, key, desc) {
|
|
63
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
64
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
65
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
66
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function __param(paramIndex, decorator) {
|
|
70
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function __metadata(metadataKey, metadataValue) {
|
|
74
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
78
|
+
var e = new Error(message);
|
|
79
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Verifies a VapiAi webhook event header.
|
|
84
|
+
*
|
|
85
|
+
* @param vapiSecretTokenGetter The VapiAi secret token. The Vapi client allows for using an AsyncGetterOrValue type, so the verifier supports that as well.
|
|
86
|
+
* @returns A function that verifies a VapiAi webhook event.
|
|
87
|
+
*/
|
|
88
|
+
function vapiAiWebhookEventVerifier(config) {
|
|
89
|
+
const {
|
|
90
|
+
verificationType: inputVerificationType,
|
|
91
|
+
secret: inputSecret,
|
|
92
|
+
hmacSecret: inputHmacSecret,
|
|
93
|
+
signaturePrefix: inputSignaturePrefix
|
|
94
|
+
} = config;
|
|
95
|
+
const verificationType = inputVerificationType ?? (inputHmacSecret != null ? 'hmac' : 'secret'); // default to secret always, never default to none
|
|
96
|
+
const secretToken = (verificationType === 'hmac' ? inputHmacSecret ?? inputSecret : inputSecret) ?? '';
|
|
97
|
+
const signaturePrefix = inputSignaturePrefix ?? '';
|
|
98
|
+
function verifyNone(input) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
function verifySecret(input) {
|
|
102
|
+
const {
|
|
103
|
+
request
|
|
104
|
+
} = input;
|
|
105
|
+
const headers = request.headers;
|
|
106
|
+
const vapiSecret = headers['x-vapi-secret'];
|
|
107
|
+
const valid = vapiSecret === secretToken;
|
|
108
|
+
return valid;
|
|
109
|
+
}
|
|
110
|
+
function verifyHmac(input) {
|
|
111
|
+
const {
|
|
112
|
+
request,
|
|
113
|
+
requestBodyString
|
|
114
|
+
} = input;
|
|
115
|
+
const headers = request.headers;
|
|
116
|
+
const timestamp = headers['x-timestamp'];
|
|
117
|
+
const vapiSignature = headers['x-signature'];
|
|
118
|
+
const message = `${timestamp}.${requestBodyString}`;
|
|
119
|
+
const hashForVerify = crypto.createHmac('sha256', secretToken).update(message).digest('hex');
|
|
120
|
+
const signature = `${signaturePrefix}${hashForVerify}`;
|
|
121
|
+
const valid = vapiSignature === signature;
|
|
122
|
+
return valid;
|
|
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
|
|
135
|
+
};
|
|
136
|
+
return result;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_TOKEN';
|
|
141
|
+
const VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN';
|
|
142
|
+
const VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE';
|
|
143
|
+
const VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR = 'VAPI_AI_WEBHOOK_SIGNATURE_PREFIX';
|
|
144
|
+
/**
|
|
145
|
+
* Configuration for VapiAiService
|
|
146
|
+
*/
|
|
147
|
+
class VapiAiWebhookServiceConfig {
|
|
148
|
+
webhookConfig;
|
|
149
|
+
static assertValidConfig(config) {
|
|
150
|
+
if (!config.webhookConfig.secret && !config.webhookConfig.hmacSecret) {
|
|
151
|
+
throw new Error('No Vapi.ai webhook secret token specified.');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Service that makes system changes based on VapiAi webhook events.
|
|
158
|
+
*/
|
|
159
|
+
exports.VapiAiWebhookService = class VapiAiWebhookService {
|
|
160
|
+
logger = new common.Logger('VapiAiWebhookService');
|
|
161
|
+
_verifier;
|
|
162
|
+
handler = vapiaiEventHandlerFactory();
|
|
163
|
+
configure = vapiaiEventHandlerConfigurerFactory(this.handler);
|
|
164
|
+
constructor(vapiAiWebhookServiceConfig) {
|
|
165
|
+
this._verifier = vapiAiWebhookEventVerifier(vapiAiWebhookServiceConfig.webhookConfig);
|
|
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);
|
|
179
|
+
}
|
|
180
|
+
const response = {
|
|
181
|
+
valid,
|
|
182
|
+
event,
|
|
183
|
+
...result
|
|
184
|
+
};
|
|
185
|
+
return response;
|
|
186
|
+
}
|
|
187
|
+
async updateForVapiAiEvent(event) {
|
|
188
|
+
const result = await this.handler(event);
|
|
189
|
+
if (!result.handled) {
|
|
190
|
+
this.logger.warn('Received unexpected/unhandled Vapi.ai event: ', event);
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
exports.VapiAiWebhookService = __decorate([common.Injectable(), __param(0, common.Inject(VapiAiWebhookServiceConfig)), __metadata("design:paramtypes", [VapiAiWebhookServiceConfig])], exports.VapiAiWebhookService);
|
|
196
|
+
|
|
197
|
+
exports.VapiAiWebhookController = class VapiAiWebhookController {
|
|
198
|
+
_vapiaiWebhookService;
|
|
199
|
+
constructor(vapiaiWebhookService) {
|
|
200
|
+
this._vapiaiWebhookService = vapiaiWebhookService;
|
|
201
|
+
}
|
|
202
|
+
async handleVapiAiWebhook(res, req, rawBody) {
|
|
203
|
+
const {
|
|
204
|
+
valid,
|
|
205
|
+
response: responseData
|
|
206
|
+
} = await this._vapiaiWebhookService.updateForWebhook(req, rawBody);
|
|
207
|
+
const response = res.status(200); // always return a 200 status code
|
|
208
|
+
if (valid && responseData) {
|
|
209
|
+
response.json(responseData);
|
|
210
|
+
} else {
|
|
211
|
+
response.json({});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
__decorate([common.Post(), __param(0, common.Res()), __param(1, common.Req()), __param(2, nestjs.RawBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, Object]), __metadata("design:returntype", Promise)], exports.VapiAiWebhookController.prototype, "handleVapiAiWebhook", null);
|
|
216
|
+
exports.VapiAiWebhookController = __decorate([common.Controller('/webhook/vapiai'), __param(0, common.Inject(exports.VapiAiWebhookService)), __metadata("design:paramtypes", [exports.VapiAiWebhookService])], exports.VapiAiWebhookController);
|
|
217
|
+
|
|
218
|
+
function vapiaiWebhookServiceConfigFactory(configService) {
|
|
219
|
+
const config = {
|
|
220
|
+
webhookConfig: {
|
|
221
|
+
secret: configService.get(VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR),
|
|
222
|
+
hmacSecret: configService.get(VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR),
|
|
223
|
+
verificationType: configService.get(VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR),
|
|
224
|
+
signaturePrefix: configService.get(VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR)
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
VapiAiWebhookServiceConfig.assertValidConfig(config);
|
|
228
|
+
return config;
|
|
229
|
+
}
|
|
230
|
+
exports.VapiAiWebhookModule = class VapiAiWebhookModule {};
|
|
231
|
+
exports.VapiAiWebhookModule = __decorate([common.Module({
|
|
232
|
+
imports: [config.ConfigModule],
|
|
233
|
+
controllers: [exports.VapiAiWebhookController],
|
|
234
|
+
providers: [{
|
|
235
|
+
provide: VapiAiWebhookServiceConfig,
|
|
236
|
+
inject: [config.ConfigService],
|
|
237
|
+
useFactory: vapiaiWebhookServiceConfigFactory
|
|
238
|
+
}, exports.VapiAiWebhookService],
|
|
239
|
+
exports: [exports.VapiAiWebhookService]
|
|
240
|
+
})], exports.VapiAiWebhookModule);
|
|
241
|
+
|
|
242
|
+
const VAPI_AI_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_SECRET_TOKEN';
|
|
243
|
+
/**
|
|
244
|
+
* Configuration for VapiAiService
|
|
245
|
+
*/
|
|
246
|
+
class VapiAiServiceConfig {
|
|
247
|
+
vapiai;
|
|
248
|
+
static assertValidConfig(config) {
|
|
249
|
+
if (!config.vapiai.config.token) {
|
|
250
|
+
throw new Error('No Vapi.ai secret/token specified.');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
exports.VapiAiApi = class VapiAiApi {
|
|
256
|
+
config;
|
|
257
|
+
vapiClient;
|
|
258
|
+
constructor(config) {
|
|
259
|
+
this.config = config;
|
|
260
|
+
this.vapiClient = new serverSdk.VapiClient(config.vapiai.config);
|
|
261
|
+
}
|
|
262
|
+
// MARK: Accessors
|
|
263
|
+
/**
|
|
264
|
+
* Gets a call by ID.
|
|
265
|
+
*
|
|
266
|
+
* @param callId
|
|
267
|
+
* @returns
|
|
268
|
+
*/
|
|
269
|
+
getCall(callId) {
|
|
270
|
+
return this.vapiClient.calls.get({
|
|
271
|
+
id: callId
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
exports.VapiAiApi = __decorate([common.Injectable(), __param(0, common.Inject(VapiAiServiceConfig)), __metadata("design:paramtypes", [VapiAiServiceConfig])], exports.VapiAiApi);
|
|
276
|
+
|
|
277
|
+
function vapiaiServiceConfigFactory(configService) {
|
|
278
|
+
const config = {
|
|
279
|
+
vapiai: {
|
|
280
|
+
config: {
|
|
281
|
+
token: configService.get(VAPI_AI_SECRET_TOKEN_ENV_VAR)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
VapiAiServiceConfig.assertValidConfig(config);
|
|
286
|
+
return config;
|
|
287
|
+
}
|
|
288
|
+
exports.VapiAiModule = class VapiAiModule {};
|
|
289
|
+
exports.VapiAiModule = __decorate([common.Module({
|
|
290
|
+
imports: [config.ConfigModule],
|
|
291
|
+
providers: [{
|
|
292
|
+
provide: VapiAiServiceConfig,
|
|
293
|
+
inject: [config.ConfigService],
|
|
294
|
+
useFactory: vapiaiServiceConfigFactory
|
|
295
|
+
}, exports.VapiAiApi],
|
|
296
|
+
exports: [exports.VapiAiApi]
|
|
297
|
+
})], exports.VapiAiModule);
|
|
298
|
+
|
|
299
|
+
exports.VAPI_AI_SECRET_TOKEN_ENV_VAR = VAPI_AI_SECRET_TOKEN_ENV_VAR;
|
|
300
|
+
exports.VapiAiServiceConfig = VapiAiServiceConfig;
|
|
301
|
+
exports.vapiAiWebhookEvent = vapiAiWebhookEvent;
|
|
302
|
+
exports.vapiAiWebhookEventVerifier = vapiAiWebhookEventVerifier;
|
|
303
|
+
exports.vapiaiEventHandlerConfigurerFactory = vapiaiEventHandlerConfigurerFactory;
|
|
304
|
+
exports.vapiaiEventHandlerFactory = vapiaiEventHandlerFactory;
|
|
305
|
+
exports.vapiaiServiceConfigFactory = vapiaiServiceConfigFactory;
|
|
306
|
+
exports.vapiaiWebhookServiceConfigFactory = vapiaiWebhookServiceConfigFactory;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { handlerFactory, handlerConfigurerFactory, handlerMappedSetFunctionFactory } from '@dereekb/util';
|
|
2
|
+
import { RawBody } from '@dereekb/nestjs';
|
|
3
|
+
import { Injectable, Inject, Logger, Post, Res, Req, Controller, Module } from '@nestjs/common';
|
|
4
|
+
import { createHmac } from 'crypto';
|
|
5
|
+
import { ConfigService, ConfigModule } from '@nestjs/config';
|
|
6
|
+
import { VapiClient } from '@vapi-ai/server-sdk';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a VapiAiWebhookEvent and treats the data as the input type.
|
|
10
|
+
*
|
|
11
|
+
* @param event
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
function vapiAiWebhookEvent(event) {
|
|
15
|
+
return event;
|
|
16
|
+
}
|
|
17
|
+
const vapiaiEventHandlerFactory = handlerFactory(x => x.type, {
|
|
18
|
+
defaultResult: {
|
|
19
|
+
handled: true,
|
|
20
|
+
response: undefined
|
|
21
|
+
},
|
|
22
|
+
negativeResult: {
|
|
23
|
+
handled: true,
|
|
24
|
+
response: undefined
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const vapiaiEventHandlerConfigurerFactory = handlerConfigurerFactory({
|
|
28
|
+
configurerForAccessor: accessor => {
|
|
29
|
+
// eslint-disable-next-line
|
|
30
|
+
const fnWithKey = handlerMappedSetFunctionFactory(accessor, vapiAiWebhookEvent);
|
|
31
|
+
const configurer = {
|
|
32
|
+
...accessor,
|
|
33
|
+
handleAssistantRequest: fnWithKey('assistant-request'),
|
|
34
|
+
handleStatusUpdate: fnWithKey('status-update'),
|
|
35
|
+
handleFunctionCall: fnWithKey('function-call'),
|
|
36
|
+
handleEndOfCallReport: fnWithKey('end-of-call-report'),
|
|
37
|
+
handleHang: fnWithKey('hang')
|
|
38
|
+
};
|
|
39
|
+
return configurer;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/******************************************************************************
|
|
44
|
+
Copyright (c) Microsoft Corporation.
|
|
45
|
+
|
|
46
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
47
|
+
purpose with or without fee is hereby granted.
|
|
48
|
+
|
|
49
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
50
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
51
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
52
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
53
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
54
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
55
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
56
|
+
***************************************************************************** */
|
|
57
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
function __decorate(decorators, target, key, desc) {
|
|
61
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
62
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
63
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
64
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function __param(paramIndex, decorator) {
|
|
68
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function __metadata(metadataKey, metadataValue) {
|
|
72
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
76
|
+
var e = new Error(message);
|
|
77
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Verifies a VapiAi webhook event header.
|
|
82
|
+
*
|
|
83
|
+
* @param vapiSecretTokenGetter The VapiAi secret token. The Vapi client allows for using an AsyncGetterOrValue type, so the verifier supports that as well.
|
|
84
|
+
* @returns A function that verifies a VapiAi webhook event.
|
|
85
|
+
*/
|
|
86
|
+
function vapiAiWebhookEventVerifier(config) {
|
|
87
|
+
const {
|
|
88
|
+
verificationType: inputVerificationType,
|
|
89
|
+
secret: inputSecret,
|
|
90
|
+
hmacSecret: inputHmacSecret,
|
|
91
|
+
signaturePrefix: inputSignaturePrefix
|
|
92
|
+
} = config;
|
|
93
|
+
const verificationType = inputVerificationType ?? (inputHmacSecret != null ? 'hmac' : 'secret'); // default to secret always, never default to none
|
|
94
|
+
const secretToken = (verificationType === 'hmac' ? inputHmacSecret ?? inputSecret : inputSecret) ?? '';
|
|
95
|
+
const signaturePrefix = inputSignaturePrefix ?? '';
|
|
96
|
+
function verifyNone(input) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
function verifySecret(input) {
|
|
100
|
+
const {
|
|
101
|
+
request
|
|
102
|
+
} = input;
|
|
103
|
+
const headers = request.headers;
|
|
104
|
+
const vapiSecret = headers['x-vapi-secret'];
|
|
105
|
+
const valid = vapiSecret === secretToken;
|
|
106
|
+
return valid;
|
|
107
|
+
}
|
|
108
|
+
function verifyHmac(input) {
|
|
109
|
+
const {
|
|
110
|
+
request,
|
|
111
|
+
requestBodyString
|
|
112
|
+
} = input;
|
|
113
|
+
const headers = request.headers;
|
|
114
|
+
const timestamp = headers['x-timestamp'];
|
|
115
|
+
const vapiSignature = headers['x-signature'];
|
|
116
|
+
const message = `${timestamp}.${requestBodyString}`;
|
|
117
|
+
const hashForVerify = createHmac('sha256', secretToken).update(message).digest('hex');
|
|
118
|
+
const signature = `${signaturePrefix}${hashForVerify}`;
|
|
119
|
+
const valid = vapiSignature === signature;
|
|
120
|
+
return valid;
|
|
121
|
+
}
|
|
122
|
+
const verify = verificationType === 'hmac' ? verifyHmac : verificationType === 'secret' ? verifySecret : verifyNone;
|
|
123
|
+
return async (request, rawBody) => {
|
|
124
|
+
const requestBodyString = String(request.body);
|
|
125
|
+
const valid = verify({
|
|
126
|
+
request,
|
|
127
|
+
requestBodyString
|
|
128
|
+
});
|
|
129
|
+
const requestBody = JSON.parse(requestBodyString);
|
|
130
|
+
const result = {
|
|
131
|
+
valid,
|
|
132
|
+
event: requestBody.message
|
|
133
|
+
};
|
|
134
|
+
return result;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_TOKEN';
|
|
139
|
+
const VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN';
|
|
140
|
+
const VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE';
|
|
141
|
+
const VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR = 'VAPI_AI_WEBHOOK_SIGNATURE_PREFIX';
|
|
142
|
+
/**
|
|
143
|
+
* Configuration for VapiAiService
|
|
144
|
+
*/
|
|
145
|
+
class VapiAiWebhookServiceConfig {
|
|
146
|
+
webhookConfig;
|
|
147
|
+
static assertValidConfig(config) {
|
|
148
|
+
if (!config.webhookConfig.secret && !config.webhookConfig.hmacSecret) {
|
|
149
|
+
throw new Error('No Vapi.ai webhook secret token specified.');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Service that makes system changes based on VapiAi webhook events.
|
|
156
|
+
*/
|
|
157
|
+
let VapiAiWebhookService = class VapiAiWebhookService {
|
|
158
|
+
logger = new Logger('VapiAiWebhookService');
|
|
159
|
+
_verifier;
|
|
160
|
+
handler = vapiaiEventHandlerFactory();
|
|
161
|
+
configure = vapiaiEventHandlerConfigurerFactory(this.handler);
|
|
162
|
+
constructor(vapiAiWebhookServiceConfig) {
|
|
163
|
+
this._verifier = vapiAiWebhookEventVerifier(vapiAiWebhookServiceConfig.webhookConfig);
|
|
164
|
+
}
|
|
165
|
+
async updateForWebhook(req, rawBody) {
|
|
166
|
+
const {
|
|
167
|
+
valid,
|
|
168
|
+
event
|
|
169
|
+
} = await this._verifier(req, rawBody);
|
|
170
|
+
let result = {
|
|
171
|
+
handled: false
|
|
172
|
+
};
|
|
173
|
+
if (!valid) {
|
|
174
|
+
this.logger.warn('Received invalid Vapi.ai event: ', event);
|
|
175
|
+
} else {
|
|
176
|
+
result = await this.updateForVapiAiEvent(event);
|
|
177
|
+
}
|
|
178
|
+
const response = {
|
|
179
|
+
valid,
|
|
180
|
+
event,
|
|
181
|
+
...result
|
|
182
|
+
};
|
|
183
|
+
return response;
|
|
184
|
+
}
|
|
185
|
+
async updateForVapiAiEvent(event) {
|
|
186
|
+
const result = await this.handler(event);
|
|
187
|
+
if (!result.handled) {
|
|
188
|
+
this.logger.warn('Received unexpected/unhandled Vapi.ai event: ', event);
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
VapiAiWebhookService = __decorate([Injectable(), __param(0, Inject(VapiAiWebhookServiceConfig)), __metadata("design:paramtypes", [VapiAiWebhookServiceConfig])], VapiAiWebhookService);
|
|
194
|
+
|
|
195
|
+
let VapiAiWebhookController = class VapiAiWebhookController {
|
|
196
|
+
_vapiaiWebhookService;
|
|
197
|
+
constructor(vapiaiWebhookService) {
|
|
198
|
+
this._vapiaiWebhookService = vapiaiWebhookService;
|
|
199
|
+
}
|
|
200
|
+
async handleVapiAiWebhook(res, req, rawBody) {
|
|
201
|
+
const {
|
|
202
|
+
valid,
|
|
203
|
+
response: responseData
|
|
204
|
+
} = await this._vapiaiWebhookService.updateForWebhook(req, rawBody);
|
|
205
|
+
const response = res.status(200); // always return a 200 status code
|
|
206
|
+
if (valid && responseData) {
|
|
207
|
+
response.json(responseData);
|
|
208
|
+
} else {
|
|
209
|
+
response.json({});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
__decorate([Post(), __param(0, Res()), __param(1, Req()), __param(2, RawBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, Object]), __metadata("design:returntype", Promise)], VapiAiWebhookController.prototype, "handleVapiAiWebhook", null);
|
|
214
|
+
VapiAiWebhookController = __decorate([Controller('/webhook/vapiai'), __param(0, Inject(VapiAiWebhookService)), __metadata("design:paramtypes", [VapiAiWebhookService])], VapiAiWebhookController);
|
|
215
|
+
|
|
216
|
+
function vapiaiWebhookServiceConfigFactory(configService) {
|
|
217
|
+
const config = {
|
|
218
|
+
webhookConfig: {
|
|
219
|
+
secret: configService.get(VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR),
|
|
220
|
+
hmacSecret: configService.get(VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR),
|
|
221
|
+
verificationType: configService.get(VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR),
|
|
222
|
+
signaturePrefix: configService.get(VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR)
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
VapiAiWebhookServiceConfig.assertValidConfig(config);
|
|
226
|
+
return config;
|
|
227
|
+
}
|
|
228
|
+
let VapiAiWebhookModule = class VapiAiWebhookModule {};
|
|
229
|
+
VapiAiWebhookModule = __decorate([Module({
|
|
230
|
+
imports: [ConfigModule],
|
|
231
|
+
controllers: [VapiAiWebhookController],
|
|
232
|
+
providers: [{
|
|
233
|
+
provide: VapiAiWebhookServiceConfig,
|
|
234
|
+
inject: [ConfigService],
|
|
235
|
+
useFactory: vapiaiWebhookServiceConfigFactory
|
|
236
|
+
}, VapiAiWebhookService],
|
|
237
|
+
exports: [VapiAiWebhookService]
|
|
238
|
+
})], VapiAiWebhookModule);
|
|
239
|
+
|
|
240
|
+
const VAPI_AI_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_SECRET_TOKEN';
|
|
241
|
+
/**
|
|
242
|
+
* Configuration for VapiAiService
|
|
243
|
+
*/
|
|
244
|
+
class VapiAiServiceConfig {
|
|
245
|
+
vapiai;
|
|
246
|
+
static assertValidConfig(config) {
|
|
247
|
+
if (!config.vapiai.config.token) {
|
|
248
|
+
throw new Error('No Vapi.ai secret/token specified.');
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
let VapiAiApi = class VapiAiApi {
|
|
254
|
+
config;
|
|
255
|
+
vapiClient;
|
|
256
|
+
constructor(config) {
|
|
257
|
+
this.config = config;
|
|
258
|
+
this.vapiClient = new VapiClient(config.vapiai.config);
|
|
259
|
+
}
|
|
260
|
+
// MARK: Accessors
|
|
261
|
+
/**
|
|
262
|
+
* Gets a call by ID.
|
|
263
|
+
*
|
|
264
|
+
* @param callId
|
|
265
|
+
* @returns
|
|
266
|
+
*/
|
|
267
|
+
getCall(callId) {
|
|
268
|
+
return this.vapiClient.calls.get({
|
|
269
|
+
id: callId
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
VapiAiApi = __decorate([Injectable(), __param(0, Inject(VapiAiServiceConfig)), __metadata("design:paramtypes", [VapiAiServiceConfig])], VapiAiApi);
|
|
274
|
+
|
|
275
|
+
function vapiaiServiceConfigFactory(configService) {
|
|
276
|
+
const config = {
|
|
277
|
+
vapiai: {
|
|
278
|
+
config: {
|
|
279
|
+
token: configService.get(VAPI_AI_SECRET_TOKEN_ENV_VAR)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
VapiAiServiceConfig.assertValidConfig(config);
|
|
284
|
+
return config;
|
|
285
|
+
}
|
|
286
|
+
let VapiAiModule = class VapiAiModule {};
|
|
287
|
+
VapiAiModule = __decorate([Module({
|
|
288
|
+
imports: [ConfigModule],
|
|
289
|
+
providers: [{
|
|
290
|
+
provide: VapiAiServiceConfig,
|
|
291
|
+
inject: [ConfigService],
|
|
292
|
+
useFactory: vapiaiServiceConfigFactory
|
|
293
|
+
}, VapiAiApi],
|
|
294
|
+
exports: [VapiAiApi]
|
|
295
|
+
})], VapiAiModule);
|
|
296
|
+
|
|
297
|
+
export { VAPI_AI_SECRET_TOKEN_ENV_VAR, VapiAiApi, VapiAiModule, VapiAiServiceConfig, VapiAiWebhookController, VapiAiWebhookModule, VapiAiWebhookService, vapiAiWebhookEvent, vapiAiWebhookEventVerifier, vapiaiEventHandlerConfigurerFactory, vapiaiEventHandlerFactory, vapiaiServiceConfigFactory, vapiaiWebhookServiceConfigFactory };
|
package/vapiai/package.json
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/nestjs/vapiai",
|
|
3
|
-
"version": "
|
|
4
|
-
"type": "commonjs",
|
|
5
|
-
"peerDependencies": {},
|
|
6
|
-
"dependencies": {},
|
|
3
|
+
"version": "13.0.0",
|
|
7
4
|
"types": "./src/index.d.ts",
|
|
8
|
-
"
|
|
5
|
+
"module": "./index.esm.js",
|
|
6
|
+
"main": "./index.cjs.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./src/index.d.ts",
|
|
10
|
+
"node": {
|
|
11
|
+
"require": "./index.cjs.js"
|
|
12
|
+
},
|
|
13
|
+
"browser": {
|
|
14
|
+
"require": "./index.cjs.js",
|
|
15
|
+
"import": "./index.esm.js"
|
|
16
|
+
},
|
|
17
|
+
"default": "./index.cjs.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@dereekb/date": "13.0.0",
|
|
22
|
+
"@dereekb/nestjs": "13.0.0",
|
|
23
|
+
"@dereekb/model": "13.0.0",
|
|
24
|
+
"@dereekb/rxjs": "13.0.0",
|
|
25
|
+
"@dereekb/util": "13.0.0",
|
|
26
|
+
"core-js": "^3.0.0"
|
|
27
|
+
}
|
|
9
28
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MaybeSo } from '@dereekb/util';
|
|
1
2
|
import { type Vapi } from '@vapi-ai/server-sdk';
|
|
2
3
|
/**
|
|
3
4
|
* Secret token used by Vapi.ai for making requests.
|
|
@@ -30,7 +31,7 @@ export type VapiApiWebhookEventVerificationType = 'none' | 'secret' | 'hmac';
|
|
|
30
31
|
/**
|
|
31
32
|
* Cost item used by Vapi.ai.
|
|
32
33
|
*/
|
|
33
|
-
export type VapiCostsItem = Vapi.ServerMessageEndOfCallReport
|
|
34
|
+
export type VapiCostsItem = MaybeSo<Vapi.ServerMessageEndOfCallReport['costs']>[number];
|
|
34
35
|
/**
|
|
35
36
|
* Vapi.ai Call identifier
|
|
36
37
|
*/
|
|
@@ -40,6 +41,7 @@ export type VapiCallId = string;
|
|
|
40
41
|
*/
|
|
41
42
|
export type VapiAssistantId = string;
|
|
42
43
|
export type VapiTranscript = string;
|
|
44
|
+
export type VapiChatMessage = MaybeSo<Vapi.Chat['messages']>[number];
|
|
43
45
|
export interface VapiTranscriptRef {
|
|
44
46
|
transcript?: VapiTranscript;
|
|
45
47
|
}
|