@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.
Files changed (218) hide show
  1. package/LICENSE +1 -1
  2. package/index.cjs.js +292 -0
  3. package/index.d.ts +1 -0
  4. package/index.esm.js +270 -0
  5. package/mailgun/index.cjs.js +646 -0
  6. package/mailgun/index.d.ts +1 -0
  7. package/mailgun/index.esm.js +633 -0
  8. package/mailgun/package.json +24 -3
  9. package/mailgun/src/lib/mailgun.d.ts +2 -2
  10. package/mailgun/src/lib/mailgun.type.d.ts +1 -1
  11. package/mailgun/src/lib/mailgun.util.d.ts +22 -17
  12. package/openai/index.cjs.js +310 -0
  13. package/openai/index.d.ts +1 -0
  14. package/openai/index.esm.js +293 -0
  15. package/openai/package.json +24 -5
  16. package/openai/src/lib/index.d.ts +0 -1
  17. package/openai/src/lib/webhook/webhook.openai.controller.d.ts +1 -1
  18. package/openai/src/lib/webhook/webhook.openai.d.ts +2 -2
  19. package/openai/src/lib/webhook/webhook.openai.service.d.ts +1 -1
  20. package/package.json +58 -28
  21. package/stripe/index.cjs.js +223 -0
  22. package/stripe/index.d.ts +1 -0
  23. package/stripe/index.esm.js +215 -0
  24. package/stripe/package.json +24 -5
  25. package/stripe/src/lib/index.d.ts +1 -1
  26. package/stripe/src/lib/stripe.module.d.ts +2 -2
  27. package/stripe/src/lib/webhook/webhook.stripe.controller.d.ts +1 -1
  28. package/typeform/index.cjs.js +378 -0
  29. package/typeform/index.d.ts +1 -0
  30. package/typeform/index.esm.js +363 -0
  31. package/typeform/package.json +24 -5
  32. package/typeform/src/lib/index.d.ts +0 -1
  33. package/typeform/src/lib/webhook/webhook.typeform.controller.d.ts +1 -1
  34. package/vapiai/index.cjs.js +306 -0
  35. package/vapiai/index.d.ts +1 -0
  36. package/vapiai/index.esm.js +297 -0
  37. package/vapiai/package.json +24 -5
  38. package/vapiai/src/lib/index.d.ts +0 -1
  39. package/vapiai/src/lib/vapiai.type.d.ts +3 -1
  40. package/vapiai/src/lib/webhook/webhook.vapiai.controller.d.ts +1 -1
  41. package/vapiai/src/lib/webhook/webhook.vapiai.d.ts +1 -9
  42. package/vapiai/src/lib/webhook/webhook.vapiai.types.d.ts +6 -34
  43. package/CHANGELOG.md +0 -1997
  44. package/mailgun/LICENSE +0 -21
  45. package/mailgun/src/index.js +0 -5
  46. package/mailgun/src/index.js.map +0 -1
  47. package/mailgun/src/lib/index.js +0 -10
  48. package/mailgun/src/lib/index.js.map +0 -1
  49. package/mailgun/src/lib/mailgun.api.js +0 -37
  50. package/mailgun/src/lib/mailgun.api.js.map +0 -1
  51. package/mailgun/src/lib/mailgun.config.js +0 -45
  52. package/mailgun/src/lib/mailgun.config.js.map +0 -1
  53. package/mailgun/src/lib/mailgun.js +0 -205
  54. package/mailgun/src/lib/mailgun.js.map +0 -1
  55. package/mailgun/src/lib/mailgun.service.js +0 -53
  56. package/mailgun/src/lib/mailgun.service.js.map +0 -1
  57. package/mailgun/src/lib/mailgun.service.module.js +0 -84
  58. package/mailgun/src/lib/mailgun.service.module.js.map +0 -1
  59. package/mailgun/src/lib/mailgun.type.js +0 -3
  60. package/mailgun/src/lib/mailgun.type.js.map +0 -1
  61. package/mailgun/src/lib/mailgun.util.js +0 -206
  62. package/mailgun/src/lib/mailgun.util.js.map +0 -1
  63. package/openai/LICENSE +0 -21
  64. package/openai/src/index.js +0 -5
  65. package/openai/src/index.js.map +0 -1
  66. package/openai/src/lib/index.js +0 -11
  67. package/openai/src/lib/index.js.map +0 -1
  68. package/openai/src/lib/openai.api.js +0 -22
  69. package/openai/src/lib/openai.api.js.map +0 -1
  70. package/openai/src/lib/openai.config.js +0 -29
  71. package/openai/src/lib/openai.config.js.map +0 -1
  72. package/openai/src/lib/openai.module.js +0 -41
  73. package/openai/src/lib/openai.module.js.map +0 -1
  74. package/openai/src/lib/openai.type.js +0 -3
  75. package/openai/src/lib/openai.type.js.map +0 -1
  76. package/openai/src/lib/openai.util.js +0 -48
  77. package/openai/src/lib/openai.util.js.map +0 -1
  78. package/openai/src/lib/webhook/index.js +0 -10
  79. package/openai/src/lib/webhook/index.js.map +0 -1
  80. package/openai/src/lib/webhook/webhook.openai.config.js +0 -17
  81. package/openai/src/lib/webhook/webhook.openai.config.js.map +0 -1
  82. package/openai/src/lib/webhook/webhook.openai.controller.js +0 -30
  83. package/openai/src/lib/webhook/webhook.openai.controller.js.map +0 -1
  84. package/openai/src/lib/webhook/webhook.openai.js +0 -41
  85. package/openai/src/lib/webhook/webhook.openai.js.map +0 -1
  86. package/openai/src/lib/webhook/webhook.openai.module.js +0 -39
  87. package/openai/src/lib/webhook/webhook.openai.module.js.map +0 -1
  88. package/openai/src/lib/webhook/webhook.openai.service.js +0 -48
  89. package/openai/src/lib/webhook/webhook.openai.service.js.map +0 -1
  90. package/openai/src/lib/webhook/webhook.openai.verify.js +0 -37
  91. package/openai/src/lib/webhook/webhook.openai.verify.js.map +0 -1
  92. package/src/index.js +0 -5
  93. package/src/index.js.map +0 -1
  94. package/src/lib/decorators/index.js +0 -6
  95. package/src/lib/decorators/index.js.map +0 -1
  96. package/src/lib/decorators/local.decorator.js +0 -17
  97. package/src/lib/decorators/local.decorator.js.map +0 -1
  98. package/src/lib/decorators/rawbody.js +0 -44
  99. package/src/lib/decorators/rawbody.js.map +0 -1
  100. package/src/lib/index.js +0 -7
  101. package/src/lib/index.js.map +0 -1
  102. package/src/lib/middlewares/index.js +0 -7
  103. package/src/lib/middlewares/index.js.map +0 -1
  104. package/src/lib/middlewares/json.middleware.js +0 -16
  105. package/src/lib/middlewares/json.middleware.js.map +0 -1
  106. package/src/lib/middlewares/rawbody.middleware.js +0 -16
  107. package/src/lib/middlewares/rawbody.middleware.js.map +0 -1
  108. package/src/lib/middlewares/webhook.js +0 -51
  109. package/src/lib/middlewares/webhook.js.map +0 -1
  110. package/src/lib/module/client/client.config.js +0 -13
  111. package/src/lib/module/client/client.config.js.map +0 -1
  112. package/src/lib/module/client/client.js +0 -8
  113. package/src/lib/module/client/client.js.map +0 -1
  114. package/src/lib/module/client/client.module.js +0 -36
  115. package/src/lib/module/client/client.module.js.map +0 -1
  116. package/src/lib/module/client/client.service.js +0 -30
  117. package/src/lib/module/client/client.service.js.map +0 -1
  118. package/src/lib/module/client/index.js +0 -8
  119. package/src/lib/module/client/index.js.map +0 -1
  120. package/src/lib/module/env/env.config.js +0 -14
  121. package/src/lib/module/env/env.config.js.map +0 -1
  122. package/src/lib/module/env/env.js +0 -10
  123. package/src/lib/module/env/env.js.map +0 -1
  124. package/src/lib/module/env/env.nest.js +0 -16
  125. package/src/lib/module/env/env.nest.js.map +0 -1
  126. package/src/lib/module/env/env.service.js +0 -33
  127. package/src/lib/module/env/env.service.js.map +0 -1
  128. package/src/lib/module/env/index.js +0 -8
  129. package/src/lib/module/env/index.js.map +0 -1
  130. package/src/lib/module/index.js +0 -7
  131. package/src/lib/module/index.js.map +0 -1
  132. package/src/lib/module/module.js +0 -26
  133. package/src/lib/module/module.js.map +0 -1
  134. package/stripe/LICENSE +0 -21
  135. package/stripe/src/index.js +0 -5
  136. package/stripe/src/index.js.map +0 -1
  137. package/stripe/src/lib/index.js +0 -8
  138. package/stripe/src/lib/index.js.map +0 -1
  139. package/stripe/src/lib/stripe.api.js +0 -40
  140. package/stripe/src/lib/stripe.api.js.map +0 -1
  141. package/stripe/src/lib/stripe.config.js +0 -19
  142. package/stripe/src/lib/stripe.config.js.map +0 -1
  143. package/stripe/src/lib/stripe.module.js +0 -41
  144. package/stripe/src/lib/stripe.module.js.map +0 -1
  145. package/stripe/src/lib/stripe.type.js +0 -4
  146. package/stripe/src/lib/stripe.type.js.map +0 -1
  147. package/stripe/src/lib/webhook/index.js +0 -8
  148. package/stripe/src/lib/webhook/index.js.map +0 -1
  149. package/stripe/src/lib/webhook/webhook.stripe.controller.js +0 -30
  150. package/stripe/src/lib/webhook/webhook.stripe.controller.js.map +0 -1
  151. package/stripe/src/lib/webhook/webhook.stripe.js +0 -67
  152. package/stripe/src/lib/webhook/webhook.stripe.js.map +0 -1
  153. package/stripe/src/lib/webhook/webhook.stripe.module.js +0 -20
  154. package/stripe/src/lib/webhook/webhook.stripe.module.js.map +0 -1
  155. package/stripe/src/lib/webhook/webhook.stripe.service.js +0 -36
  156. package/stripe/src/lib/webhook/webhook.stripe.service.js.map +0 -1
  157. package/typeform/LICENSE +0 -21
  158. package/typeform/src/index.js +0 -5
  159. package/typeform/src/index.js.map +0 -1
  160. package/typeform/src/lib/index.js +0 -11
  161. package/typeform/src/lib/index.js.map +0 -1
  162. package/typeform/src/lib/typeform.api.js +0 -22
  163. package/typeform/src/lib/typeform.api.js.map +0 -1
  164. package/typeform/src/lib/typeform.config.js +0 -21
  165. package/typeform/src/lib/typeform.config.js.map +0 -1
  166. package/typeform/src/lib/typeform.module.js +0 -39
  167. package/typeform/src/lib/typeform.module.js.map +0 -1
  168. package/typeform/src/lib/typeform.type.js +0 -3
  169. package/typeform/src/lib/typeform.type.js.map +0 -1
  170. package/typeform/src/lib/typeform.util.js +0 -26
  171. package/typeform/src/lib/typeform.util.js.map +0 -1
  172. package/typeform/src/lib/webhook/index.js +0 -12
  173. package/typeform/src/lib/webhook/index.js.map +0 -1
  174. package/typeform/src/lib/webhook/webhook.typeform.config.js +0 -17
  175. package/typeform/src/lib/webhook/webhook.typeform.config.js.map +0 -1
  176. package/typeform/src/lib/webhook/webhook.typeform.controller.js +0 -30
  177. package/typeform/src/lib/webhook/webhook.typeform.controller.js.map +0 -1
  178. package/typeform/src/lib/webhook/webhook.typeform.form.js +0 -113
  179. package/typeform/src/lib/webhook/webhook.typeform.form.js.map +0 -1
  180. package/typeform/src/lib/webhook/webhook.typeform.js +0 -27
  181. package/typeform/src/lib/webhook/webhook.typeform.js.map +0 -1
  182. package/typeform/src/lib/webhook/webhook.typeform.module.js +0 -38
  183. package/typeform/src/lib/webhook/webhook.typeform.module.js.map +0 -1
  184. package/typeform/src/lib/webhook/webhook.typeform.service.js +0 -45
  185. package/typeform/src/lib/webhook/webhook.typeform.service.js.map +0 -1
  186. package/typeform/src/lib/webhook/webhook.typeform.type.js +0 -3
  187. package/typeform/src/lib/webhook/webhook.typeform.type.js.map +0 -1
  188. package/typeform/src/lib/webhook/webhook.typeform.verify.js +0 -28
  189. package/typeform/src/lib/webhook/webhook.typeform.verify.js.map +0 -1
  190. package/vapiai/LICENSE +0 -21
  191. package/vapiai/src/index.js +0 -5
  192. package/vapiai/src/index.js.map +0 -1
  193. package/vapiai/src/lib/index.js +0 -10
  194. package/vapiai/src/lib/index.js.map +0 -1
  195. package/vapiai/src/lib/vapiai.api.js +0 -32
  196. package/vapiai/src/lib/vapiai.api.js.map +0 -1
  197. package/vapiai/src/lib/vapiai.config.js +0 -17
  198. package/vapiai/src/lib/vapiai.config.js.map +0 -1
  199. package/vapiai/src/lib/vapiai.module.js +0 -38
  200. package/vapiai/src/lib/vapiai.module.js.map +0 -1
  201. package/vapiai/src/lib/vapiai.type.js +0 -3
  202. package/vapiai/src/lib/vapiai.type.js.map +0 -1
  203. package/vapiai/src/lib/webhook/index.js +0 -10
  204. package/vapiai/src/lib/webhook/index.js.map +0 -1
  205. package/vapiai/src/lib/webhook/webhook.vapi.config.js +0 -20
  206. package/vapiai/src/lib/webhook/webhook.vapi.config.js.map +0 -1
  207. package/vapiai/src/lib/webhook/webhook.vapiai.controller.js +0 -38
  208. package/vapiai/src/lib/webhook/webhook.vapiai.controller.js.map +0 -1
  209. package/vapiai/src/lib/webhook/webhook.vapiai.js +0 -42
  210. package/vapiai/src/lib/webhook/webhook.vapiai.js.map +0 -1
  211. package/vapiai/src/lib/webhook/webhook.vapiai.module.js +0 -41
  212. package/vapiai/src/lib/webhook/webhook.vapiai.module.js.map +0 -1
  213. package/vapiai/src/lib/webhook/webhook.vapiai.service.js +0 -52
  214. package/vapiai/src/lib/webhook/webhook.vapiai.service.js.map +0 -1
  215. package/vapiai/src/lib/webhook/webhook.vapiai.types.js +0 -25
  216. package/vapiai/src/lib/webhook/webhook.vapiai.types.js.map +0 -1
  217. package/vapiai/src/lib/webhook/webhook.vapiai.verify.js +0 -49
  218. 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 };
@@ -1,9 +1,28 @@
1
1
  {
2
2
  "name": "@dereekb/nestjs/vapiai",
3
- "version": "12.6.21",
4
- "type": "commonjs",
5
- "peerDependencies": {},
6
- "dependencies": {},
3
+ "version": "13.0.0",
7
4
  "types": "./src/index.d.ts",
8
- "main": "./src/index.js"
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,6 +1,5 @@
1
1
  export * from './webhook';
2
2
  export * from './vapiai.module';
3
3
  export * from './vapiai.api';
4
- export * from './vapiai.module';
5
4
  export * from './vapiai.config';
6
5
  export * from './vapiai.type';
@@ -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.Costs.Item;
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
  }
@@ -1,4 +1,4 @@
1
- import { RawBodyBuffer } from '@dereekb/nestjs';
1
+ import { type RawBodyBuffer } from '@dereekb/nestjs';
2
2
  import { Request, Response } from 'express';
3
3
  import { VapiAiWebhookService } from './webhook.vapiai.service';
4
4
  export declare class VapiAiWebhookController {