@memberjunction/telephony-adapters 0.0.0 → 6.1.0-edge.7

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 (115) hide show
  1. package/LICENSE +183 -0
  2. package/dist/index.d.ts +33 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +83 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/resolvers/RingCentralTelephonyResolver.d.ts +20 -0
  7. package/dist/resolvers/RingCentralTelephonyResolver.d.ts.map +1 -0
  8. package/dist/resolvers/RingCentralTelephonyResolver.js +83 -0
  9. package/dist/resolvers/RingCentralTelephonyResolver.js.map +1 -0
  10. package/dist/resolvers/TeamsMeetingsResolver.d.ts +21 -0
  11. package/dist/resolvers/TeamsMeetingsResolver.d.ts.map +1 -0
  12. package/dist/resolvers/TeamsMeetingsResolver.js +87 -0
  13. package/dist/resolvers/TeamsMeetingsResolver.js.map +1 -0
  14. package/dist/resolvers/TelephonyResolver.d.ts +20 -0
  15. package/dist/resolvers/TelephonyResolver.d.ts.map +1 -0
  16. package/dist/resolvers/TelephonyResolver.js +83 -0
  17. package/dist/resolvers/TelephonyResolver.js.map +1 -0
  18. package/dist/resolvers/VonageTelephonyResolver.d.ts +20 -0
  19. package/dist/resolvers/VonageTelephonyResolver.d.ts.map +1 -0
  20. package/dist/resolvers/VonageTelephonyResolver.js +83 -0
  21. package/dist/resolvers/VonageTelephonyResolver.js.map +1 -0
  22. package/dist/resolvers/index.d.ts +10 -0
  23. package/dist/resolvers/index.d.ts.map +1 -0
  24. package/dist/resolvers/index.js +10 -0
  25. package/dist/resolvers/index.js.map +1 -0
  26. package/dist/server-extensions/RingCentralTelephonyExtension.d.ts +14 -0
  27. package/dist/server-extensions/RingCentralTelephonyExtension.d.ts.map +1 -0
  28. package/dist/server-extensions/RingCentralTelephonyExtension.js +81 -0
  29. package/dist/server-extensions/RingCentralTelephonyExtension.js.map +1 -0
  30. package/dist/server-extensions/TeamsMeetingsExtension.d.ts +17 -0
  31. package/dist/server-extensions/TeamsMeetingsExtension.d.ts.map +1 -0
  32. package/dist/server-extensions/TeamsMeetingsExtension.js +109 -0
  33. package/dist/server-extensions/TeamsMeetingsExtension.js.map +1 -0
  34. package/dist/server-extensions/TwilioTelephonyExtension.d.ts +14 -0
  35. package/dist/server-extensions/TwilioTelephonyExtension.d.ts.map +1 -0
  36. package/dist/server-extensions/TwilioTelephonyExtension.js +88 -0
  37. package/dist/server-extensions/TwilioTelephonyExtension.js.map +1 -0
  38. package/dist/server-extensions/VonageTelephonyExtension.d.ts +14 -0
  39. package/dist/server-extensions/VonageTelephonyExtension.d.ts.map +1 -0
  40. package/dist/server-extensions/VonageTelephonyExtension.js +89 -0
  41. package/dist/server-extensions/VonageTelephonyExtension.js.map +1 -0
  42. package/dist/sessionManager.d.ts +26 -0
  43. package/dist/sessionManager.d.ts.map +1 -0
  44. package/dist/sessionManager.js +38 -0
  45. package/dist/sessionManager.js.map +1 -0
  46. package/dist/telephony/RingCentralTelephonyService.d.ts +79 -0
  47. package/dist/telephony/RingCentralTelephonyService.d.ts.map +1 -0
  48. package/dist/telephony/RingCentralTelephonyService.js +225 -0
  49. package/dist/telephony/RingCentralTelephonyService.js.map +1 -0
  50. package/dist/telephony/TeamsMeetingsRouter.d.ts +21 -0
  51. package/dist/telephony/TeamsMeetingsRouter.d.ts.map +1 -0
  52. package/dist/telephony/TeamsMeetingsRouter.js +84 -0
  53. package/dist/telephony/TeamsMeetingsRouter.js.map +1 -0
  54. package/dist/telephony/TeamsMeetingsService.d.ts +76 -0
  55. package/dist/telephony/TeamsMeetingsService.d.ts.map +1 -0
  56. package/dist/telephony/TeamsMeetingsService.js +157 -0
  57. package/dist/telephony/TeamsMeetingsService.js.map +1 -0
  58. package/dist/telephony/TwilioTelephonyRouter.d.ts +30 -0
  59. package/dist/telephony/TwilioTelephonyRouter.d.ts.map +1 -0
  60. package/dist/telephony/TwilioTelephonyRouter.js +137 -0
  61. package/dist/telephony/TwilioTelephonyRouter.js.map +1 -0
  62. package/dist/telephony/TwilioTelephonyService.d.ts +91 -0
  63. package/dist/telephony/TwilioTelephonyService.d.ts.map +1 -0
  64. package/dist/telephony/TwilioTelephonyService.js +191 -0
  65. package/dist/telephony/TwilioTelephonyService.js.map +1 -0
  66. package/dist/telephony/VonageTelephonyRouter.d.ts +24 -0
  67. package/dist/telephony/VonageTelephonyRouter.d.ts.map +1 -0
  68. package/dist/telephony/VonageTelephonyRouter.js +175 -0
  69. package/dist/telephony/VonageTelephonyRouter.js.map +1 -0
  70. package/dist/telephony/VonageTelephonyService.d.ts +62 -0
  71. package/dist/telephony/VonageTelephonyService.d.ts.map +1 -0
  72. package/dist/telephony/VonageTelephonyService.js +162 -0
  73. package/dist/telephony/VonageTelephonyService.js.map +1 -0
  74. package/dist/telephony/calendar-scheduler.d.ts +41 -0
  75. package/dist/telephony/calendar-scheduler.d.ts.map +1 -0
  76. package/dist/telephony/calendar-scheduler.js +98 -0
  77. package/dist/telephony/calendar-scheduler.js.map +1 -0
  78. package/dist/telephony/index.d.ts +21 -0
  79. package/dist/telephony/index.d.ts.map +1 -0
  80. package/dist/telephony/index.js +26 -0
  81. package/dist/telephony/index.js.map +1 -0
  82. package/dist/telephony/ringcentral-runtime.d.ts +11 -0
  83. package/dist/telephony/ringcentral-runtime.d.ts.map +1 -0
  84. package/dist/telephony/ringcentral-runtime.js +20 -0
  85. package/dist/telephony/ringcentral-runtime.js.map +1 -0
  86. package/dist/telephony/teams-meetings-runtime.d.ts +11 -0
  87. package/dist/telephony/teams-meetings-runtime.d.ts.map +1 -0
  88. package/dist/telephony/teams-meetings-runtime.js +20 -0
  89. package/dist/telephony/teams-meetings-runtime.js.map +1 -0
  90. package/dist/telephony/teamsAcsMediaRegistry.d.ts +35 -0
  91. package/dist/telephony/teamsAcsMediaRegistry.d.ts.map +1 -0
  92. package/dist/telephony/teamsAcsMediaRegistry.js +86 -0
  93. package/dist/telephony/teamsAcsMediaRegistry.js.map +1 -0
  94. package/dist/telephony/telephony-runtime.d.ts +14 -0
  95. package/dist/telephony/telephony-runtime.d.ts.map +1 -0
  96. package/dist/telephony/telephony-runtime.js +23 -0
  97. package/dist/telephony/telephony-runtime.js.map +1 -0
  98. package/dist/telephony/twilioMediaRegistry.d.ts +60 -0
  99. package/dist/telephony/twilioMediaRegistry.d.ts.map +1 -0
  100. package/dist/telephony/twilioMediaRegistry.js +109 -0
  101. package/dist/telephony/twilioMediaRegistry.js.map +1 -0
  102. package/dist/telephony/vonage-runtime.d.ts +11 -0
  103. package/dist/telephony/vonage-runtime.d.ts.map +1 -0
  104. package/dist/telephony/vonage-runtime.js +20 -0
  105. package/dist/telephony/vonage-runtime.js.map +1 -0
  106. package/dist/telephony/vonageMediaRegistry.d.ts +38 -0
  107. package/dist/telephony/vonageMediaRegistry.d.ts.map +1 -0
  108. package/dist/telephony/vonageMediaRegistry.js +113 -0
  109. package/dist/telephony/vonageMediaRegistry.js.map +1 -0
  110. package/dist/types.d.ts +123 -0
  111. package/dist/types.d.ts.map +1 -0
  112. package/dist/types.js +27 -0
  113. package/dist/types.js.map +1 -0
  114. package/package.json +48 -8
  115. package/README.md +0 -45
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TwilioTelephonyService.js","sourceRoot":"","sources":["../../src/telephony/TwilioTelephonyService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @fileoverview Express + WSS wiring for the Vonage telephony ingress.
3
+ *
4
+ * @module @memberjunction/telephony-adapters
5
+ */
6
+ import { Router } from 'express';
7
+ import type { VonageTelephonyConfig } from '../types.js';
8
+ import { VonageCallMediaRegistry } from './vonageMediaRegistry.js';
9
+ import { VonageTelephonyService } from './VonageTelephonyService.js';
10
+ /** The mount path for the Vonage telephony public router. */
11
+ export declare const VONAGE_TELEPHONY_MOUNT_PATH = "/telephony/vonage";
12
+ /** The media websocket path Vonage's `connect`-websocket NCCO connects to. */
13
+ export declare const VONAGE_MEDIA_WSS_PATH = "/telephony/vonage/media";
14
+ /**
15
+ * Builds the Vonage telephony handler: the public answer/event router + a function to attach the media
16
+ * WSS to the shared HTTP server.
17
+ */
18
+ export declare function createVonageTelephonyHandler(publicUrl: string, config: VonageTelephonyConfig): {
19
+ publicRouter: Router;
20
+ attachMediaStreamServer: () => void;
21
+ registry: VonageCallMediaRegistry;
22
+ service: VonageTelephonyService;
23
+ };
24
+ //# sourceMappingURL=VonageTelephonyRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VonageTelephonyRouter.d.ts","sourceRoot":"","sources":["../../src/telephony/VonageTelephonyRouter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAiD,MAAM,SAAS,CAAC;AAahF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,6DAA6D;AAC7D,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAE/D,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAK/D;;;GAGG;AACH,wBAAgB,4BAA4B,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,qBAAqB,GAC9B;IACC,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,OAAO,EAAE,sBAAsB,CAAC;CACnC,CAkBA"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * @fileoverview Express + WSS wiring for the Vonage telephony ingress.
3
+ *
4
+ * @module @memberjunction/telephony-adapters
5
+ */
6
+ import { Router, urlencoded, json } from 'express';
7
+ import { WebSocketServer } from 'ws';
8
+ import { RegisterMediaUpgradeRoute } from '@memberjunction/server-extensions-core';
9
+ import { LogError, LogStatus, Metadata } from '@memberjunction/core';
10
+ import { UserCache } from '@memberjunction/generic-database-provider';
11
+ import { verifyVonageSignature, verifyVonageJwt, resolveInboundCall, buildInboundAnswerNcco, parseVonageControlEvent, } from '@memberjunction/ai-bridge-vonage';
12
+ import { VonageCallMediaRegistry } from './vonageMediaRegistry.js';
13
+ import { VonageTelephonyService } from './VonageTelephonyService.js';
14
+ /** The mount path for the Vonage telephony public router. */
15
+ export const VONAGE_TELEPHONY_MOUNT_PATH = '/telephony/vonage';
16
+ /** The media websocket path Vonage's `connect`-websocket NCCO connects to. */
17
+ export const VONAGE_MEDIA_WSS_PATH = '/telephony/vonage/media';
18
+ /** A polite NCCO returned when no agent is available for the dialed number. */
19
+ const NO_AGENT_NCCO = [{ action: 'talk', text: 'Sorry, no agent is available to take this call.' }];
20
+ /**
21
+ * Builds the Vonage telephony handler: the public answer/event router + a function to attach the media
22
+ * WSS to the shared HTTP server.
23
+ */
24
+ export function createVonageTelephonyHandler(publicUrl, config) {
25
+ const registry = new VonageCallMediaRegistry();
26
+ const service = new VonageTelephonyService(config, registry);
27
+ const publicRouter = Router();
28
+ publicRouter.post('/answer', json(), urlencoded({ extended: false }), async (req, res) => {
29
+ await handleInboundAnswer(service, config, req, res);
30
+ });
31
+ publicRouter.post('/event', json(), urlencoded({ extended: false }), (req, res) => {
32
+ handleCallEvent(config, req, res);
33
+ });
34
+ return {
35
+ publicRouter,
36
+ attachMediaStreamServer: () => attachMediaStreamServer(registry),
37
+ registry,
38
+ service,
39
+ };
40
+ }
41
+ /** Handles the inbound answer webhook: verify → resolve → start bridge → return the connect-websocket NCCO. */
42
+ async function handleInboundAnswer(service, config, req, res) {
43
+ const params = coerceParams(req.body);
44
+ if (!verifyVonageRequest(config, req, params)) {
45
+ res.status(403).type('application/json').json({ error: 'Invalid Vonage signature.' });
46
+ return;
47
+ }
48
+ let resolved;
49
+ try {
50
+ resolved = resolveInboundCall(params);
51
+ }
52
+ catch (e) {
53
+ LogError(`[Telephony][Vonage] answer webhook unparseable: ${e instanceof Error ? e.message : String(e)}`);
54
+ res.status(200).type('application/json').json(NO_AGENT_NCCO);
55
+ return;
56
+ }
57
+ const context = resolveServerContext();
58
+ if (!context) {
59
+ LogError('[Telephony][Vonage] no server context user available; cannot start inbound call.');
60
+ res.status(200).type('application/json').json(NO_AGENT_NCCO);
61
+ return;
62
+ }
63
+ const result = await service.HandleInboundCall(resolved, context.user, context.provider);
64
+ if (!result.accepted) {
65
+ LogStatus(`[Telephony][Vonage] inbound ${resolved.callId} not accepted: ${result.reason ?? 'unknown'}`);
66
+ res.status(200).type('application/json').json(NO_AGENT_NCCO);
67
+ return;
68
+ }
69
+ const mediaUrl = appendCallUuid(config.mediaPublicUrl, resolved.callId);
70
+ res.status(200).type('application/json').json(buildInboundAnswerNcco(mediaUrl));
71
+ }
72
+ /** Handles a call-lifecycle event webhook: verify then acknowledge. */
73
+ function handleCallEvent(config, req, res) {
74
+ const params = coerceParams(req.body);
75
+ if (!verifyVonageRequest(config, req, params)) {
76
+ res.status(403).type('application/json').json({ error: 'Invalid Vonage signature.' });
77
+ return;
78
+ }
79
+ LogStatus(`[Telephony][Vonage] event: ${params['status'] ?? params['event'] ?? 'unknown'} for ${params['uuid'] ?? params['conversation_uuid'] ?? '?'}`);
80
+ res.status(200).end();
81
+ }
82
+ /** Verifies a public Vonage webhook via the webhook JWT (preferred) or the signed-request `sig` HMAC. */
83
+ function verifyVonageRequest(config, req, params) {
84
+ const secret = config.signatureSecret;
85
+ if (!secret) {
86
+ return false;
87
+ }
88
+ const jwtClaims = verifyVonageJwt(secret, req.get('Authorization'), Math.floor(Date.now() / 1000));
89
+ if (jwtClaims) {
90
+ return true;
91
+ }
92
+ return verifyVonageSignature(secret, params['sig'], params);
93
+ }
94
+ /**
95
+ * Attaches the media WSS to the shared HTTP server on {@link VONAGE_MEDIA_WSS_PATH}.
96
+ */
97
+ function attachMediaStreamServer(registry) {
98
+ const wss = new WebSocketServer({ noServer: true });
99
+ wss.on('connection', (socket, request) => wireMediaSocket(socket, request, registry));
100
+ RegisterMediaUpgradeRoute(VONAGE_MEDIA_WSS_PATH, wss);
101
+ LogStatus(`[Telephony][Vonage] media WSS route registered at ${VONAGE_MEDIA_WSS_PATH}`);
102
+ }
103
+ /** Wires one media socket: key on the `call_uuid` query param, attach, dispatch inbound frames, tear down on close. */
104
+ function wireMediaSocket(socket, request, registry) {
105
+ const callUuid = readCallUuid(request);
106
+ if (!callUuid) {
107
+ LogError('[Telephony][Vonage] media socket connected with no call_uuid; closing.');
108
+ socket.close();
109
+ return;
110
+ }
111
+ const adapter = {
112
+ sendBinary: (data) => socket.send(data),
113
+ sendText: (data) => socket.send(data),
114
+ close: () => socket.close(),
115
+ };
116
+ registry.AttachSocket(callUuid, adapter);
117
+ socket.on('message', (raw, isBinary) => {
118
+ if (isBinary) {
119
+ registry.DispatchInboundAudio(callUuid, toArrayBuffer(raw));
120
+ return;
121
+ }
122
+ const event = parseVonageControlEvent(raw.toString('utf8'));
123
+ if (event) {
124
+ registry.DispatchInboundEvent(callUuid, event);
125
+ }
126
+ });
127
+ socket.on('close', () => registry.EndCall(callUuid));
128
+ }
129
+ /** Copies a Node `Buffer` into a standalone `ArrayBuffer`. */
130
+ function toArrayBuffer(buf) {
131
+ const out = new ArrayBuffer(buf.byteLength);
132
+ new Uint8Array(out).set(buf);
133
+ return out;
134
+ }
135
+ /** Reads the `call_uuid` query param off the websocket upgrade request URL, or null when absent. */
136
+ function readCallUuid(request) {
137
+ try {
138
+ const url = new URL(request.url ?? '', 'http://localhost');
139
+ const value = url.searchParams.get('call_uuid');
140
+ return value && value.length > 0 ? value : null;
141
+ }
142
+ catch {
143
+ return null;
144
+ }
145
+ }
146
+ /** Appends the call UUID as a `call_uuid` query param to the media URL so the WSS can key the socket. */
147
+ function appendCallUuid(mediaUrl, callUuid) {
148
+ const sep = mediaUrl.includes('?') ? '&' : '?';
149
+ return `${mediaUrl}${sep}call_uuid=${encodeURIComponent(callUuid)}`;
150
+ }
151
+ /** Coerces an Express body (JSON object or urlencoded) to the `Record<string,string>` the verifiers expect. */
152
+ function coerceParams(body) {
153
+ const out = {};
154
+ if (body && typeof body === 'object') {
155
+ for (const [key, value] of Object.entries(body)) {
156
+ if (typeof value === 'string') {
157
+ out[key] = value;
158
+ }
159
+ else if (typeof value === 'number' || typeof value === 'boolean') {
160
+ out[key] = String(value);
161
+ }
162
+ }
163
+ }
164
+ return out;
165
+ }
166
+ /** Resolves the server-side principal + provider for the public webhook. */
167
+ function resolveServerContext() {
168
+ const user = UserCache.Instance.GetSystemUser() ?? UserCache.Users.find((u) => u.IsActive && u.Type?.trim().toLowerCase() === 'owner') ?? null;
169
+ const provider = Metadata.Provider; // global-provider-ok: inbound telephony webhook runs in server-global provider context
170
+ if (!user || !provider) {
171
+ return null;
172
+ }
173
+ return { user, provider };
174
+ }
175
+ //# sourceMappingURL=VonageTelephonyRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VonageTelephonyRouter.js","sourceRoot":"","sources":["../../src/telephony/VonageTelephonyRouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @fileoverview Orchestrates Vonage telephony bridge sessions (inbound + outbound) for MJAPI.
3
+ *
4
+ * @module @memberjunction/telephony-adapters
5
+ */
6
+ import { UserInfo, IMetadataProvider } from '@memberjunction/core';
7
+ import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
8
+ import { CreateBridgeRealtimeSession } from '@memberjunction/ai-agents';
9
+ import { type BridgeNativeSdkBinding } from '@memberjunction/ai-bridge-base';
10
+ import type { VonageTelephonyConfig } from '../types.js';
11
+ import { IAgentSessionManager } from '../sessionManager.js';
12
+ import { VonageCallMediaRegistry } from './vonageMediaRegistry.js';
13
+ /** A resolved inbound call's identifying fields (parsed from the Vonage answer/event webhook). */
14
+ export interface InboundCallInput {
15
+ /** The Vonage call UUID (`uuid` / `conversation_uuid`). */
16
+ callId: string;
17
+ /** The caller's number (Vonage `from`). */
18
+ from: string;
19
+ /** The dialed DID (Vonage `to`) — resolved to an agent identity. */
20
+ to: string;
21
+ }
22
+ /** Result of starting an inbound bridge session. */
23
+ export interface InboundCallResult {
24
+ /** Whether a pinned agent was resolved + a bridge session started. */
25
+ accepted: boolean;
26
+ /** Why it was rejected (no agent identity for the DID, provider missing, etc.). */
27
+ reason?: string;
28
+ }
29
+ /** Injectable collaborators (production defaults wired in the constructor; fakes in tests). */
30
+ export interface VonageTelephonyServiceDeps {
31
+ engine?: Pick<AIBridgeEngine, 'ProviderByName' | 'ProviderByDriverClass' | 'StartBridgeSession' | 'Config'>;
32
+ sessionFactory?: typeof CreateBridgeRealtimeSession;
33
+ sessionManager?: IAgentSessionManager;
34
+ }
35
+ /**
36
+ * Starts Vonage bridge sessions. One instance per server, constructed alongside the telephony router and
37
+ * sharing the {@link VonageCallMediaRegistry} with the media WSS server.
38
+ */
39
+ export declare class VonageTelephonyService {
40
+ private readonly config;
41
+ private readonly registry;
42
+ private readonly voice;
43
+ private readonly engine;
44
+ private readonly sessionFactory;
45
+ private readonly sessionManager;
46
+ constructor(config: VonageTelephonyConfig, registry: VonageCallMediaRegistry, deps?: VonageTelephonyServiceDeps);
47
+ /**
48
+ * Resolves the dialed DID to a pinned agent and starts an INBOUND bridge session.
49
+ */
50
+ HandleInboundCall(input: InboundCallInput, contextUser: UserInfo, provider: IMetadataProvider): Promise<InboundCallResult>;
51
+ /**
52
+ * Places an OUTBOUND call from a given agent identity to a destination number.
53
+ */
54
+ PlaceOutboundCall(agentIdentityId: string, toNumber: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<string>;
55
+ private startBridge;
56
+ private resolveProvider;
57
+ buildBindSdk(): BridgeNativeSdkBinding;
58
+ private buildSessionConfiguration;
59
+ private resolveAgentIdentityByPhone;
60
+ private loadAgentIdentity;
61
+ }
62
+ //# sourceMappingURL=VonageTelephonyService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VonageTelephonyService.d.ts","sourceRoot":"","sources":["../../src/telephony/VonageTelephonyService.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAW,QAAQ,EAAE,iBAAiB,EAAY,MAAM,sBAAsB,CAAC;AAGtF,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAEH,KAAK,sBAAsB,EAI9B,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAA8B,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAMnE,kGAAkG;AAClG,MAAM,WAAW,gBAAgB;IAC7B,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;CACd;AAED,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAC9B,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,+FAA+F;AAC/F,MAAM,WAAW,0BAA0B;IACvC,MAAM,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,gBAAgB,GAAG,uBAAuB,GAAG,oBAAoB,GAAG,QAAQ,CAAC,CAAC;IAC5G,cAAc,CAAC,EAAE,OAAO,2BAA2B,CAAC;IACpD,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACzC;AAED;;;GAGG;AACH,qBAAa,sBAAsB;IAO3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqG;IAC5H,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;IACpE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;gBAGjC,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,EAAE,uBAAuB,EAClD,IAAI,GAAE,0BAA+B;IAazC;;OAEG;IACU,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwBvI;;OAEG;IACU,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;YAkBhI,WAAW;IAsCzB,OAAO,CAAC,eAAe;IAQhB,YAAY,IAAI,sBAAsB;IAgB7C,OAAO,CAAC,yBAAyB;YAWnB,2BAA2B;YAsB3B,iBAAiB;CAQlC"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * @fileoverview Orchestrates Vonage telephony bridge sessions (inbound + outbound) for MJAPI.
3
+ *
4
+ * @module @memberjunction/telephony-adapters
5
+ */
6
+ import { RunView, LogError } from '@memberjunction/core';
7
+ import { EscapeSQLString } from '@memberjunction/global';
8
+ import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
9
+ import { CreateBridgeRealtimeSession } from '@memberjunction/ai-agents';
10
+ import { DIRECTION_CONFIG_KEY, FROM_NUMBER_CONFIG_KEY, INBOUND_CALL_ID_CONFIG_KEY, } from '@memberjunction/ai-bridge-base';
11
+ import { VonageCallSdk, RealVonageBindings, RealVonageVoiceClient } from '@memberjunction/ai-bridge-vonage';
12
+ import { DefaultAgentSessionManager } from '../sessionManager.js';
13
+ const VONAGE_PROVIDER_DRIVER = 'VonageBridge';
14
+ const AGENT_IDENTITY_ENTITY = 'MJ: AI Bridge Agent Identities';
15
+ const PHONE_IDENTITY_TYPE = 'PhoneNumber';
16
+ /**
17
+ * Starts Vonage bridge sessions. One instance per server, constructed alongside the telephony router and
18
+ * sharing the {@link VonageCallMediaRegistry} with the media WSS server.
19
+ */
20
+ export class VonageTelephonyService {
21
+ constructor(config, registry, deps = {}) {
22
+ this.config = config;
23
+ this.registry = registry;
24
+ this.voice = new RealVonageVoiceClient({
25
+ ApplicationId: config.applicationId,
26
+ PrivateKey: config.privateKey,
27
+ ApiKey: config.apiKey,
28
+ ApiSecret: config.apiSecret,
29
+ });
30
+ this.engine = deps.engine ?? AIBridgeEngine.Instance;
31
+ this.sessionFactory = deps.sessionFactory ?? CreateBridgeRealtimeSession;
32
+ this.sessionManager = deps.sessionManager ?? new DefaultAgentSessionManager();
33
+ }
34
+ /**
35
+ * Resolves the dialed DID to a pinned agent and starts an INBOUND bridge session.
36
+ */
37
+ async HandleInboundCall(input, contextUser, provider) {
38
+ try {
39
+ await this.engine.Config(false, contextUser, provider);
40
+ const vonageProvider = this.resolveProvider();
41
+ const identity = await this.resolveAgentIdentityByPhone(input.to, vonageProvider.ID, contextUser);
42
+ if (!identity) {
43
+ return { accepted: false, reason: `No active agent identity for dialed number '${input.to}'.` };
44
+ }
45
+ this.registry.RegisterCall(input.callId);
46
+ await this.startBridge({
47
+ agentID: identity.AgentID,
48
+ direction: 'Inbound',
49
+ address: input.from,
50
+ inboundCallId: input.callId,
51
+ contextUser,
52
+ provider,
53
+ });
54
+ return { accepted: true };
55
+ }
56
+ catch (e) {
57
+ LogError(`[Telephony][Vonage] inbound call ${input.callId} failed: ${e instanceof Error ? e.message : String(e)}`);
58
+ return { accepted: false, reason: 'Internal error starting the agent.' };
59
+ }
60
+ }
61
+ /**
62
+ * Places an OUTBOUND call from a given agent identity to a destination number.
63
+ */
64
+ async PlaceOutboundCall(agentIdentityId, toNumber, contextUser, provider) {
65
+ const identity = await this.loadAgentIdentity(agentIdentityId, contextUser, provider);
66
+ if (!identity) {
67
+ throw new Error(`Agent identity '${agentIdentityId}' not found or inactive.`);
68
+ }
69
+ const session = await this.startBridge({
70
+ agentID: identity.AgentID,
71
+ direction: 'Outbound',
72
+ address: toNumber,
73
+ fromNumber: identity.IdentityValue,
74
+ contextUser,
75
+ provider,
76
+ });
77
+ return session.RoomKey ?? '';
78
+ }
79
+ // ── internals ────────────────────────────────────────────────────────────────
80
+ async startBridge(args) {
81
+ await this.engine.Config(false, args.contextUser, args.provider);
82
+ const vonageProvider = this.resolveProvider();
83
+ const agentSession = await this.sessionManager.CreateSession({ agentID: args.agentID, userID: args.contextUser.ID }, args.contextUser, args.provider);
84
+ const realtimeSession = await this.sessionFactory({
85
+ AgentID: args.agentID,
86
+ TargetAgentID: args.agentID,
87
+ ContextUser: args.contextUser,
88
+ MetadataProvider: args.provider,
89
+ AgentSessionID: agentSession.ID,
90
+ RoomName: args.address,
91
+ });
92
+ const active = await this.engine.StartBridgeSession({
93
+ AgentSessionID: agentSession.ID,
94
+ AgentID: args.agentID,
95
+ TargetAgentID: args.agentID,
96
+ Provider: vonageProvider,
97
+ RealtimeSession: realtimeSession,
98
+ Address: args.address,
99
+ Direction: args.direction,
100
+ Configuration: this.buildSessionConfiguration(args.direction, args.fromNumber, args.inboundCallId),
101
+ BindSdk: this.buildBindSdk(),
102
+ ContextUser: args.contextUser,
103
+ MetadataProvider: args.provider,
104
+ });
105
+ return { RoomKey: active.RoomKey };
106
+ }
107
+ resolveProvider() {
108
+ const provider = this.engine.ProviderByDriverClass(VONAGE_PROVIDER_DRIVER) ?? this.engine.ProviderByName('Vonage');
109
+ if (!provider) {
110
+ throw new Error(`No active 'MJ: AI Bridge Providers' row for the Vonage bridge (DriverClass '${VONAGE_PROVIDER_DRIVER}').`);
111
+ }
112
+ return provider;
113
+ }
114
+ buildBindSdk() {
115
+ return (driver) => {
116
+ const telephony = driver;
117
+ telephony.SetSdkFactory(() => new VonageCallSdk(new RealVonageBindings({
118
+ Voice: this.voice,
119
+ MediaPump: this.registry,
120
+ MediaWssUrl: this.config.mediaPublicUrl,
121
+ EventUrl: this.config.eventUrl,
122
+ })));
123
+ };
124
+ }
125
+ buildSessionConfiguration(direction, fromNumber, inboundCallId) {
126
+ const config = { [DIRECTION_CONFIG_KEY]: direction };
127
+ if (fromNumber) {
128
+ config[FROM_NUMBER_CONFIG_KEY] = fromNumber;
129
+ }
130
+ if (inboundCallId) {
131
+ config[INBOUND_CALL_ID_CONFIG_KEY] = inboundCallId;
132
+ }
133
+ return config;
134
+ }
135
+ async resolveAgentIdentityByPhone(dialedNumber, providerId, contextUser) {
136
+ const normalized = (dialedNumber ?? '').trim();
137
+ if (!normalized) {
138
+ return null;
139
+ }
140
+ const rv = new RunView();
141
+ const result = await rv.RunView({
142
+ EntityName: AGENT_IDENTITY_ENTITY,
143
+ ExtraFilter: `IdentityType='${PHONE_IDENTITY_TYPE}' AND IdentityValue='${EscapeSQLString(normalized)}' AND ProviderID='${EscapeSQLString(providerId)}' AND IsActive=1`,
144
+ MaxRows: 1,
145
+ ResultType: 'entity_object',
146
+ }, contextUser);
147
+ if (!result.Success) {
148
+ LogError(`[Telephony][Vonage] agent-identity lookup failed: ${result.ErrorMessage}`);
149
+ return null;
150
+ }
151
+ return result.Results?.[0] ?? null;
152
+ }
153
+ async loadAgentIdentity(agentIdentityId, contextUser, provider) {
154
+ const entity = await provider.GetEntityObject(AGENT_IDENTITY_ENTITY, contextUser);
155
+ const loaded = await entity.Load(agentIdentityId);
156
+ if (!loaded || !entity.IsActive) {
157
+ return null;
158
+ }
159
+ return entity;
160
+ }
161
+ }
162
+ //# sourceMappingURL=VonageTelephonyService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VonageTelephonyService.js","sourceRoot":"","sources":["../../src/telephony/VonageTelephonyService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @fileoverview Host wiring for the scheduled/invite-driven meeting join loop (program M2).
3
+ *
4
+ * @module @memberjunction/telephony-adapters
5
+ */
6
+ import { UserInfo, IMetadataProvider } from '@memberjunction/core';
7
+ import { type CalendarSourceResolver, type ScheduledBridgeSessionFactory } from '@memberjunction/ai-bridge-server';
8
+ import type { TeamsMeetingsConfig } from '../types.js';
9
+ import { TeamsMeetingsService } from './TeamsMeetingsService.js';
10
+ /** Options for {@link StartCalendarScheduler}. */
11
+ export interface CalendarSchedulerOptions {
12
+ /** The server metadata provider all reads/writes run under. */
13
+ Provider: IMetadataProvider;
14
+ /** The system user the watcher + runner (and every created/started bridge) run as. */
15
+ ContextUser: UserInfo;
16
+ /** The Teams meetings service (shared with the ingress) — supplies the scheduled-join bind-sdk. */
17
+ TeamsService: TeamsMeetingsService;
18
+ /** The Teams meetings config — supplies the bot Graph access token for calendar polling. */
19
+ TeamsConfig: TeamsMeetingsConfig;
20
+ /** Poll cadence (ms). Defaults to {@link DEFAULT_POLL_INTERVAL_MS}. */
21
+ PollIntervalMs?: number;
22
+ }
23
+ /** A running scheduler handle — call {@link CalendarSchedulerHandle.Stop} to clear the interval. */
24
+ export interface CalendarSchedulerHandle {
25
+ /** Stops the periodic sweep/run loop (clears the timer). Safe to call more than once. */
26
+ Stop(): void;
27
+ }
28
+ /**
29
+ * Builds the {@link CalendarSourceResolver} that binds the real calendar clients per identity.
30
+ */
31
+ export declare function buildCalendarSourceResolver(teamsConfig: TeamsMeetingsConfig): CalendarSourceResolver;
32
+ /**
33
+ * Builds the {@link ScheduledBridgeSessionFactory} that turns a due bridge into start params.
34
+ */
35
+ export declare function buildScheduledSessionFactory(teamsService: TeamsMeetingsService): ScheduledBridgeSessionFactory;
36
+ /**
37
+ * Starts the calendar/scheduled-bridge loop: sweeps calendars and runs due bridges once immediately,
38
+ * then on a fixed interval.
39
+ */
40
+ export declare function StartCalendarScheduler(options: CalendarSchedulerOptions): CalendarSchedulerHandle;
41
+ //# sourceMappingURL=calendar-scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-scheduler.d.ts","sourceRoot":"","sources":["../../src/telephony/calendar-scheduler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAuB,MAAM,sBAAsB,CAAC;AAExF,OAAO,EAKH,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,EAErC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAQjE,kDAAkD;AAClD,MAAM,WAAW,wBAAwB;IACrC,+DAA+D;IAC/D,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,sFAAsF;IACtF,WAAW,EAAE,QAAQ,CAAC;IACtB,mGAAmG;IACnG,YAAY,EAAE,oBAAoB,CAAC;IACnC,4FAA4F;IAC5F,WAAW,EAAE,mBAAmB,CAAC;IACjC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,oGAAoG;AACpG,MAAM,WAAW,uBAAuB;IACpC,yFAAyF;IACzF,IAAI,IAAI,IAAI,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,mBAAmB,GAAG,sBAAsB,CAQpG;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,oBAAoB,GAAG,6BAA6B,CAyB9G;AAeD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,wBAAwB,GAAG,uBAAuB,CAkCjG"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @fileoverview Host wiring for the scheduled/invite-driven meeting join loop (program M2).
3
+ *
4
+ * @module @memberjunction/telephony-adapters
5
+ */
6
+ import { LogStatus, LogError } from '@memberjunction/core';
7
+ import { CalendarWatcher, ScheduledBridgeRunner, GraphCalendarSource, GraphCalendarClient, } from '@memberjunction/ai-bridge-server';
8
+ /** The Teams bridge driver class — identities/bridges on this provider poll Graph + join via the Teams service. */
9
+ const TEAMS_PROVIDER_DRIVER = 'TeamsBridge';
10
+ /** Default cadence (ms) for the calendar sweep + due-bridge run. 60s balances freshness vs. API quota. */
11
+ const DEFAULT_POLL_INTERVAL_MS = 60_000;
12
+ /**
13
+ * Builds the {@link CalendarSourceResolver} that binds the real calendar clients per identity.
14
+ */
15
+ export function buildCalendarSourceResolver(teamsConfig) {
16
+ return (_identity, provider) => {
17
+ const driver = provider?.DriverClass?.trim();
18
+ if (driver === TEAMS_PROVIDER_DRIVER && teamsConfig.botAccessToken) {
19
+ return new GraphCalendarSource(new GraphCalendarClient({ Credentials: { AccessToken: teamsConfig.botAccessToken } }));
20
+ }
21
+ return null;
22
+ };
23
+ }
24
+ /**
25
+ * Builds the {@link ScheduledBridgeSessionFactory} that turns a due bridge into start params.
26
+ */
27
+ export function buildScheduledSessionFactory(teamsService) {
28
+ return async (ctx) => {
29
+ const joinUrl = ctx.BridgeRow.Address?.trim();
30
+ if (!joinUrl) {
31
+ LogStatus(`[CalendarScheduler] bridge ${ctx.BridgeRow.ID} has no join address; skipping.`);
32
+ return null;
33
+ }
34
+ if (ctx.Provider.DriverClass?.trim() !== TEAMS_PROVIDER_DRIVER) {
35
+ LogStatus(`[CalendarScheduler] no scheduled-join wiring for provider '${ctx.Provider.Name}'; skipping bridge ${ctx.BridgeRow.ID}.`);
36
+ return null;
37
+ }
38
+ const agentID = await resolveAgentID(ctx.BridgeRow.AgentSessionID, ctx.ContextUser, ctx.MetadataProvider);
39
+ if (!agentID) {
40
+ LogStatus(`[CalendarScheduler] could not resolve agent for session ${ctx.BridgeRow.AgentSessionID}; skipping.`);
41
+ return null;
42
+ }
43
+ const params = await teamsService.BuildScheduledStartParams({
44
+ agentID,
45
+ joinUrl,
46
+ agentSessionID: ctx.BridgeRow.AgentSessionID,
47
+ contextUser: ctx.ContextUser,
48
+ provider: ctx.MetadataProvider,
49
+ });
50
+ return params;
51
+ };
52
+ }
53
+ /** Loads the `AIAgentSession` to resolve the agent the scheduled bridge belongs to. */
54
+ async function resolveAgentID(agentSessionID, contextUser, provider) {
55
+ const session = await provider.GetEntityObject('MJ: AI Agent Sessions', contextUser);
56
+ if (!(await session.Load(agentSessionID))) {
57
+ return null;
58
+ }
59
+ return session.AgentID;
60
+ }
61
+ /**
62
+ * Starts the calendar/scheduled-bridge loop: sweeps calendars and runs due bridges once immediately,
63
+ * then on a fixed interval.
64
+ */
65
+ export function StartCalendarScheduler(options) {
66
+ const watcher = new CalendarWatcher({
67
+ SourceResolver: buildCalendarSourceResolver(options.TeamsConfig),
68
+ ContextUser: options.ContextUser,
69
+ MetadataProvider: options.Provider,
70
+ });
71
+ const runner = new ScheduledBridgeRunner({
72
+ SessionFactory: buildScheduledSessionFactory(options.TeamsService),
73
+ ContextUser: options.ContextUser,
74
+ MetadataProvider: options.Provider,
75
+ });
76
+ const tick = async () => {
77
+ try {
78
+ const swept = await watcher.Sweep();
79
+ const ran = await runner.RunDueBridges();
80
+ if (swept.BridgesCreated > 0 || ran.Started > 0) {
81
+ LogStatus(`[CalendarScheduler] swept ${swept.BridgesCreated} new bridge(s); started ${ran.Started} due bridge(s).`);
82
+ }
83
+ }
84
+ catch (err) {
85
+ LogError(`[CalendarScheduler] sweep/run pass failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
86
+ }
87
+ };
88
+ void tick(); // run-once at boot
89
+ const timer = setInterval(() => void tick(), options.PollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
90
+ timer.unref?.();
91
+ LogStatus(`[CalendarScheduler] started (every ${(options.PollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS) / 1000}s).`);
92
+ return {
93
+ Stop() {
94
+ clearInterval(timer);
95
+ },
96
+ };
97
+ }
98
+ //# sourceMappingURL=calendar-scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-scheduler.js","sourceRoot":"","sources":["../../src/telephony/calendar-scheduler.ts"],"names":[],"mappings":"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"}