@absolutejs/voice 0.0.22-beta.23 → 0.0.22-beta.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +169 -2
- package/dist/opsWebhook.d.ts +126 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { createVoicePostgresExternalObjectMapStore, createVoicePostgresIntegrati
|
|
|
13
13
|
export { createVoiceS3ReviewStore } from './s3Store';
|
|
14
14
|
export { createVoiceMemoryStore } from './memoryStore';
|
|
15
15
|
export { createVoiceCRMActivitySink, createVoiceHelpdeskTicketSink, createVoiceIntegrationHTTPSink, createVoiceHubSpotTaskSink, createVoiceHubSpotTaskSyncSinks, createVoiceHubSpotTaskUpdateSink, createVoiceLinearIssueSink, createVoiceLinearIssueSyncSinks, createVoiceLinearIssueUpdateSink, createVoiceZendeskTicketSink, createVoiceZendeskTicketSyncSinks, createVoiceZendeskTicketUpdateSink, deliverVoiceIntegrationEventToSinks } from './opsSinks';
|
|
16
|
+
export { createVoiceOpsWebhookEnvelope, createVoiceOpsWebhookReceiverRoutes, createVoiceOpsWebhookSink, verifyVoiceOpsWebhookSignature } from './opsWebhook';
|
|
16
17
|
export { createVoiceIntegrationSinkWorker, createVoiceIntegrationSinkWorkerLoop, createVoiceOpsTaskWorker, createVoiceOpsTaskProcessorWorker, createVoiceOpsTaskProcessorWorkerLoop, createVoiceRedisIdempotencyStore, createVoiceRedisTaskLeaseCoordinator, createVoiceTraceSinkDeliveryWorker, createVoiceTraceSinkDeliveryWorkerLoop, createVoiceWebhookDeliveryWorker, createVoiceWebhookDeliveryWorkerLoop, summarizeVoiceTraceSinkDeliveries, summarizeVoiceOpsTaskQueue, summarizeVoiceIntegrationEvents } from './queue';
|
|
17
18
|
export { assignVoiceOpsTask, applyVoiceOpsTaskAssignmentRule, applyVoiceOpsTaskPolicy, buildVoiceOpsTaskFromReview, buildVoiceOpsTaskFromSLABreach, claimVoiceOpsTask, completeVoiceOpsTask, createVoiceExternalObjectMap, createVoiceExternalObjectMapId, createVoiceCallCompletedEvent, createVoiceTaskSLABreachedEvent, deadLetterVoiceOpsTask, deliverVoiceIntegrationEvent, failVoiceOpsTask, hasVoiceOpsTaskSLABreach, heartbeatVoiceOpsTask, isVoiceOpsTaskOverdue, markVoiceOpsTaskSLABreached, matchesVoiceOpsTaskAssignmentRule, resolveVoiceOpsTaskAgeBucket, createVoiceIntegrationEvent, createVoiceReviewSavedEvent, resolveVoiceOpsTaskAssignment, resolveVoiceOpsTaskPolicy, requeueVoiceOpsTask, createVoiceTaskCreatedEvent, createVoiceTaskUpdatedEvent, listVoiceOpsTasks, reopenVoiceOpsTask, startVoiceOpsTask, summarizeVoiceOpsTaskAnalytics, summarizeVoiceOpsTasks, withVoiceIntegrationEventId, withVoiceOpsTaskId } from './ops';
|
|
18
19
|
export { createVoiceSession } from './session';
|
|
@@ -38,6 +39,7 @@ export type { VoiceOpsRuntime, VoiceOpsRuntimeConfig, VoiceOpsRuntimeSummary, Vo
|
|
|
38
39
|
export type { VoiceOpsPresetName, VoiceOpsPresetOverrides, VoiceResolvedOpsPreset } from './opsPresets';
|
|
39
40
|
export type { VoiceOutcomeRecipe, VoiceOutcomeRecipeName, VoiceOutcomeRecipeOptions } from './outcomeRecipes';
|
|
40
41
|
export type { VoiceCRMActivitySinkOptions, VoiceHubSpotTaskSinkOptions, VoiceHubSpotTaskUpdateSinkOptions, VoiceHelpdeskTicketSinkOptions, VoiceIntegrationHTTPSinkOptions, VoiceIntegrationSink, VoiceIntegrationSinkDeliveryResult, VoiceLinearIssueSinkOptions, VoiceLinearIssueUpdateSinkOptions, VoiceZendeskTicketSinkOptions, VoiceZendeskTicketUpdateSinkOptions } from './opsSinks';
|
|
42
|
+
export type { VoiceOpsWebhookEnvelope, VoiceOpsWebhookEntity, VoiceOpsWebhookLinkResolver, VoiceOpsWebhookReceiverRoutesOptions, VoiceOpsWebhookSinkOptions, VoiceOpsWebhookVerificationResult } from './opsWebhook';
|
|
41
43
|
export type { StoredVoiceCallReviewArtifact, VoiceCallReviewArtifact, VoiceCallReviewConfig, VoiceCallReviewPostCallSummary, VoiceCallReviewRecorder, VoiceCallReviewRecorderOptions, VoiceCallReviewStore, VoiceCallReviewSummary, VoiceCallReviewTimelineEvent } from './testing/review';
|
|
42
44
|
export type { VoiceFileRuntimeStorage, VoiceFileStoreOptions } from './fileStore';
|
|
43
45
|
export type { StoredVoiceTraceEvent, VoiceTraceEvaluation, VoiceTraceEvaluationOptions, VoiceTraceEvent, VoiceTraceEventFilter, VoiceTraceEventStore, VoiceTraceEventType, VoiceTraceIssue, VoiceTraceIssueSeverity, VoiceTraceHTTPSinkOptions, VoiceTracePruneFilter, VoiceTracePruneOptions, VoiceTracePruneResult, VoiceTraceRedactionConfig, VoiceTraceRedactionOptions, VoiceTraceRedactionReplacement, VoiceResolvedTraceRedactionOptions, VoiceTraceSink, VoiceTraceSinkDeliveryQueueStatus, VoiceTraceSinkDeliveryRecord, VoiceTraceSinkDeliveryResult, VoiceTraceSinkDeliveryStatus, VoiceTraceSinkDeliveryStore, VoiceTraceSinkFanoutResult, VoiceTraceSinkStoreOptions, VoiceTraceSummary } from './trace';
|
package/dist/index.js
CHANGED
|
@@ -7167,12 +7167,14 @@ var summarizeVoiceSessions = async (options = {}) => {
|
|
|
7167
7167
|
const providerErrors = {};
|
|
7168
7168
|
const providers = new Set;
|
|
7169
7169
|
let latestOutcome;
|
|
7170
|
+
let errorCount = 0;
|
|
7170
7171
|
for (const event of sorted) {
|
|
7171
7172
|
const provider = getString3(event.payload.provider);
|
|
7172
7173
|
if (provider) {
|
|
7173
7174
|
providers.add(provider);
|
|
7174
7175
|
}
|
|
7175
7176
|
if (event.type === "session.error" && (event.payload.providerStatus === "error" || typeof event.payload.error === "string")) {
|
|
7177
|
+
errorCount += 1;
|
|
7176
7178
|
increment2(providerErrors, provider ?? "unknown");
|
|
7177
7179
|
}
|
|
7178
7180
|
const outcome = getString3(event.payload.outcome);
|
|
@@ -7182,14 +7184,14 @@ var summarizeVoiceSessions = async (options = {}) => {
|
|
|
7182
7184
|
}
|
|
7183
7185
|
const item = {
|
|
7184
7186
|
endedAt: summary.endedAt,
|
|
7185
|
-
errorCount
|
|
7187
|
+
errorCount,
|
|
7186
7188
|
eventCount: summary.eventCount,
|
|
7187
7189
|
latestOutcome,
|
|
7188
7190
|
providerErrors,
|
|
7189
7191
|
providers: [...providers].sort(),
|
|
7190
7192
|
sessionId,
|
|
7191
7193
|
startedAt: summary.startedAt,
|
|
7192
|
-
status:
|
|
7194
|
+
status: errorCount > 0 ? "failed" : "healthy",
|
|
7193
7195
|
transcriptCount: summary.transcriptCount,
|
|
7194
7196
|
turnCount: summary.turnCount
|
|
7195
7197
|
};
|
|
@@ -8870,6 +8872,167 @@ var createVoiceMemoryStore = () => {
|
|
|
8870
8872
|
};
|
|
8871
8873
|
return { get, getOrCreate, list, remove, set };
|
|
8872
8874
|
};
|
|
8875
|
+
// src/opsWebhook.ts
|
|
8876
|
+
import { Elysia as Elysia5 } from "elysia";
|
|
8877
|
+
var toHex4 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
8878
|
+
var signVoiceOpsWebhookBody = async (input) => {
|
|
8879
|
+
const encoder = new TextEncoder;
|
|
8880
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(input.secret), {
|
|
8881
|
+
hash: "SHA-256",
|
|
8882
|
+
name: "HMAC"
|
|
8883
|
+
}, false, ["sign"]);
|
|
8884
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(`${input.timestamp}.${input.body}`));
|
|
8885
|
+
return `sha256=${toHex4(new Uint8Array(signature))}`;
|
|
8886
|
+
};
|
|
8887
|
+
var timingSafeEqual = (left, right) => {
|
|
8888
|
+
const encoder = new TextEncoder;
|
|
8889
|
+
const leftBytes = encoder.encode(left);
|
|
8890
|
+
const rightBytes = encoder.encode(right);
|
|
8891
|
+
if (leftBytes.length !== rightBytes.length) {
|
|
8892
|
+
return false;
|
|
8893
|
+
}
|
|
8894
|
+
let diff = 0;
|
|
8895
|
+
for (let index = 0;index < leftBytes.length; index += 1) {
|
|
8896
|
+
diff |= leftBytes[index] ^ rightBytes[index];
|
|
8897
|
+
}
|
|
8898
|
+
return diff === 0;
|
|
8899
|
+
};
|
|
8900
|
+
var resolveWebhookLink = async (resolver, event) => {
|
|
8901
|
+
if (typeof resolver === "function") {
|
|
8902
|
+
return resolver({
|
|
8903
|
+
event
|
|
8904
|
+
});
|
|
8905
|
+
}
|
|
8906
|
+
return resolver;
|
|
8907
|
+
};
|
|
8908
|
+
var joinBaseUrl = (baseUrl, path) => `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
8909
|
+
var asString = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
|
|
8910
|
+
var buildVoiceOpsWebhookEntity = (event) => ({
|
|
8911
|
+
disposition: asString(event.payload.disposition),
|
|
8912
|
+
outcome: asString(event.payload.outcome),
|
|
8913
|
+
priority: asString(event.payload.priority),
|
|
8914
|
+
queue: asString(event.payload.queue),
|
|
8915
|
+
reviewId: asString(event.payload.reviewId),
|
|
8916
|
+
scenarioId: asString(event.payload.scenarioId),
|
|
8917
|
+
sessionId: asString(event.payload.sessionId),
|
|
8918
|
+
status: asString(event.payload.status),
|
|
8919
|
+
target: asString(event.payload.target),
|
|
8920
|
+
taskId: asString(event.payload.taskId)
|
|
8921
|
+
});
|
|
8922
|
+
var createVoiceOpsWebhookEnvelope = async (input) => {
|
|
8923
|
+
const entity = buildVoiceOpsWebhookEntity(input.event);
|
|
8924
|
+
const replayHref = await resolveWebhookLink(input.replayHref, input.event) ?? (input.baseUrl && entity.sessionId ? joinBaseUrl(input.baseUrl, `/api/voice-sessions/${encodeURIComponent(entity.sessionId)}/replay`) : undefined);
|
|
8925
|
+
const links = {
|
|
8926
|
+
event: await resolveWebhookLink(input.eventHref, input.event),
|
|
8927
|
+
replay: replayHref,
|
|
8928
|
+
review: await resolveWebhookLink(input.reviewHref, input.event),
|
|
8929
|
+
task: await resolveWebhookLink(input.taskHref, input.event)
|
|
8930
|
+
};
|
|
8931
|
+
return {
|
|
8932
|
+
entity,
|
|
8933
|
+
event: {
|
|
8934
|
+
createdAt: input.event.createdAt,
|
|
8935
|
+
id: input.event.id,
|
|
8936
|
+
payload: input.event.payload,
|
|
8937
|
+
type: input.event.type
|
|
8938
|
+
},
|
|
8939
|
+
links: links.event || links.replay || links.review || links.task ? links : undefined,
|
|
8940
|
+
schemaVersion: 1,
|
|
8941
|
+
source: "absolutejs-voice"
|
|
8942
|
+
};
|
|
8943
|
+
};
|
|
8944
|
+
var createVoiceOpsWebhookSink = (options) => createVoiceIntegrationHTTPSink({
|
|
8945
|
+
...options,
|
|
8946
|
+
body: ({ event }) => createVoiceOpsWebhookEnvelope({
|
|
8947
|
+
baseUrl: options.baseUrl,
|
|
8948
|
+
event,
|
|
8949
|
+
eventHref: options.eventHref,
|
|
8950
|
+
replayHref: options.replayHref,
|
|
8951
|
+
reviewHref: options.reviewHref,
|
|
8952
|
+
taskHref: options.taskHref
|
|
8953
|
+
}),
|
|
8954
|
+
kind: options.kind ?? "ops-webhook"
|
|
8955
|
+
});
|
|
8956
|
+
var verifyVoiceOpsWebhookSignature = async (input) => {
|
|
8957
|
+
if (!input.secret) {
|
|
8958
|
+
return {
|
|
8959
|
+
ok: false,
|
|
8960
|
+
reason: "missing-secret"
|
|
8961
|
+
};
|
|
8962
|
+
}
|
|
8963
|
+
if (!input.signature) {
|
|
8964
|
+
return {
|
|
8965
|
+
ok: false,
|
|
8966
|
+
reason: "missing-signature"
|
|
8967
|
+
};
|
|
8968
|
+
}
|
|
8969
|
+
if (!input.signature.startsWith("sha256=")) {
|
|
8970
|
+
return {
|
|
8971
|
+
ok: false,
|
|
8972
|
+
reason: "unsupported-algorithm"
|
|
8973
|
+
};
|
|
8974
|
+
}
|
|
8975
|
+
if (!input.timestamp) {
|
|
8976
|
+
return {
|
|
8977
|
+
ok: false,
|
|
8978
|
+
reason: "missing-timestamp"
|
|
8979
|
+
};
|
|
8980
|
+
}
|
|
8981
|
+
const timestampMs = Number(input.timestamp);
|
|
8982
|
+
const toleranceMs = Math.max(0, input.toleranceMs ?? 5 * 60 * 1000);
|
|
8983
|
+
if (!Number.isFinite(timestampMs) || toleranceMs > 0 && Math.abs((input.now ?? Date.now()) - timestampMs) > toleranceMs) {
|
|
8984
|
+
return {
|
|
8985
|
+
ok: false,
|
|
8986
|
+
reason: "stale-timestamp"
|
|
8987
|
+
};
|
|
8988
|
+
}
|
|
8989
|
+
const expected = await signVoiceOpsWebhookBody({
|
|
8990
|
+
body: input.body,
|
|
8991
|
+
secret: input.secret,
|
|
8992
|
+
timestamp: input.timestamp
|
|
8993
|
+
});
|
|
8994
|
+
if (!timingSafeEqual(expected, input.signature)) {
|
|
8995
|
+
return {
|
|
8996
|
+
ok: false,
|
|
8997
|
+
reason: "invalid-signature"
|
|
8998
|
+
};
|
|
8999
|
+
}
|
|
9000
|
+
return {
|
|
9001
|
+
ok: true
|
|
9002
|
+
};
|
|
9003
|
+
};
|
|
9004
|
+
var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
|
|
9005
|
+
const path = options.path ?? "/api/voice-ops/webhook";
|
|
9006
|
+
return new Elysia5().post(path, async ({ request, set }) => {
|
|
9007
|
+
const body = await request.text();
|
|
9008
|
+
if (options.signingSecret) {
|
|
9009
|
+
const verification = await verifyVoiceOpsWebhookSignature({
|
|
9010
|
+
body,
|
|
9011
|
+
secret: options.signingSecret,
|
|
9012
|
+
signature: request.headers.get("x-absolutejs-signature"),
|
|
9013
|
+
timestamp: request.headers.get("x-absolutejs-timestamp"),
|
|
9014
|
+
toleranceMs: options.toleranceMs
|
|
9015
|
+
});
|
|
9016
|
+
if (!verification.ok) {
|
|
9017
|
+
set.status = 401;
|
|
9018
|
+
return {
|
|
9019
|
+
ok: false,
|
|
9020
|
+
reason: verification.reason
|
|
9021
|
+
};
|
|
9022
|
+
}
|
|
9023
|
+
}
|
|
9024
|
+
const envelope = JSON.parse(body);
|
|
9025
|
+
await options.onEnvelope?.({
|
|
9026
|
+
envelope,
|
|
9027
|
+
request
|
|
9028
|
+
});
|
|
9029
|
+
return {
|
|
9030
|
+
eventId: envelope.event?.id,
|
|
9031
|
+
ok: true,
|
|
9032
|
+
type: envelope.event?.type
|
|
9033
|
+
};
|
|
9034
|
+
});
|
|
9035
|
+
};
|
|
8873
9036
|
// src/queue.ts
|
|
8874
9037
|
var releaseLeaseScript = `
|
|
8875
9038
|
if redis.call("GET", KEYS[1]) == ARGV[1] then
|
|
@@ -10835,6 +10998,7 @@ export {
|
|
|
10835
10998
|
withVoiceOpsTaskId,
|
|
10836
10999
|
withVoiceIntegrationEventId,
|
|
10837
11000
|
voice,
|
|
11001
|
+
verifyVoiceOpsWebhookSignature,
|
|
10838
11002
|
transcodeTwilioInboundPayloadToPCM16,
|
|
10839
11003
|
transcodePCMToTwilioOutboundPayload,
|
|
10840
11004
|
summarizeVoiceTraceSinkDeliveries,
|
|
@@ -10941,6 +11105,9 @@ export {
|
|
|
10941
11105
|
createVoicePostgresReviewStore,
|
|
10942
11106
|
createVoicePostgresIntegrationEventStore,
|
|
10943
11107
|
createVoicePostgresExternalObjectMapStore,
|
|
11108
|
+
createVoiceOpsWebhookSink,
|
|
11109
|
+
createVoiceOpsWebhookReceiverRoutes,
|
|
11110
|
+
createVoiceOpsWebhookEnvelope,
|
|
10944
11111
|
createVoiceOpsTaskWorker,
|
|
10945
11112
|
createVoiceOpsTaskProcessorWorkerLoop,
|
|
10946
11113
|
createVoiceOpsTaskProcessorWorker,
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import type { StoredVoiceIntegrationEvent, VoiceIntegrationEventType } from './ops';
|
|
3
|
+
import type { VoiceIntegrationHTTPSinkOptions, VoiceIntegrationSink } from './opsSinks';
|
|
4
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
5
|
+
export type VoiceOpsWebhookLinkResolver = string | ((input: {
|
|
6
|
+
event: StoredVoiceIntegrationEvent;
|
|
7
|
+
}) => MaybePromise<string | undefined>);
|
|
8
|
+
export type VoiceOpsWebhookEntity = {
|
|
9
|
+
disposition?: string;
|
|
10
|
+
outcome?: string;
|
|
11
|
+
priority?: string;
|
|
12
|
+
queue?: string;
|
|
13
|
+
reviewId?: string;
|
|
14
|
+
scenarioId?: string;
|
|
15
|
+
sessionId?: string;
|
|
16
|
+
status?: string;
|
|
17
|
+
target?: string;
|
|
18
|
+
taskId?: string;
|
|
19
|
+
};
|
|
20
|
+
export type VoiceOpsWebhookEnvelope = {
|
|
21
|
+
entity: VoiceOpsWebhookEntity;
|
|
22
|
+
event: {
|
|
23
|
+
createdAt: number;
|
|
24
|
+
id: string;
|
|
25
|
+
payload: Record<string, unknown>;
|
|
26
|
+
type: VoiceIntegrationEventType;
|
|
27
|
+
};
|
|
28
|
+
links?: {
|
|
29
|
+
event?: string;
|
|
30
|
+
replay?: string;
|
|
31
|
+
review?: string;
|
|
32
|
+
task?: string;
|
|
33
|
+
};
|
|
34
|
+
schemaVersion: 1;
|
|
35
|
+
source: 'absolutejs-voice';
|
|
36
|
+
};
|
|
37
|
+
export type VoiceOpsWebhookSinkOptions = Omit<VoiceIntegrationHTTPSinkOptions<VoiceOpsWebhookEnvelope>, 'body'> & {
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
eventHref?: VoiceOpsWebhookLinkResolver;
|
|
40
|
+
replayHref?: VoiceOpsWebhookLinkResolver;
|
|
41
|
+
reviewHref?: VoiceOpsWebhookLinkResolver;
|
|
42
|
+
taskHref?: VoiceOpsWebhookLinkResolver;
|
|
43
|
+
};
|
|
44
|
+
export type VoiceOpsWebhookVerificationResult = {
|
|
45
|
+
ok: true;
|
|
46
|
+
} | {
|
|
47
|
+
ok: false;
|
|
48
|
+
reason: 'invalid-signature' | 'missing-secret' | 'missing-signature' | 'missing-timestamp' | 'stale-timestamp' | 'unsupported-algorithm';
|
|
49
|
+
};
|
|
50
|
+
export type VoiceOpsWebhookReceiverRoutesOptions = {
|
|
51
|
+
onEnvelope?: (input: {
|
|
52
|
+
envelope: VoiceOpsWebhookEnvelope;
|
|
53
|
+
request: Request;
|
|
54
|
+
}) => MaybePromise<void>;
|
|
55
|
+
path?: string;
|
|
56
|
+
signingSecret?: string;
|
|
57
|
+
toleranceMs?: number;
|
|
58
|
+
};
|
|
59
|
+
export declare const createVoiceOpsWebhookEnvelope: (input: {
|
|
60
|
+
baseUrl?: string;
|
|
61
|
+
event: StoredVoiceIntegrationEvent;
|
|
62
|
+
eventHref?: VoiceOpsWebhookLinkResolver;
|
|
63
|
+
replayHref?: VoiceOpsWebhookLinkResolver;
|
|
64
|
+
reviewHref?: VoiceOpsWebhookLinkResolver;
|
|
65
|
+
taskHref?: VoiceOpsWebhookLinkResolver;
|
|
66
|
+
}) => Promise<VoiceOpsWebhookEnvelope>;
|
|
67
|
+
export declare const createVoiceOpsWebhookSink: (options: VoiceOpsWebhookSinkOptions) => VoiceIntegrationSink;
|
|
68
|
+
export declare const verifyVoiceOpsWebhookSignature: (input: {
|
|
69
|
+
body: string;
|
|
70
|
+
now?: number;
|
|
71
|
+
secret?: string;
|
|
72
|
+
signature?: string | null;
|
|
73
|
+
timestamp?: string | null;
|
|
74
|
+
toleranceMs?: number;
|
|
75
|
+
}) => Promise<VoiceOpsWebhookVerificationResult>;
|
|
76
|
+
export declare const createVoiceOpsWebhookReceiverRoutes: (options?: VoiceOpsWebhookReceiverRoutesOptions) => Elysia<"", {
|
|
77
|
+
decorator: {};
|
|
78
|
+
store: {};
|
|
79
|
+
derive: {};
|
|
80
|
+
resolve: {};
|
|
81
|
+
}, {
|
|
82
|
+
typebox: {};
|
|
83
|
+
error: {};
|
|
84
|
+
}, {
|
|
85
|
+
schema: {};
|
|
86
|
+
standaloneSchema: {};
|
|
87
|
+
macro: {};
|
|
88
|
+
macroFn: {};
|
|
89
|
+
parser: {};
|
|
90
|
+
response: {};
|
|
91
|
+
}, {
|
|
92
|
+
[x: string]: {
|
|
93
|
+
post: {
|
|
94
|
+
body: unknown;
|
|
95
|
+
params: {};
|
|
96
|
+
query: unknown;
|
|
97
|
+
headers: unknown;
|
|
98
|
+
response: {
|
|
99
|
+
200: {
|
|
100
|
+
ok: boolean;
|
|
101
|
+
reason: "invalid-signature" | "missing-secret" | "missing-signature" | "missing-timestamp" | "stale-timestamp" | "unsupported-algorithm";
|
|
102
|
+
eventId?: undefined;
|
|
103
|
+
type?: undefined;
|
|
104
|
+
} | {
|
|
105
|
+
eventId: string;
|
|
106
|
+
ok: boolean;
|
|
107
|
+
type: VoiceIntegrationEventType;
|
|
108
|
+
reason?: undefined;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}, {
|
|
114
|
+
derive: {};
|
|
115
|
+
resolve: {};
|
|
116
|
+
schema: {};
|
|
117
|
+
standaloneSchema: {};
|
|
118
|
+
response: {};
|
|
119
|
+
}, {
|
|
120
|
+
derive: {};
|
|
121
|
+
resolve: {};
|
|
122
|
+
schema: {};
|
|
123
|
+
standaloneSchema: {};
|
|
124
|
+
response: {};
|
|
125
|
+
}>;
|
|
126
|
+
export {};
|