@dereekb/nestjs 12.1.13 → 12.2.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/CHANGELOG.md +13 -0
- package/mailgun/package.json +1 -1
- package/package.json +7 -1
- package/stripe/package.json +1 -1
- package/stripe/src/lib/webhook/webhook.stripe.d.ts +2 -2
- package/stripe/src/lib/webhook/webhook.stripe.service.d.ts +1 -1
- package/vapiai/LICENSE +21 -0
- package/vapiai/package.json +9 -0
- package/vapiai/src/index.d.ts +1 -0
- package/vapiai/src/index.js +5 -0
- package/vapiai/src/index.js.map +1 -0
- package/vapiai/src/lib/index.d.ts +6 -0
- package/vapiai/src/lib/index.js +10 -0
- package/vapiai/src/lib/index.js.map +1 -0
- package/vapiai/src/lib/vapiai.api.d.ts +7 -0
- package/vapiai/src/lib/vapiai.api.js +22 -0
- package/vapiai/src/lib/vapiai.api.js.map +1 -0
- package/vapiai/src/lib/vapiai.config.d.ts +12 -0
- package/vapiai/src/lib/vapiai.config.js +17 -0
- package/vapiai/src/lib/vapiai.config.js.map +1 -0
- package/vapiai/src/lib/vapiai.module.d.ts +5 -0
- package/vapiai/src/lib/vapiai.module.js +38 -0
- package/vapiai/src/lib/vapiai.module.js.map +1 -0
- package/vapiai/src/lib/vapiai.type.d.ts +37 -0
- package/vapiai/src/lib/vapiai.type.js +3 -0
- package/vapiai/src/lib/vapiai.type.js.map +1 -0
- package/vapiai/src/lib/webhook/index.d.ts +6 -0
- package/vapiai/src/lib/webhook/index.js +10 -0
- package/vapiai/src/lib/webhook/index.js.map +1 -0
- package/vapiai/src/lib/webhook/webhook.vapi.config.d.ts +13 -0
- package/vapiai/src/lib/webhook/webhook.vapi.config.js +20 -0
- package/vapiai/src/lib/webhook/webhook.vapi.config.js.map +1 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.controller.d.ts +8 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.controller.js +38 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.controller.js.map +1 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.d.ts +50 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.js +44 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.js.map +1 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.module.d.ts +5 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.module.js +41 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.module.js.map +1 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.service.d.ts +20 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.service.js +52 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.service.js.map +1 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.types.d.ts +134 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.types.js +21 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.types.js.map +1 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.verify.d.ts +45 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.verify.js +49 -0
- package/vapiai/src/lib/webhook/webhook.vapiai.verify.js.map +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
# [12.2.0](https://github.com/dereekb/dbx-components/compare/v12.1.14-dev...v12.2.0) (2025-06-29)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* added vapi.ai integration ([c06f5e8](https://github.com/dereekb/dbx-components/commit/c06f5e886369ad5da2712b667346b5cbf7161845))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [12.1.14](https://github.com/dereekb/dbx-components/compare/v12.1.13-dev...v12.1.14) (2025-06-27)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
5
18
|
## [12.1.13](https://github.com/dereekb/dbx-components/compare/v12.1.12-dev...v12.1.13) (2025-06-23)
|
|
6
19
|
|
|
7
20
|
|
package/mailgun/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/nestjs",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.2.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
"main": "./mailgun/src/index.js",
|
|
21
21
|
"require": "./mailgun/src/index.js",
|
|
22
22
|
"default": "./mailgun/src/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./vapiai": {
|
|
25
|
+
"types": "./vapiai/src/index.d.ts",
|
|
26
|
+
"main": "./vapiai/src/index.js",
|
|
27
|
+
"require": "./vapiai/src/index.js",
|
|
28
|
+
"default": "./vapiai/src/index.js"
|
|
23
29
|
}
|
|
24
30
|
},
|
|
25
31
|
"main": "./src/index.js",
|
package/stripe/package.json
CHANGED
|
@@ -42,7 +42,7 @@ export type StripeCheckoutSessionEventDataObject = Stripe.TypedEventDataObject<S
|
|
|
42
42
|
export type StripeCustomerSubscriptionEventDataObject = Stripe.TypedEventDataObject<Stripe.Subscription>;
|
|
43
43
|
export type StripeSubscriptionScheduleEventDataObject = Stripe.TypedEventDataObject<Stripe.SubscriptionSchedule>;
|
|
44
44
|
export type StripeEventHandler = Handler<Stripe.Event, string>;
|
|
45
|
-
export declare const stripeEventHandlerFactory: import("@dereekb/util").HandlerFactory<Stripe.Event, string>;
|
|
45
|
+
export declare const stripeEventHandlerFactory: import("@dereekb/util").HandlerFactory<Stripe.Event, string, boolean>;
|
|
46
46
|
export type StripeHandlerMappedSetFunction<T> = HandlerMappedSetFunction<StripeWebhookEvent<T>>;
|
|
47
47
|
export interface StripeEventHandlerConfigurer extends HandlerBindAccessor<Stripe.Event, string> {
|
|
48
48
|
readonly handleCheckoutSessionComplete: StripeHandlerMappedSetFunction<StripeCheckoutSessionEventDataObject>;
|
|
@@ -59,4 +59,4 @@ export interface StripeEventHandlerConfigurer extends HandlerBindAccessor<Stripe
|
|
|
59
59
|
readonly handleSubscriptionScheduleReleased: StripeHandlerMappedSetFunction<StripeSubscriptionScheduleEventDataObject>;
|
|
60
60
|
readonly handleSubscriptionScheduleUpdated: StripeHandlerMappedSetFunction<StripeSubscriptionScheduleEventDataObject>;
|
|
61
61
|
}
|
|
62
|
-
export declare const stripeEventHandlerConfigurerFactory: import("@dereekb/util").HandlerConfigurerFactory<StripeEventHandlerConfigurer, Stripe.Event, string>;
|
|
62
|
+
export declare const stripeEventHandlerConfigurerFactory: import("@dereekb/util").HandlerConfigurerFactory<StripeEventHandlerConfigurer, Stripe.Event, string, boolean>;
|
|
@@ -9,7 +9,7 @@ export declare class StripeWebhookService {
|
|
|
9
9
|
private readonly logger;
|
|
10
10
|
private readonly _stripeApi;
|
|
11
11
|
readonly handler: Handler<Stripe.Event>;
|
|
12
|
-
readonly configure: import("@dereekb/util").HandlerConfigurer<import("./webhook.stripe").StripeEventHandlerConfigurer, Stripe.Event, string>;
|
|
12
|
+
readonly configure: import("@dereekb/util").HandlerConfigurer<import("./webhook.stripe").StripeEventHandlerConfigurer, Stripe.Event, string, boolean>;
|
|
13
13
|
constructor(stripeApi: StripeApi);
|
|
14
14
|
updateForWebhook(req: Request, rawBody: Buffer): Promise<boolean>;
|
|
15
15
|
updateForStripeEvent(event: Stripe.Event): Promise<boolean>;
|
package/vapiai/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Hapier Creative LLC.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/nestjs/vapiai/src/index.ts"],"names":[],"mappings":";;;AAAA,gDAAsB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./webhook"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./vapiai.module"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./vapiai.api"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./vapiai.module"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./vapiai.config"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./vapiai.type"), exports);
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/nestjs/vapiai/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,oDAA0B;AAC1B,0DAAgC;AAChC,uDAA6B;AAC7B,0DAAgC;AAChC,0DAAgC;AAChC,wDAA8B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiAiApi = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const server_sdk_1 = require("@vapi-ai/server-sdk");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const vapiai_config_1 = require("./vapiai.config");
|
|
8
|
+
let VapiAiApi = class VapiAiApi {
|
|
9
|
+
config;
|
|
10
|
+
vapiClient;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.vapiClient = new server_sdk_1.VapiClient(config.vapiai.config);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
exports.VapiAiApi = VapiAiApi;
|
|
17
|
+
exports.VapiAiApi = VapiAiApi = tslib_1.__decorate([
|
|
18
|
+
(0, common_1.Injectable)(),
|
|
19
|
+
tslib_1.__param(0, (0, common_1.Inject)(vapiai_config_1.VapiAiServiceConfig)),
|
|
20
|
+
tslib_1.__metadata("design:paramtypes", [vapiai_config_1.VapiAiServiceConfig])
|
|
21
|
+
], VapiAiApi);
|
|
22
|
+
//# sourceMappingURL=vapiai.api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vapiai.api.js","sourceRoot":"","sources":["../../../../../../packages/nestjs/vapiai/src/lib/vapiai.api.ts"],"names":[],"mappings":";;;;AAAA,oDAAiD;AACjD,2CAAoD;AACpD,mDAAsD;AAG/C,IAAM,SAAS,GAAf,MAAM,SAAS;IAG8B;IAFzC,UAAU,CAAa;IAEhC,YAAkD,MAA2B;QAA3B,WAAM,GAAN,MAAM,CAAqB;QAC3E,IAAI,CAAC,UAAU,GAAG,IAAI,uBAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;CACF,CAAA;AANY,8BAAS;oBAAT,SAAS;IADrB,IAAA,mBAAU,GAAE;IAIE,mBAAA,IAAA,eAAM,EAAC,mCAAmB,CAAC,CAAA;6CAAkB,mCAAmB;GAHlE,SAAS,CAMrB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { VapiClient } from '@vapi-ai/server-sdk';
|
|
2
|
+
export declare const VAPI_AI_SECRET_TOKEN_ENV_VAR = "VAPI_AI_SECRET_TOKEN";
|
|
3
|
+
export interface VapiAiServiceApiConfig {
|
|
4
|
+
readonly config: VapiClient.Options;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for VapiAiService
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class VapiAiServiceConfig {
|
|
10
|
+
readonly vapiai: VapiAiServiceApiConfig;
|
|
11
|
+
static assertValidConfig(config: VapiAiServiceConfig): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiAiServiceConfig = exports.VAPI_AI_SECRET_TOKEN_ENV_VAR = void 0;
|
|
4
|
+
exports.VAPI_AI_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_SECRET_TOKEN';
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for VapiAiService
|
|
7
|
+
*/
|
|
8
|
+
class VapiAiServiceConfig {
|
|
9
|
+
vapiai;
|
|
10
|
+
static assertValidConfig(config) {
|
|
11
|
+
if (!config.vapiai.config.token) {
|
|
12
|
+
throw new Error('No Vapi.ai secret/token specified.');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.VapiAiServiceConfig = VapiAiServiceConfig;
|
|
17
|
+
//# sourceMappingURL=vapiai.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vapiai.config.js","sourceRoot":"","sources":["../../../../../../packages/nestjs/vapiai/src/lib/vapiai.config.ts"],"names":[],"mappings":";;;AAEa,QAAA,4BAA4B,GAAG,sBAAsB,CAAC;AAMnE;;GAEG;AACH,MAAsB,mBAAmB;IAC9B,MAAM,CAA0B;IAEzC,MAAM,CAAC,iBAAiB,CAAC,MAA2B;QAClD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;CACF;AARD,kDAQC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiAiModule = void 0;
|
|
4
|
+
exports.vapiaiServiceConfigFactory = vapiaiServiceConfigFactory;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const config_1 = require("@nestjs/config");
|
|
8
|
+
const vapiai_api_1 = require("./vapiai.api");
|
|
9
|
+
const vapiai_config_1 = require("./vapiai.config");
|
|
10
|
+
function vapiaiServiceConfigFactory(configService) {
|
|
11
|
+
const config = {
|
|
12
|
+
vapiai: {
|
|
13
|
+
config: {
|
|
14
|
+
token: configService.get(vapiai_config_1.VAPI_AI_SECRET_TOKEN_ENV_VAR)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
vapiai_config_1.VapiAiServiceConfig.assertValidConfig(config);
|
|
19
|
+
return config;
|
|
20
|
+
}
|
|
21
|
+
let VapiAiModule = class VapiAiModule {
|
|
22
|
+
};
|
|
23
|
+
exports.VapiAiModule = VapiAiModule;
|
|
24
|
+
exports.VapiAiModule = VapiAiModule = tslib_1.__decorate([
|
|
25
|
+
(0, common_1.Module)({
|
|
26
|
+
imports: [config_1.ConfigModule],
|
|
27
|
+
providers: [
|
|
28
|
+
{
|
|
29
|
+
provide: vapiai_config_1.VapiAiServiceConfig,
|
|
30
|
+
inject: [config_1.ConfigService],
|
|
31
|
+
useFactory: vapiaiServiceConfigFactory
|
|
32
|
+
},
|
|
33
|
+
vapiai_api_1.VapiAiApi
|
|
34
|
+
],
|
|
35
|
+
exports: [vapiai_api_1.VapiAiApi]
|
|
36
|
+
})
|
|
37
|
+
], VapiAiModule);
|
|
38
|
+
//# sourceMappingURL=vapiai.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vapiai.module.js","sourceRoot":"","sources":["../../../../../../packages/nestjs/vapiai/src/lib/vapiai.module.ts"],"names":[],"mappings":";;;AAMA,gEAWC;;AAjBD,2CAAwC;AACxC,2CAA6D;AAC7D,6CAAyC;AACzC,mDAAoF;AAGpF,SAAgB,0BAA0B,CAAC,aAA4B;IACrE,MAAM,MAAM,GAAwB;QAClC,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,KAAK,EAAE,aAAa,CAAC,GAAG,CAAoB,4CAA4B,CAAsB;aAC/F;SACF;KACF,CAAC;IAEF,mCAAmB,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,MAAM,CAAC;AAChB,CAAC;AAcM,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IAZxB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,qBAAY,CAAC;QACvB,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,mCAAmB;gBAC5B,MAAM,EAAE,CAAC,sBAAa,CAAC;gBACvB,UAAU,EAAE,0BAA0B;aACvC;YACD,sBAAS;SACV;QACD,OAAO,EAAE,CAAC,sBAAS,CAAC;KACrB,CAAC;GACW,YAAY,CAAG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ChatCostsItem, CallCostsItem, ServerMessageEndOfCallReportCostsItem } from '@vapi-ai/server-sdk/api';
|
|
2
|
+
/**
|
|
3
|
+
* Secret token used by Vapi.ai for making requests.
|
|
4
|
+
*/
|
|
5
|
+
export type VapiAiSecretToken = string;
|
|
6
|
+
/**
|
|
7
|
+
* Secret token used by Vapi.ai for validating webhook events.
|
|
8
|
+
*/
|
|
9
|
+
export type VapiAiWebhookSecretToken = string;
|
|
10
|
+
/**
|
|
11
|
+
* Type of verification to use for validating webhook events.
|
|
12
|
+
*
|
|
13
|
+
* none:
|
|
14
|
+
* - no verification is performed
|
|
15
|
+
*
|
|
16
|
+
* secret:
|
|
17
|
+
* - uses the x-vapi-secret header to verify the webhook event by comparing it to the secret
|
|
18
|
+
*
|
|
19
|
+
* hmac:
|
|
20
|
+
* - uses a secret key along with HMAC to verify the webhook event. Requires configuration!
|
|
21
|
+
* - must configure the hmac setup in the Vapi.ai console at https://dashboard.vapi.ai/settings/integrations
|
|
22
|
+
* -- supply a secret token, but keep all other settings as default
|
|
23
|
+
* --- defaults:
|
|
24
|
+
* ---- signature header: x-signature
|
|
25
|
+
* ---- timestamp header: x-timestamp
|
|
26
|
+
* ---- payload format: {timestamp}.{body}
|
|
27
|
+
* ---- signature encoding: hex
|
|
28
|
+
*/
|
|
29
|
+
export type VapiApiWebhookEventVerificationType = 'none' | 'secret' | 'hmac';
|
|
30
|
+
/**
|
|
31
|
+
* Cost item used by Vapi.ai.
|
|
32
|
+
*/
|
|
33
|
+
export type VapiCostsItem = ChatCostsItem | CallCostsItem | ServerMessageEndOfCallReportCostsItem;
|
|
34
|
+
/**
|
|
35
|
+
* Assistant id used by Vapi.ai.
|
|
36
|
+
*/
|
|
37
|
+
export type VapiAssistantId = string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vapiai.type.js","sourceRoot":"","sources":["../../../../../../packages/nestjs/vapiai/src/lib/vapiai.type.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./webhook.vapiai"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./webhook.vapiai.controller"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./webhook.vapiai.module"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./webhook.vapiai.service"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./webhook.vapiai.types"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./webhook.vapiai.verify"), exports);
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/index.ts"],"names":[],"mappings":";;;AAAA,2DAAiC;AACjC,sEAA4C;AAC5C,kEAAwC;AACxC,mEAAyC;AACzC,iEAAuC;AACvC,kEAAwC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { VapiApiWebhookEventVerificationConfig } from './webhook.vapiai.verify';
|
|
2
|
+
export declare const VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR = "VAPI_AI_WEBHOOK_SECRET_TOKEN";
|
|
3
|
+
export declare const VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR = "VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN";
|
|
4
|
+
export declare const VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR = "VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE";
|
|
5
|
+
export declare const VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR = "VAPI_AI_WEBHOOK_SIGNATURE_PREFIX";
|
|
6
|
+
export type VapiAiWebhookConfig = VapiApiWebhookEventVerificationConfig;
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for VapiAiService
|
|
9
|
+
*/
|
|
10
|
+
export declare abstract class VapiAiWebhookServiceConfig {
|
|
11
|
+
readonly webhookConfig: VapiAiWebhookConfig;
|
|
12
|
+
static assertValidConfig(config: VapiAiWebhookServiceConfig): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiAiWebhookServiceConfig = exports.VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR = exports.VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR = exports.VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR = exports.VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR = void 0;
|
|
4
|
+
exports.VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_TOKEN';
|
|
5
|
+
exports.VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR = 'VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN';
|
|
6
|
+
exports.VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR = 'VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE';
|
|
7
|
+
exports.VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR = 'VAPI_AI_WEBHOOK_SIGNATURE_PREFIX';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for VapiAiService
|
|
10
|
+
*/
|
|
11
|
+
class VapiAiWebhookServiceConfig {
|
|
12
|
+
webhookConfig;
|
|
13
|
+
static assertValidConfig(config) {
|
|
14
|
+
if (!config.webhookConfig.secret && !config.webhookConfig.hmacSecret) {
|
|
15
|
+
throw new Error('No Vapi.ai webhook secret token specified.');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.VapiAiWebhookServiceConfig = VapiAiWebhookServiceConfig;
|
|
20
|
+
//# sourceMappingURL=webhook.vapi.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.vapi.config.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/webhook.vapi.config.ts"],"names":[],"mappings":";;;AAEa,QAAA,oCAAoC,GAAG,8BAA8B,CAAC;AACtE,QAAA,yCAAyC,GAAG,mCAAmC,CAAC;AAChF,QAAA,gDAAgD,GAAG,0CAA0C,CAAC;AAC9F,QAAA,wCAAwC,GAAG,kCAAkC,CAAC;AAI3F;;GAEG;AACH,MAAsB,0BAA0B;IACrC,aAAa,CAAuB;IAE7C,MAAM,CAAC,iBAAiB,CAAC,MAAkC;QACzD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;YACrE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;CACF;AARD,gEAQC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RawBodyBuffer } from '@dereekb/nestjs';
|
|
2
|
+
import { Request, Response } from 'express';
|
|
3
|
+
import { VapiAiWebhookService } from './webhook.vapiai.service';
|
|
4
|
+
export declare class VapiAiWebhookController {
|
|
5
|
+
private readonly _vapiaiWebhookService;
|
|
6
|
+
constructor(vapiaiWebhookService: VapiAiWebhookService);
|
|
7
|
+
handleVapiAiWebhook(res: Response, req: Request, rawBody: RawBodyBuffer): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiAiWebhookController = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const nestjs_1 = require("@dereekb/nestjs");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const webhook_vapiai_service_1 = require("./webhook.vapiai.service");
|
|
8
|
+
let VapiAiWebhookController = class VapiAiWebhookController {
|
|
9
|
+
_vapiaiWebhookService;
|
|
10
|
+
constructor(vapiaiWebhookService) {
|
|
11
|
+
this._vapiaiWebhookService = vapiaiWebhookService;
|
|
12
|
+
}
|
|
13
|
+
async handleVapiAiWebhook(res, req, rawBody) {
|
|
14
|
+
const { valid, response: responseData } = await this._vapiaiWebhookService.updateForWebhook(req, rawBody);
|
|
15
|
+
const response = res.status(200); // always return a 200 status code
|
|
16
|
+
if (valid && responseData) {
|
|
17
|
+
response.json(responseData);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
response.json({});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
exports.VapiAiWebhookController = VapiAiWebhookController;
|
|
25
|
+
tslib_1.__decorate([
|
|
26
|
+
(0, common_1.Post)(),
|
|
27
|
+
tslib_1.__param(0, (0, common_1.Res)()),
|
|
28
|
+
tslib_1.__param(1, (0, common_1.Req)()),
|
|
29
|
+
tslib_1.__param(2, (0, nestjs_1.RawBody)()),
|
|
30
|
+
tslib_1.__metadata("design:type", Function),
|
|
31
|
+
tslib_1.__metadata("design:paramtypes", [Object, Object, Object]),
|
|
32
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
33
|
+
], VapiAiWebhookController.prototype, "handleVapiAiWebhook", null);
|
|
34
|
+
exports.VapiAiWebhookController = VapiAiWebhookController = tslib_1.__decorate([
|
|
35
|
+
(0, common_1.Controller)('/webhook/vapiai'),
|
|
36
|
+
tslib_1.__metadata("design:paramtypes", [webhook_vapiai_service_1.VapiAiWebhookService])
|
|
37
|
+
], VapiAiWebhookController);
|
|
38
|
+
//# sourceMappingURL=webhook.vapiai.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.vapiai.controller.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/webhook.vapiai.controller.ts"],"names":[],"mappings":";;;;AAAA,4CAAyD;AACzD,2CAA4D;AAE5D,qEAAgE;AAGzD,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IACjB,qBAAqB,CAAuB;IAE7D,YAAY,oBAA0C;QACpD,IAAI,CAAC,qBAAqB,GAAG,oBAAoB,CAAC;IACpD,CAAC;IAGK,AAAN,KAAK,CAAC,mBAAmB,CAAQ,GAAa,EAAS,GAAY,EAAa,OAAsB;QACpG,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE1G,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,kCAAkC;QAEpE,IAAI,KAAK,IAAI,YAAY,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;CACF,CAAA;AAnBY,0DAAuB;AAQ5B;IADL,IAAA,aAAI,GAAE;IACoB,mBAAA,IAAA,YAAG,GAAE,CAAA;IAAiB,mBAAA,IAAA,YAAG,GAAE,CAAA;IAAgB,mBAAA,IAAA,gBAAO,GAAE,CAAA;;;;kEAU9E;kCAlBU,uBAAuB;IADnC,IAAA,mBAAU,EAAC,iBAAiB,CAAC;6CAIM,6CAAoB;GAH3C,uBAAuB,CAmBnC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { HandlerBindAccessor, HandlerMappedSetFunction, Handler, Maybe } from '@dereekb/util';
|
|
2
|
+
import '../vapiai.type';
|
|
3
|
+
import { AssistantRequestPayload, EndOfCallReportPayload, FunctionCallPayload, HangPayload, SpeechUpdatePayload, StatusUpdatePayload, TranscriptPayload, VapiPayload, VapiResponse, VapiWebhookEnum } from './webhook.vapiai.types';
|
|
4
|
+
export type VapiAiWebhookEventType = VapiWebhookEnum | string;
|
|
5
|
+
export interface VapiAiWebhookResult {
|
|
6
|
+
readonly handled: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Response to return to the vapi server.
|
|
9
|
+
*/
|
|
10
|
+
readonly response?: VapiResponse;
|
|
11
|
+
}
|
|
12
|
+
export interface RawVapiAiWebhookEvent {
|
|
13
|
+
readonly message: UntypedVapiAiWebhookEvent;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A parsed VapiWebhookEventType that contains the relevant data and the original event.
|
|
17
|
+
*/
|
|
18
|
+
export type VapiAiWebhookEvent<T extends VapiPayload = VapiPayload, ET extends VapiAiWebhookEventType = VapiAiWebhookEventType> = T & {
|
|
19
|
+
/**
|
|
20
|
+
* The event type
|
|
21
|
+
*/
|
|
22
|
+
readonly type: ET;
|
|
23
|
+
};
|
|
24
|
+
export type UntypedVapiAiWebhookEvent = VapiAiWebhookEvent;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a ZoomWebhookEvent and treats the data as the input type.
|
|
27
|
+
*
|
|
28
|
+
* @param event
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
export declare function vapiAiWebhookEvent<T extends VapiPayload>(event: UntypedVapiAiWebhookEvent): VapiAiWebhookEvent<T>;
|
|
32
|
+
export type VapiAiEventHandler = Handler<UntypedVapiAiWebhookEvent, VapiAiWebhookEventType>;
|
|
33
|
+
export declare const vapiaiEventHandlerFactory: import("@dereekb/util").HandlerFactory<UntypedVapiAiWebhookEvent, string, VapiAiWebhookResult>;
|
|
34
|
+
export type VapiAiHandlerMappedSetFunction<T extends VapiPayload> = HandlerMappedSetFunction<VapiAiWebhookEvent<T>, Maybe<VapiAiWebhookResult>>;
|
|
35
|
+
export interface VapiAiEventHandlerConfigurer extends HandlerBindAccessor<UntypedVapiAiWebhookEvent, VapiAiWebhookEventType, VapiAiWebhookResult> {
|
|
36
|
+
readonly handleAssistantRequest: VapiAiHandlerMappedSetFunction<AssistantRequestPayload>;
|
|
37
|
+
readonly handleStatusUpdate: VapiAiHandlerMappedSetFunction<StatusUpdatePayload>;
|
|
38
|
+
readonly handleFunctionCall: VapiAiHandlerMappedSetFunction<FunctionCallPayload>;
|
|
39
|
+
readonly handleEndOfCallReport: VapiAiHandlerMappedSetFunction<EndOfCallReportPayload>;
|
|
40
|
+
readonly handleHang: VapiAiHandlerMappedSetFunction<HangPayload>;
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated
|
|
43
|
+
*/
|
|
44
|
+
readonly handleSpeechUpdate: VapiAiHandlerMappedSetFunction<SpeechUpdatePayload>;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated
|
|
47
|
+
*/
|
|
48
|
+
readonly handleTranscript: VapiAiHandlerMappedSetFunction<TranscriptPayload>;
|
|
49
|
+
}
|
|
50
|
+
export declare const vapiaiEventHandlerConfigurerFactory: import("@dereekb/util").HandlerConfigurerFactory<VapiAiEventHandlerConfigurer, UntypedVapiAiWebhookEvent, string, VapiAiWebhookResult>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vapiaiEventHandlerConfigurerFactory = exports.vapiaiEventHandlerFactory = void 0;
|
|
4
|
+
exports.vapiAiWebhookEvent = vapiAiWebhookEvent;
|
|
5
|
+
const util_1 = require("@dereekb/util");
|
|
6
|
+
require("../vapiai.type");
|
|
7
|
+
const webhook_vapiai_types_1 = require("./webhook.vapiai.types");
|
|
8
|
+
/**
|
|
9
|
+
* Creates a ZoomWebhookEvent and treats the data as the input type.
|
|
10
|
+
*
|
|
11
|
+
* @param event
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
function vapiAiWebhookEvent(event) {
|
|
15
|
+
return event;
|
|
16
|
+
}
|
|
17
|
+
exports.vapiaiEventHandlerFactory = (0, util_1.handlerFactory)((x) => x.type, {
|
|
18
|
+
defaultResult: {
|
|
19
|
+
handled: true,
|
|
20
|
+
response: undefined
|
|
21
|
+
},
|
|
22
|
+
negativeResult: {
|
|
23
|
+
handled: true,
|
|
24
|
+
response: undefined
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
exports.vapiaiEventHandlerConfigurerFactory = (0, util_1.handlerConfigurerFactory)({
|
|
28
|
+
configurerForAccessor: (accessor) => {
|
|
29
|
+
// eslint-disable-next-line
|
|
30
|
+
const fnWithKey = (0, util_1.handlerMappedSetFunctionFactory)(accessor, vapiAiWebhookEvent);
|
|
31
|
+
const configurer = {
|
|
32
|
+
...accessor,
|
|
33
|
+
handleAssistantRequest: fnWithKey(webhook_vapiai_types_1.VapiWebhookEnum.ASSISTANT_REQUEST),
|
|
34
|
+
handleStatusUpdate: fnWithKey(webhook_vapiai_types_1.VapiWebhookEnum.STATUS_UPDATE),
|
|
35
|
+
handleFunctionCall: fnWithKey(webhook_vapiai_types_1.VapiWebhookEnum.FUNCTION_CALL),
|
|
36
|
+
handleEndOfCallReport: fnWithKey(webhook_vapiai_types_1.VapiWebhookEnum.END_OF_CALL_REPORT),
|
|
37
|
+
handleHang: fnWithKey(webhook_vapiai_types_1.VapiWebhookEnum.HANG),
|
|
38
|
+
handleSpeechUpdate: fnWithKey(webhook_vapiai_types_1.VapiWebhookEnum.SPEECH_UPDATE),
|
|
39
|
+
handleTranscript: fnWithKey(webhook_vapiai_types_1.VapiWebhookEnum.TRANSCRIPT)
|
|
40
|
+
};
|
|
41
|
+
return configurer;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=webhook.vapiai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.vapiai.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/webhook.vapiai.ts"],"names":[],"mappings":";;;AAoCA,gDAEC;AAtCD,wCAAyK;AACzK,0BAAwB;AACxB,iEAAoO;AA4BpO;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAwB,KAAgC;IACxF,OAAO,KAA8B,CAAC;AACxC,CAAC;AAIY,QAAA,yBAAyB,GAAG,IAAA,qBAAc,EAAyE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;IAC7I,aAAa,EAAE;QACb,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,SAAS;KACpB;IACD,cAAc,EAAE;QACd,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,SAAS;KACpB;CACF,CAAC,CAAC;AAoBU,QAAA,mCAAmC,GAAG,IAAA,+BAAwB,EAAuG;IAChL,qBAAqB,EAAE,CAAC,QAAqG,EAAE,EAAE;QAC/H,2BAA2B;QAC3B,MAAM,SAAS,GAAG,IAAA,sCAA+B,EAAmF,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QAElK,MAAM,UAAU,GAAiC;YAC/C,GAAG,QAAQ;YACX,sBAAsB,EAAE,SAAS,CAAC,sCAAe,CAAC,iBAAiB,CAAC;YACpE,kBAAkB,EAAE,SAAS,CAAC,sCAAe,CAAC,aAAa,CAAC;YAC5D,kBAAkB,EAAE,SAAS,CAAC,sCAAe,CAAC,aAAa,CAAC;YAC5D,qBAAqB,EAAE,SAAS,CAAC,sCAAe,CAAC,kBAAkB,CAAC;YACpE,UAAU,EAAE,SAAS,CAAC,sCAAe,CAAC,IAAI,CAAC;YAC3C,kBAAkB,EAAE,SAAS,CAAC,sCAAe,CAAC,aAAa,CAAC;YAC5D,gBAAgB,EAAE,SAAS,CAAC,sCAAe,CAAC,UAAU,CAAC;SACxD,CAAC;QAEF,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { VapiAiWebhookServiceConfig } from './webhook.vapi.config';
|
|
2
|
+
import { ConfigService } from '@nestjs/config';
|
|
3
|
+
export declare function vapiaiWebhookServiceConfigFactory(configService: ConfigService): VapiAiWebhookServiceConfig;
|
|
4
|
+
export declare class VapiAiWebhookModule {
|
|
5
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiAiWebhookModule = void 0;
|
|
4
|
+
exports.vapiaiWebhookServiceConfigFactory = vapiaiWebhookServiceConfigFactory;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const webhook_vapiai_controller_1 = require("./webhook.vapiai.controller");
|
|
7
|
+
const common_1 = require("@nestjs/common");
|
|
8
|
+
const webhook_vapiai_service_1 = require("./webhook.vapiai.service");
|
|
9
|
+
const webhook_vapi_config_1 = require("./webhook.vapi.config");
|
|
10
|
+
const config_1 = require("@nestjs/config");
|
|
11
|
+
function vapiaiWebhookServiceConfigFactory(configService) {
|
|
12
|
+
const config = {
|
|
13
|
+
webhookConfig: {
|
|
14
|
+
secret: configService.get(webhook_vapi_config_1.VAPI_AI_WEBHOOK_SECRET_TOKEN_ENV_VAR),
|
|
15
|
+
hmacSecret: configService.get(webhook_vapi_config_1.VAPI_AI_WEBHOOK_HMAC_SECRET_TOKEN_ENV_VAR),
|
|
16
|
+
verificationType: configService.get(webhook_vapi_config_1.VAPI_AI_WEBHOOK_SECRET_VERIFICATION_TYPE_ENV_VAR),
|
|
17
|
+
signaturePrefix: configService.get(webhook_vapi_config_1.VAPI_AI_WEBHOOK_SIGNATURE_PREFIX_ENV_VAR)
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
webhook_vapi_config_1.VapiAiWebhookServiceConfig.assertValidConfig(config);
|
|
21
|
+
return config;
|
|
22
|
+
}
|
|
23
|
+
let VapiAiWebhookModule = class VapiAiWebhookModule {
|
|
24
|
+
};
|
|
25
|
+
exports.VapiAiWebhookModule = VapiAiWebhookModule;
|
|
26
|
+
exports.VapiAiWebhookModule = VapiAiWebhookModule = tslib_1.__decorate([
|
|
27
|
+
(0, common_1.Module)({
|
|
28
|
+
imports: [config_1.ConfigModule],
|
|
29
|
+
controllers: [webhook_vapiai_controller_1.VapiAiWebhookController],
|
|
30
|
+
providers: [
|
|
31
|
+
{
|
|
32
|
+
provide: webhook_vapi_config_1.VapiAiWebhookServiceConfig,
|
|
33
|
+
inject: [config_1.ConfigService],
|
|
34
|
+
useFactory: vapiaiWebhookServiceConfigFactory
|
|
35
|
+
},
|
|
36
|
+
webhook_vapiai_service_1.VapiAiWebhookService
|
|
37
|
+
],
|
|
38
|
+
exports: [webhook_vapiai_service_1.VapiAiWebhookService]
|
|
39
|
+
})
|
|
40
|
+
], VapiAiWebhookModule);
|
|
41
|
+
//# sourceMappingURL=webhook.vapiai.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.vapiai.module.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/webhook.vapiai.module.ts"],"names":[],"mappings":";;;AAOA,8EAYC;;AAnBD,2EAAsE;AACtE,2CAAwC;AACxC,qEAAgE;AAChE,+DAAgP;AAChP,2CAA6D;AAG7D,SAAgB,iCAAiC,CAAC,aAA4B;IAC5E,MAAM,MAAM,GAA+B;QACzC,aAAa,EAAE;YACb,MAAM,EAAE,aAAa,CAAC,GAAG,CAAgC,0DAAoC,CAAC;YAC9F,UAAU,EAAE,aAAa,CAAC,GAAG,CAAgC,+DAAyC,CAAC;YACvG,gBAAgB,EAAE,aAAa,CAAC,GAAG,CAAkD,sEAAgD,CAAC;YACtI,eAAe,EAAE,aAAa,CAAC,GAAG,CAAqB,8DAAwC,CAAC;SACjG;KACF,CAAC;IAEF,gDAA0B,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC;AAeM,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;CAAG,CAAA;AAAtB,kDAAmB;8BAAnB,mBAAmB;IAb/B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,qBAAY,CAAC;QACvB,WAAW,EAAE,CAAC,mDAAuB,CAAC;QACtC,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,gDAA0B;gBACnC,MAAM,EAAE,CAAC,sBAAa,CAAC;gBACvB,UAAU,EAAE,iCAAiC;aAC9C;YACD,6CAAoB;SACrB;QACD,OAAO,EAAE,CAAC,6CAAoB,CAAC;KAChC,CAAC;GACW,mBAAmB,CAAG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
import { UntypedVapiAiWebhookEvent, VapiAiWebhookEvent, VapiAiWebhookEventType, VapiAiWebhookResult } from './webhook.vapiai';
|
|
3
|
+
import { Handler } from '@dereekb/util';
|
|
4
|
+
import { VapiAiWebhookServiceConfig } from './webhook.vapi.config';
|
|
5
|
+
export interface UpdateForVapiAiWebhookResponse extends VapiAiWebhookResult {
|
|
6
|
+
readonly valid: boolean;
|
|
7
|
+
readonly event: UntypedVapiAiWebhookEvent;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Service that makes system changes based on VapiAi webhook events.
|
|
11
|
+
*/
|
|
12
|
+
export declare class VapiAiWebhookService {
|
|
13
|
+
private readonly logger;
|
|
14
|
+
private readonly _verifier;
|
|
15
|
+
readonly handler: Handler<VapiAiWebhookEvent, VapiAiWebhookEventType, VapiAiWebhookResult>;
|
|
16
|
+
readonly configure: import("@dereekb/util").HandlerConfigurer<import("./webhook.vapiai").VapiAiEventHandlerConfigurer, UntypedVapiAiWebhookEvent, string, VapiAiWebhookResult>;
|
|
17
|
+
constructor(vapiAiWebhookServiceConfig: VapiAiWebhookServiceConfig);
|
|
18
|
+
updateForWebhook(req: Request, rawBody: Buffer): Promise<UpdateForVapiAiWebhookResponse>;
|
|
19
|
+
updateForVapiAiEvent(event: UntypedVapiAiWebhookEvent): Promise<VapiAiWebhookResult>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiAiWebhookService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const webhook_vapiai_1 = require("./webhook.vapiai");
|
|
7
|
+
const webhook_vapiai_verify_1 = require("./webhook.vapiai.verify");
|
|
8
|
+
const webhook_vapi_config_1 = require("./webhook.vapi.config");
|
|
9
|
+
/**
|
|
10
|
+
* Service that makes system changes based on VapiAi webhook events.
|
|
11
|
+
*/
|
|
12
|
+
let VapiAiWebhookService = class VapiAiWebhookService {
|
|
13
|
+
logger = new common_1.Logger('VapiAiWebhookService');
|
|
14
|
+
_verifier;
|
|
15
|
+
handler = (0, webhook_vapiai_1.vapiaiEventHandlerFactory)();
|
|
16
|
+
configure = (0, webhook_vapiai_1.vapiaiEventHandlerConfigurerFactory)(this.handler);
|
|
17
|
+
constructor(vapiAiWebhookServiceConfig) {
|
|
18
|
+
this._verifier = (0, webhook_vapiai_verify_1.vapiAiWebhookEventVerifier)(vapiAiWebhookServiceConfig.webhookConfig);
|
|
19
|
+
}
|
|
20
|
+
async updateForWebhook(req, rawBody) {
|
|
21
|
+
const { valid, event } = await this._verifier(req, rawBody);
|
|
22
|
+
let result = {
|
|
23
|
+
handled: false
|
|
24
|
+
};
|
|
25
|
+
if (!valid) {
|
|
26
|
+
this.logger.warn('Received invalid Vapi.ai event: ', event);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
result = await this.updateForVapiAiEvent(event);
|
|
30
|
+
}
|
|
31
|
+
const response = {
|
|
32
|
+
valid,
|
|
33
|
+
event,
|
|
34
|
+
...result
|
|
35
|
+
};
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
async updateForVapiAiEvent(event) {
|
|
39
|
+
const result = await this.handler(event);
|
|
40
|
+
if (!result.handled) {
|
|
41
|
+
this.logger.warn('Received unexpected/unhandled Vapi.ai event: ', event);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.VapiAiWebhookService = VapiAiWebhookService;
|
|
47
|
+
exports.VapiAiWebhookService = VapiAiWebhookService = tslib_1.__decorate([
|
|
48
|
+
(0, common_1.Injectable)(),
|
|
49
|
+
tslib_1.__param(0, (0, common_1.Inject)(webhook_vapi_config_1.VapiAiWebhookServiceConfig)),
|
|
50
|
+
tslib_1.__metadata("design:paramtypes", [webhook_vapi_config_1.VapiAiWebhookServiceConfig])
|
|
51
|
+
], VapiAiWebhookService);
|
|
52
|
+
//# sourceMappingURL=webhook.vapiai.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.vapiai.service.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/webhook.vapiai.service.ts"],"names":[],"mappings":";;;;AAAA,2CAA4D;AAE5D,qDAA8L;AAE9L,mEAAiG;AACjG,+DAAmE;AAOnE;;GAEG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IACd,MAAM,GAAG,IAAI,eAAM,CAAC,sBAAsB,CAAC,CAAC;IAE5C,SAAS,CAA6B;IAE9C,OAAO,GAA6E,IAAA,0CAAyB,GAAE,CAAC;IAChH,SAAS,GAAG,IAAA,oDAAmC,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEvE,YAAgD,0BAAsD;QACpG,IAAI,CAAC,SAAS,GAAG,IAAA,kDAA0B,EAAC,0BAA0B,CAAC,aAAa,CAAC,CAAC;IACxF,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,GAAY,EAAE,OAAe;QACzD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5D,IAAI,MAAM,GAAwB;YAChC,OAAO,EAAE,KAAK;SACf,CAAC;QAEF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,QAAQ,GAAmC;YAC/C,KAAK;YACL,KAAK;YACL,GAAG,MAAM;SACV,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,KAAgC;QACzD,MAAM,MAAM,GAAwB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAA;AA1CY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IASE,mBAAA,IAAA,eAAM,EAAC,gDAA0B,CAAC,CAAA;6CAA6B,gDAA0B;GAR3F,oBAAoB,CA0ChC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { DollarAmount, ISO8601DateStringUTCFull, JSONEncodedString, UnixDateTimeNumber, WebsiteUrlWithPrefix } from '@dereekb/util';
|
|
2
|
+
import { Analysis, Artifact, Assistant, Call, CallEndedReason, CallStatus, ChatMessagesItem, CostBreakdown } from '@vapi-ai/server-sdk/api';
|
|
3
|
+
import { VapiAssistantId, VapiCostsItem } from '../vapiai.type';
|
|
4
|
+
export declare enum VapiWebhookEnum {
|
|
5
|
+
ASSISTANT_REQUEST = "assistant-request",
|
|
6
|
+
FUNCTION_CALL = "function-call",
|
|
7
|
+
STATUS_UPDATE = "status-update",
|
|
8
|
+
END_OF_CALL_REPORT = "end-of-call-report",
|
|
9
|
+
HANG = "hang",
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated needs documentation link
|
|
12
|
+
*/
|
|
13
|
+
SPEECH_UPDATE = "speech-update",
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated needs documentation link
|
|
16
|
+
*/
|
|
17
|
+
TRANSCRIPT = "transcript"
|
|
18
|
+
}
|
|
19
|
+
interface BaseVapiPayload {
|
|
20
|
+
readonly call: Call;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Assistant request event payload
|
|
24
|
+
*
|
|
25
|
+
* https://docs.vapi.ai/server-url/events#retrieving-assistants
|
|
26
|
+
*/
|
|
27
|
+
export interface AssistantRequestPayload extends BaseVapiPayload {
|
|
28
|
+
readonly type: VapiWebhookEnum.ASSISTANT_REQUEST;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Status update event payload
|
|
32
|
+
*
|
|
33
|
+
* https://docs.vapi.ai/server-url/events#call-status-updates
|
|
34
|
+
*/
|
|
35
|
+
export interface StatusUpdatePayload extends BaseVapiPayload {
|
|
36
|
+
readonly type: VapiWebhookEnum.STATUS_UPDATE;
|
|
37
|
+
readonly status: CallStatus;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Function call event payload
|
|
41
|
+
*
|
|
42
|
+
* https://docs.vapi.ai/server-url/events#function-calling
|
|
43
|
+
*/
|
|
44
|
+
export interface FunctionCallPayload extends BaseVapiPayload {
|
|
45
|
+
readonly type: VapiWebhookEnum.FUNCTION_CALL;
|
|
46
|
+
readonly functionCall: {
|
|
47
|
+
readonly name: string;
|
|
48
|
+
readonly parameters: JSONEncodedString;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* End of call report event payload
|
|
53
|
+
*
|
|
54
|
+
* https://docs.vapi.ai/server-url/events#end-of-call-report
|
|
55
|
+
*/
|
|
56
|
+
export interface EndOfCallReportPayload extends BaseVapiPayload {
|
|
57
|
+
readonly type: VapiWebhookEnum.END_OF_CALL_REPORT;
|
|
58
|
+
readonly timestamp: UnixDateTimeNumber;
|
|
59
|
+
readonly analysis: Analysis;
|
|
60
|
+
readonly artifact: Artifact;
|
|
61
|
+
readonly startedAt: ISO8601DateStringUTCFull;
|
|
62
|
+
readonly endedAt: ISO8601DateStringUTCFull;
|
|
63
|
+
readonly endedReason: CallEndedReason;
|
|
64
|
+
readonly cost: DollarAmount;
|
|
65
|
+
readonly costBreakdown: CostBreakdown;
|
|
66
|
+
readonly costs: VapiCostsItem[];
|
|
67
|
+
readonly transcript: string;
|
|
68
|
+
readonly messages: ChatMessagesItem[];
|
|
69
|
+
readonly summary: string;
|
|
70
|
+
readonly recordingUrl?: WebsiteUrlWithPrefix;
|
|
71
|
+
readonly stereoRecordingUrl?: WebsiteUrlWithPrefix;
|
|
72
|
+
readonly assistant: Assistant;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Hang event payload
|
|
76
|
+
*
|
|
77
|
+
* https://docs.vapi.ai/server-url/events#hang-notifications
|
|
78
|
+
*/
|
|
79
|
+
export interface HangPayload extends BaseVapiPayload {
|
|
80
|
+
readonly type: VapiWebhookEnum.HANG;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @deprecated needs documentation link
|
|
84
|
+
*/
|
|
85
|
+
export interface SpeechUpdatePayload extends BaseVapiPayload {
|
|
86
|
+
readonly type: VapiWebhookEnum.SPEECH_UPDATE;
|
|
87
|
+
readonly status: 'started' | 'stopped';
|
|
88
|
+
readonly role: 'assistant' | 'user';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* @deprecated needs documentation link
|
|
92
|
+
*/
|
|
93
|
+
export interface TranscriptPayload {
|
|
94
|
+
readonly type: VapiWebhookEnum.TRANSCRIPT;
|
|
95
|
+
readonly role: 'assistant' | 'user';
|
|
96
|
+
readonly transcriptType: 'partial' | 'final';
|
|
97
|
+
readonly transcript: string;
|
|
98
|
+
}
|
|
99
|
+
export type VapiPayload = AssistantRequestPayload | StatusUpdatePayload | FunctionCallPayload | EndOfCallReportPayload | SpeechUpdatePayload | TranscriptPayload | HangPayload;
|
|
100
|
+
/**
|
|
101
|
+
* Response returned when a function is called.
|
|
102
|
+
*
|
|
103
|
+
* https://docs.vapi.ai/server-url/events#function-calling
|
|
104
|
+
*/
|
|
105
|
+
export type FunctionCallMessageResponse = {
|
|
106
|
+
readonly result: string | JSONEncodedString;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Response returned when an assistant request is received.
|
|
110
|
+
*
|
|
111
|
+
* https://docs.vapi.ai/server-url/events#retrieving-assistants
|
|
112
|
+
*/
|
|
113
|
+
export type AssistantRequestMessageResponse = AssistantRequestMessageSuccessResponse | AssistantRequestMessageErrorResponse;
|
|
114
|
+
export type AssistantRequestMessageSuccessResponse = AssistantRequestMessageSuccessIdResponse | AssistantRequestMessageSuccessObjectResponse;
|
|
115
|
+
export interface AssistantRequestMessageSuccessIdResponse {
|
|
116
|
+
readonly assistantId: VapiAssistantId;
|
|
117
|
+
}
|
|
118
|
+
export interface AssistantRequestMessageSuccessObjectResponse {
|
|
119
|
+
readonly assistant: Assistant;
|
|
120
|
+
}
|
|
121
|
+
export interface AssistantRequestMessageErrorResponse {
|
|
122
|
+
readonly error?: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Response that does not return any data.
|
|
126
|
+
*/
|
|
127
|
+
export type VapiVoidResponse = void;
|
|
128
|
+
export type StatusUpdateMessageResponse = VapiVoidResponse;
|
|
129
|
+
export type SpeechUpdateMessageResponse = VapiVoidResponse;
|
|
130
|
+
export type TranscriptMessageResponse = VapiVoidResponse;
|
|
131
|
+
export type HangMessageResponse = VapiVoidResponse;
|
|
132
|
+
export type EndOfCallReportMessageResponse = VapiVoidResponse;
|
|
133
|
+
export type VapiResponse = AssistantRequestMessageResponse | FunctionCallMessageResponse | EndOfCallReportMessageResponse | HangMessageResponse | StatusUpdateMessageResponse | SpeechUpdateMessageResponse | TranscriptMessageResponse;
|
|
134
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapiWebhookEnum = void 0;
|
|
4
|
+
var VapiWebhookEnum;
|
|
5
|
+
(function (VapiWebhookEnum) {
|
|
6
|
+
VapiWebhookEnum["ASSISTANT_REQUEST"] = "assistant-request";
|
|
7
|
+
VapiWebhookEnum["FUNCTION_CALL"] = "function-call";
|
|
8
|
+
VapiWebhookEnum["STATUS_UPDATE"] = "status-update";
|
|
9
|
+
VapiWebhookEnum["END_OF_CALL_REPORT"] = "end-of-call-report";
|
|
10
|
+
VapiWebhookEnum["HANG"] = "hang";
|
|
11
|
+
// TODO: speech update and transcript are not implemented or have documentation. They might be deprecated
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated needs documentation link
|
|
14
|
+
*/
|
|
15
|
+
VapiWebhookEnum["SPEECH_UPDATE"] = "speech-update";
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated needs documentation link
|
|
18
|
+
*/
|
|
19
|
+
VapiWebhookEnum["TRANSCRIPT"] = "transcript";
|
|
20
|
+
})(VapiWebhookEnum || (exports.VapiWebhookEnum = VapiWebhookEnum = {}));
|
|
21
|
+
//# sourceMappingURL=webhook.vapiai.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.vapiai.types.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/webhook.vapiai.types.ts"],"names":[],"mappings":";;;AAIA,IAAY,eAeX;AAfD,WAAY,eAAe;IACzB,0DAAuC,CAAA;IACvC,kDAA+B,CAAA;IAC/B,kDAA+B,CAAA;IAC/B,4DAAyC,CAAA;IACzC,gCAAa,CAAA;IACb,yGAAyG;IACzG;;OAEG;IACH,kDAA+B,CAAA;IAC/B;;OAEG;IACH,4CAAyB,CAAA;AAC3B,CAAC,EAfW,eAAe,+BAAf,eAAe,QAe1B"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
import { VapiAiWebhookSecretToken, VapiApiWebhookEventVerificationType } from '../vapiai.type';
|
|
3
|
+
import { UntypedVapiAiWebhookEvent } from './webhook.vapiai';
|
|
4
|
+
import { Maybe } from '@dereekb/util';
|
|
5
|
+
export interface VapiApiWebhookEventVerificationConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Secret token to use for verification.
|
|
8
|
+
*
|
|
9
|
+
* If not defined, defaults to an empty string.
|
|
10
|
+
*/
|
|
11
|
+
readonly secret?: VapiAiWebhookSecretToken;
|
|
12
|
+
/**
|
|
13
|
+
* Secret token to use for HMAC verification.
|
|
14
|
+
*
|
|
15
|
+
* If not provided, defaults to secret.
|
|
16
|
+
*/
|
|
17
|
+
readonly hmacSecret?: Maybe<VapiAiWebhookSecretToken>;
|
|
18
|
+
/**
|
|
19
|
+
* HMAC signature prefix
|
|
20
|
+
*
|
|
21
|
+
* Should match the prefix configured in the Vapi console
|
|
22
|
+
*/
|
|
23
|
+
readonly signaturePrefix?: Maybe<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Explicit verification type.
|
|
26
|
+
*
|
|
27
|
+
* If not provided, defaults to hmac if hmac secret is provided.
|
|
28
|
+
*/
|
|
29
|
+
readonly verificationType?: Maybe<VapiApiWebhookEventVerificationType>;
|
|
30
|
+
}
|
|
31
|
+
export interface VapiAiWebhookEventVerificationResult {
|
|
32
|
+
readonly valid: boolean;
|
|
33
|
+
readonly event: UntypedVapiAiWebhookEvent;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Function that verifies a VapiAi webhook event.
|
|
37
|
+
*/
|
|
38
|
+
export type VapiAiWebhookEventVerifier = (req: Request, rawBody: Buffer) => Promise<VapiAiWebhookEventVerificationResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Verifies a VapiAi webhook event header.
|
|
41
|
+
*
|
|
42
|
+
* @param vapiSecretTokenGetter The VapiAi secret token. The Vapi client allows for using an AsyncGetterOrValue type, so the verifier supports that as well.
|
|
43
|
+
* @returns A function that verifies a VapiAi webhook event.
|
|
44
|
+
*/
|
|
45
|
+
export declare function vapiAiWebhookEventVerifier(config: VapiApiWebhookEventVerificationConfig): VapiAiWebhookEventVerifier;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vapiAiWebhookEventVerifier = vapiAiWebhookEventVerifier;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
/**
|
|
6
|
+
* Verifies a VapiAi webhook event header.
|
|
7
|
+
*
|
|
8
|
+
* @param vapiSecretTokenGetter The VapiAi secret token. The Vapi client allows for using an AsyncGetterOrValue type, so the verifier supports that as well.
|
|
9
|
+
* @returns A function that verifies a VapiAi webhook event.
|
|
10
|
+
*/
|
|
11
|
+
function vapiAiWebhookEventVerifier(config) {
|
|
12
|
+
const { verificationType: inputVerificationType, secret: inputSecret, hmacSecret: inputHmacSecret, signaturePrefix: inputSignaturePrefix } = config;
|
|
13
|
+
const verificationType = inputVerificationType ?? (inputHmacSecret != null ? 'hmac' : 'secret'); // default to secret always, never default to none
|
|
14
|
+
const secretToken = (verificationType === 'hmac' ? (inputHmacSecret ?? inputSecret) : inputSecret) ?? '';
|
|
15
|
+
const signaturePrefix = inputSignaturePrefix ?? '';
|
|
16
|
+
function verifyNone(input) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
function verifySecret(input) {
|
|
20
|
+
const { request } = input;
|
|
21
|
+
const headers = request.headers;
|
|
22
|
+
const vapiSecret = headers['x-vapi-secret'];
|
|
23
|
+
const valid = vapiSecret === secretToken;
|
|
24
|
+
return valid;
|
|
25
|
+
}
|
|
26
|
+
function verifyHmac(input) {
|
|
27
|
+
const { request, requestBodyString } = input;
|
|
28
|
+
const headers = request.headers;
|
|
29
|
+
const timestamp = headers['x-timestamp'];
|
|
30
|
+
const vapiSignature = headers['x-signature'];
|
|
31
|
+
const message = `${timestamp}.${requestBodyString}`;
|
|
32
|
+
const hashForVerify = (0, crypto_1.createHmac)('sha256', secretToken).update(message).digest('hex');
|
|
33
|
+
const signature = `${signaturePrefix}${hashForVerify}`;
|
|
34
|
+
const valid = vapiSignature === signature;
|
|
35
|
+
return valid;
|
|
36
|
+
}
|
|
37
|
+
const verify = verificationType === 'hmac' ? verifyHmac : verificationType === 'secret' ? verifySecret : verifyNone;
|
|
38
|
+
return async (request, rawBody) => {
|
|
39
|
+
const requestBodyString = String(request.body);
|
|
40
|
+
const valid = verify({ request, requestBodyString });
|
|
41
|
+
const requestBody = JSON.parse(requestBodyString);
|
|
42
|
+
const result = {
|
|
43
|
+
valid,
|
|
44
|
+
event: requestBody.message
|
|
45
|
+
};
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=webhook.vapiai.verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.vapiai.verify.js","sourceRoot":"","sources":["../../../../../../../packages/nestjs/vapiai/src/lib/webhook/webhook.vapiai.verify.ts"],"names":[],"mappings":";;AAiDA,gEAoDC;AAjGD,mCAAoC;AAuCpC;;;;;GAKG;AACH,SAAgB,0BAA0B,CAAC,MAA6C;IACtF,MAAM,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAAC;IACpJ,MAAM,gBAAgB,GAAG,qBAAqB,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,kDAAkD;IACnJ,MAAM,WAAW,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IACzG,MAAM,eAAe,GAAG,oBAAoB,IAAI,EAAE,CAAC;IAOnD,SAAS,UAAU,CAAC,KAAkB;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,YAAY,CAAC,KAAkB;QACtC,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAG,UAAU,KAAK,WAAW,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS,UAAU,CAAC,KAAkB;QACpC,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAC;QAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAE7C,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,iBAAiB,EAAE,CAAC;QACpD,MAAM,aAAa,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtF,MAAM,SAAS,GAAG,GAAG,eAAe,GAAG,aAAa,EAAE,CAAC;QAEvD,MAAM,KAAK,GAAG,aAAa,KAAK,SAAS,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;IAEpH,OAAO,KAAK,EAAE,OAAgB,EAAE,OAAe,EAAE,EAAE;QACjD,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACrD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAA0B,CAAC;QAE3E,MAAM,MAAM,GAAyC;YACnD,KAAK;YACL,KAAK,EAAE,WAAW,CAAC,OAAO;SAC3B,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|