@memberjunction/server 5.44.0 → 5.45.1

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 (267) hide show
  1. package/dist/agentSessions/ReturningVisitorRecap.d.ts +39 -0
  2. package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -0
  3. package/dist/agentSessions/ReturningVisitorRecap.js +198 -0
  4. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -0
  5. package/dist/agentSessions/SessionJanitor.d.ts +13 -0
  6. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  7. package/dist/agentSessions/SessionJanitor.js +65 -7
  8. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  9. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  10. package/dist/agentSessions/SessionManager.js +37 -0
  11. package/dist/agentSessions/SessionManager.js.map +1 -1
  12. package/dist/auth/magicLink/MagicLinkRouter.d.ts +10 -0
  13. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  14. package/dist/auth/magicLink/MagicLinkRouter.js +16 -0
  15. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  16. package/dist/auth/magicLink/MagicLinkService.d.ts +7 -0
  17. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  18. package/dist/auth/magicLink/MagicLinkService.js +13 -3
  19. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  20. package/dist/auth/magicLink/index.d.ts +1 -1
  21. package/dist/auth/magicLink/index.d.ts.map +1 -1
  22. package/dist/auth/magicLink/index.js +1 -1
  23. package/dist/auth/magicLink/index.js.map +1 -1
  24. package/dist/auth/magicLink/magicLinkCore.d.ts +38 -1
  25. package/dist/auth/magicLink/magicLinkCore.d.ts.map +1 -1
  26. package/dist/auth/magicLink/magicLinkCore.js +42 -19
  27. package/dist/auth/magicLink/magicLinkCore.js.map +1 -1
  28. package/dist/auth/magicLink/types.d.ts +26 -0
  29. package/dist/auth/magicLink/types.d.ts.map +1 -1
  30. package/dist/config.d.ts +1883 -144
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +160 -36
  33. package/dist/config.js.map +1 -1
  34. package/dist/context.d.ts.map +1 -1
  35. package/dist/context.js +45 -2
  36. package/dist/context.js.map +1 -1
  37. package/dist/generated/generated.d.ts +522 -0
  38. package/dist/generated/generated.d.ts.map +1 -1
  39. package/dist/generated/generated.js +2860 -0
  40. package/dist/generated/generated.js.map +1 -1
  41. package/dist/generic/ResolverBase.d.ts +13 -0
  42. package/dist/generic/ResolverBase.d.ts.map +1 -1
  43. package/dist/generic/ResolverBase.js +22 -0
  44. package/dist/generic/ResolverBase.js.map +1 -1
  45. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  46. package/dist/generic/RunViewResolver.js +4 -0
  47. package/dist/generic/RunViewResolver.js.map +1 -1
  48. package/dist/index.d.ts +0 -2
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +101 -3
  51. package/dist/index.js.map +1 -1
  52. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  53. package/dist/integration/CustomColumnPromoter.js +6 -0
  54. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  55. package/dist/realtimeWidget/WidgetRouter.d.ts +26 -0
  56. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -0
  57. package/dist/realtimeWidget/WidgetRouter.js +182 -0
  58. package/dist/realtimeWidget/WidgetRouter.js.map +1 -0
  59. package/dist/realtimeWidget/WidgetSessionService.d.ts +265 -0
  60. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -0
  61. package/dist/realtimeWidget/WidgetSessionService.js +477 -0
  62. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -0
  63. package/dist/realtimeWidget/host-identity.d.ts +40 -0
  64. package/dist/realtimeWidget/host-identity.d.ts.map +1 -0
  65. package/dist/realtimeWidget/host-identity.js +58 -0
  66. package/dist/realtimeWidget/host-identity.js.map +1 -0
  67. package/dist/realtimeWidget/index.d.ts +10 -0
  68. package/dist/realtimeWidget/index.d.ts.map +1 -0
  69. package/dist/realtimeWidget/index.js +9 -0
  70. package/dist/realtimeWidget/index.js.map +1 -0
  71. package/dist/realtimeWidget/visitorIdentity.d.ts +76 -0
  72. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -0
  73. package/dist/realtimeWidget/visitorIdentity.js +202 -0
  74. package/dist/realtimeWidget/visitorIdentity.js.map +1 -0
  75. package/dist/realtimeWidget/widgetCore.d.ts +106 -0
  76. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -0
  77. package/dist/realtimeWidget/widgetCore.js +173 -0
  78. package/dist/realtimeWidget/widgetCore.js.map +1 -0
  79. package/dist/realtimeWidget/widgetGuestElevation.d.ts +51 -0
  80. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -0
  81. package/dist/realtimeWidget/widgetGuestElevation.js +79 -0
  82. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -0
  83. package/dist/resolvers/ComponentRegistryResolver.d.ts +7 -0
  84. package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -1
  85. package/dist/resolvers/ComponentRegistryResolver.js +31 -8
  86. package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
  87. package/dist/resolvers/EntityPermissionResolver.d.ts.map +1 -1
  88. package/dist/resolvers/EntityPermissionResolver.js +1 -2
  89. package/dist/resolvers/EntityPermissionResolver.js.map +1 -1
  90. package/dist/resolvers/QuerySystemUserResolver.d.ts +9 -6
  91. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  92. package/dist/resolvers/QuerySystemUserResolver.js +15 -13
  93. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  94. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +10 -0
  95. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  96. package/dist/resolvers/RealtimeClientSessionResolver.js +47 -3
  97. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  98. package/dist/resolvers/RingCentralTelephonyResolver.d.ts +27 -0
  99. package/dist/resolvers/RingCentralTelephonyResolver.d.ts.map +1 -0
  100. package/dist/resolvers/RingCentralTelephonyResolver.js +87 -0
  101. package/dist/resolvers/RingCentralTelephonyResolver.js.map +1 -0
  102. package/dist/resolvers/RunAIAgentResolver.d.ts +9 -0
  103. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  104. package/dist/resolvers/RunAIAgentResolver.js +20 -4
  105. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  106. package/dist/resolvers/SearchKnowledgeResolver.d.ts.map +1 -1
  107. package/dist/resolvers/SearchKnowledgeResolver.js +2 -0
  108. package/dist/resolvers/SearchKnowledgeResolver.js.map +1 -1
  109. package/dist/resolvers/TeamsMeetingsResolver.d.ts +28 -0
  110. package/dist/resolvers/TeamsMeetingsResolver.d.ts.map +1 -0
  111. package/dist/resolvers/TeamsMeetingsResolver.js +91 -0
  112. package/dist/resolvers/TeamsMeetingsResolver.js.map +1 -0
  113. package/dist/resolvers/TelephonyResolver.d.ts +26 -0
  114. package/dist/resolvers/TelephonyResolver.d.ts.map +1 -0
  115. package/dist/resolvers/TelephonyResolver.js +86 -0
  116. package/dist/resolvers/TelephonyResolver.js.map +1 -0
  117. package/dist/resolvers/TestQuerySQLResolver.d.ts +1 -1
  118. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  119. package/dist/resolvers/TestQuerySQLResolver.js +2 -3
  120. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  121. package/dist/resolvers/VonageTelephonyResolver.d.ts +26 -0
  122. package/dist/resolvers/VonageTelephonyResolver.d.ts.map +1 -0
  123. package/dist/resolvers/VonageTelephonyResolver.js +86 -0
  124. package/dist/resolvers/VonageTelephonyResolver.js.map +1 -0
  125. package/dist/rest/MediaStreamHandler.js +4 -1
  126. package/dist/rest/MediaStreamHandler.js.map +1 -1
  127. package/dist/telephony/RingCentralTelephonyService.d.ts +115 -0
  128. package/dist/telephony/RingCentralTelephonyService.d.ts.map +1 -0
  129. package/dist/telephony/RingCentralTelephonyService.js +262 -0
  130. package/dist/telephony/RingCentralTelephonyService.js.map +1 -0
  131. package/dist/telephony/TeamsMeetingsRouter.d.ts +40 -0
  132. package/dist/telephony/TeamsMeetingsRouter.d.ts.map +1 -0
  133. package/dist/telephony/TeamsMeetingsRouter.js +96 -0
  134. package/dist/telephony/TeamsMeetingsRouter.js.map +1 -0
  135. package/dist/telephony/TeamsMeetingsService.d.ts +113 -0
  136. package/dist/telephony/TeamsMeetingsService.d.ts.map +1 -0
  137. package/dist/telephony/TeamsMeetingsService.js +196 -0
  138. package/dist/telephony/TeamsMeetingsService.js.map +1 -0
  139. package/dist/telephony/TwilioTelephonyRouter.d.ts +36 -0
  140. package/dist/telephony/TwilioTelephonyRouter.d.ts.map +1 -0
  141. package/dist/telephony/TwilioTelephonyRouter.js +143 -0
  142. package/dist/telephony/TwilioTelephonyRouter.js.map +1 -0
  143. package/dist/telephony/TwilioTelephonyService.d.ts +95 -0
  144. package/dist/telephony/TwilioTelephonyService.d.ts.map +1 -0
  145. package/dist/telephony/TwilioTelephonyService.js +193 -0
  146. package/dist/telephony/TwilioTelephonyService.js.map +1 -0
  147. package/dist/telephony/VonageTelephonyRouter.d.ts +41 -0
  148. package/dist/telephony/VonageTelephonyRouter.d.ts.map +1 -0
  149. package/dist/telephony/VonageTelephonyRouter.js +201 -0
  150. package/dist/telephony/VonageTelephonyRouter.js.map +1 -0
  151. package/dist/telephony/VonageTelephonyService.d.ts +90 -0
  152. package/dist/telephony/VonageTelephonyService.d.ts.map +1 -0
  153. package/dist/telephony/VonageTelephonyService.js +191 -0
  154. package/dist/telephony/VonageTelephonyService.js.map +1 -0
  155. package/dist/telephony/calendar-scheduler.d.ts +67 -0
  156. package/dist/telephony/calendar-scheduler.d.ts.map +1 -0
  157. package/dist/telephony/calendar-scheduler.js +133 -0
  158. package/dist/telephony/calendar-scheduler.js.map +1 -0
  159. package/dist/telephony/index.d.ts +29 -0
  160. package/dist/telephony/index.d.ts.map +1 -0
  161. package/dist/telephony/index.js +38 -0
  162. package/dist/telephony/index.js.map +1 -0
  163. package/dist/telephony/media-upgrade-router.d.ts +33 -0
  164. package/dist/telephony/media-upgrade-router.d.ts.map +1 -0
  165. package/dist/telephony/media-upgrade-router.js +56 -0
  166. package/dist/telephony/media-upgrade-router.js.map +1 -0
  167. package/dist/telephony/ringcentral-runtime.d.ts +14 -0
  168. package/dist/telephony/ringcentral-runtime.d.ts.map +1 -0
  169. package/dist/telephony/ringcentral-runtime.js +18 -0
  170. package/dist/telephony/ringcentral-runtime.js.map +1 -0
  171. package/dist/telephony/teams-meetings-runtime.d.ts +16 -0
  172. package/dist/telephony/teams-meetings-runtime.d.ts.map +1 -0
  173. package/dist/telephony/teams-meetings-runtime.js +20 -0
  174. package/dist/telephony/teams-meetings-runtime.js.map +1 -0
  175. package/dist/telephony/teamsAcsMediaRegistry.d.ts +69 -0
  176. package/dist/telephony/teamsAcsMediaRegistry.d.ts.map +1 -0
  177. package/dist/telephony/teamsAcsMediaRegistry.js +118 -0
  178. package/dist/telephony/teamsAcsMediaRegistry.js.map +1 -0
  179. package/dist/telephony/telephony-runtime.d.ts +14 -0
  180. package/dist/telephony/telephony-runtime.d.ts.map +1 -0
  181. package/dist/telephony/telephony-runtime.js +18 -0
  182. package/dist/telephony/telephony-runtime.js.map +1 -0
  183. package/dist/telephony/twilioMediaRegistry.d.ts +60 -0
  184. package/dist/telephony/twilioMediaRegistry.d.ts.map +1 -0
  185. package/dist/telephony/twilioMediaRegistry.js +106 -0
  186. package/dist/telephony/twilioMediaRegistry.js.map +1 -0
  187. package/dist/telephony/vonage-runtime.d.ts +14 -0
  188. package/dist/telephony/vonage-runtime.d.ts.map +1 -0
  189. package/dist/telephony/vonage-runtime.js +18 -0
  190. package/dist/telephony/vonage-runtime.js.map +1 -0
  191. package/dist/telephony/vonageMediaRegistry.d.ts +78 -0
  192. package/dist/telephony/vonageMediaRegistry.d.ts.map +1 -0
  193. package/dist/telephony/vonageMediaRegistry.js +158 -0
  194. package/dist/telephony/vonageMediaRegistry.js.map +1 -0
  195. package/package.json +88 -83
  196. package/src/__tests__/RunAIAgentResolver.streaming.test.ts +128 -0
  197. package/src/__tests__/magicLink.test.ts +53 -3
  198. package/src/__tests__/search-knowledge-tags.test.ts +9 -9
  199. package/src/__tests__/teams-meetings-service.test.ts +65 -0
  200. package/src/__tests__/teamsAcsMediaRegistry.test.ts +82 -0
  201. package/src/__tests__/twilio-telephony-service.test.ts +23 -0
  202. package/src/__tests__/twilioMediaRegistry.test.ts +103 -0
  203. package/src/__tests__/vonageMediaRegistry.test.ts +180 -0
  204. package/src/__tests__/widget.test.ts +204 -0
  205. package/src/__tests__/widgetGuestElevation.test.ts +57 -0
  206. package/src/__tests__/widgetHostIdentity.test.ts +117 -0
  207. package/src/agentSessions/ReturningVisitorRecap.ts +242 -0
  208. package/src/agentSessions/SessionJanitor.ts +66 -6
  209. package/src/agentSessions/SessionManager.ts +38 -0
  210. package/src/auth/magicLink/MagicLinkRouter.ts +17 -0
  211. package/src/auth/magicLink/MagicLinkService.ts +13 -3
  212. package/src/auth/magicLink/index.ts +1 -0
  213. package/src/auth/magicLink/magicLinkCore.ts +48 -20
  214. package/src/auth/magicLink/types.ts +26 -0
  215. package/src/config.ts +172 -38
  216. package/src/context.ts +50 -3
  217. package/src/generated/generated.ts +1991 -1
  218. package/src/generic/ResolverBase.ts +28 -0
  219. package/src/generic/RunViewResolver.ts +4 -0
  220. package/src/index.ts +109 -3
  221. package/src/integration/CustomColumnPromoter.ts +6 -0
  222. package/src/realtimeWidget/WidgetRouter.ts +204 -0
  223. package/src/realtimeWidget/WidgetSessionService.ts +714 -0
  224. package/src/realtimeWidget/host-identity.ts +84 -0
  225. package/src/realtimeWidget/index.ts +15 -0
  226. package/src/realtimeWidget/visitorIdentity.ts +258 -0
  227. package/src/realtimeWidget/widgetCore.ts +231 -0
  228. package/src/realtimeWidget/widgetGuestElevation.ts +115 -0
  229. package/src/resolvers/ComponentRegistryResolver.ts +36 -10
  230. package/src/resolvers/EntityPermissionResolver.ts +1 -2
  231. package/src/resolvers/QuerySystemUserResolver.ts +14 -10
  232. package/src/resolvers/RealtimeClientSessionResolver.ts +59 -2
  233. package/src/resolvers/RingCentralTelephonyResolver.ts +64 -0
  234. package/src/resolvers/RunAIAgentResolver.ts +32 -8
  235. package/src/resolvers/SearchKnowledgeResolver.ts +2 -0
  236. package/src/resolvers/TeamsMeetingsResolver.ts +68 -0
  237. package/src/resolvers/TelephonyResolver.ts +63 -0
  238. package/src/resolvers/TestQuerySQLResolver.ts +2 -3
  239. package/src/resolvers/VonageTelephonyResolver.ts +63 -0
  240. package/src/rest/MediaStreamHandler.ts +4 -1
  241. package/src/telephony/RingCentralTelephonyService.ts +342 -0
  242. package/src/telephony/TeamsMeetingsRouter.ts +124 -0
  243. package/src/telephony/TeamsMeetingsService.ts +268 -0
  244. package/src/telephony/TwilioTelephonyRouter.ts +184 -0
  245. package/src/telephony/TwilioTelephonyService.ts +261 -0
  246. package/src/telephony/VonageTelephonyRouter.ts +239 -0
  247. package/src/telephony/VonageTelephonyService.ts +259 -0
  248. package/src/telephony/calendar-scheduler.ts +176 -0
  249. package/src/telephony/index.ts +43 -0
  250. package/src/telephony/media-upgrade-router.ts +62 -0
  251. package/src/telephony/ringcentral-runtime.ts +22 -0
  252. package/src/telephony/teams-meetings-runtime.ts +24 -0
  253. package/src/telephony/teamsAcsMediaRegistry.ts +152 -0
  254. package/src/telephony/telephony-runtime.ts +22 -0
  255. package/src/telephony/twilioMediaRegistry.ts +137 -0
  256. package/src/telephony/vonage-runtime.ts +22 -0
  257. package/src/telephony/vonageMediaRegistry.ts +200 -0
  258. package/dist/agents/skip-agent.d.ts +0 -111
  259. package/dist/agents/skip-agent.d.ts.map +0 -1
  260. package/dist/agents/skip-agent.js +0 -1487
  261. package/dist/agents/skip-agent.js.map +0 -1
  262. package/dist/agents/skip-sdk.d.ts +0 -261
  263. package/dist/agents/skip-sdk.d.ts.map +0 -1
  264. package/dist/agents/skip-sdk.js +0 -909
  265. package/dist/agents/skip-sdk.js.map +0 -1
  266. package/src/agents/skip-agent.ts +0 -1594
  267. package/src/agents/skip-sdk.ts +0 -1210
@@ -0,0 +1,133 @@
1
+ /**
2
+ * @fileoverview Host wiring for the scheduled/invite-driven meeting join loop (program M2).
3
+ *
4
+ * Composes the offline-complete seams from `@memberjunction/ai-bridge-server` into a running
5
+ * background loop, mirroring the {@link SessionJanitor} startup pattern (run once at boot, then on an
6
+ * interval):
7
+ *
8
+ * 1. {@link CalendarWatcher} polls each agent identity's calendar (via the injected
9
+ * {@link CalendarSourceResolver}, bound here to the real {@link GraphCalendarClient} /
10
+ * {@link GoogleCalendarClient}) and creates a `Scheduled` `AIAgentSessionBridge` for every invite
11
+ * addressed to the agent.
12
+ * 2. {@link ScheduledBridgeRunner} starts each bridge whose `ScheduledStartTime` is due, building the
13
+ * realtime session + the provider bind-sdk via the per-provider meeting service (Teams today).
14
+ *
15
+ * Calendar credentials are PRE-RESOLVED upstream (the bot's Graph access token comes from the Teams
16
+ * meetings config — `botAccessToken`, resolved via MJ config, never inline). Google calendar polling
17
+ * binds only when a Google auth client is supplied; otherwise those identities are skipped (the watcher
18
+ * tolerates a `null` source per identity). Live verification requires a real tenant + the Azure app /
19
+ * Google service account — the same access the meeting bridges need.
20
+ *
21
+ * @module @memberjunction/server/telephony
22
+ */
23
+ import { LogStatus, LogError } from '@memberjunction/core';
24
+ import { CalendarWatcher, ScheduledBridgeRunner, GraphCalendarSource, GraphCalendarClient, } from '@memberjunction/ai-bridge-server';
25
+ /** The Teams bridge driver class — identities/bridges on this provider poll Graph + join via the Teams service. */
26
+ const TEAMS_PROVIDER_DRIVER = 'TeamsBridge';
27
+ /** Default cadence (ms) for the calendar sweep + due-bridge run. 60s balances freshness vs. API quota. */
28
+ const DEFAULT_POLL_INTERVAL_MS = 60_000;
29
+ /**
30
+ * Builds the {@link CalendarSourceResolver} that binds the real calendar clients per identity. Graph
31
+ * (Teams/Microsoft) identities bind a {@link GraphCalendarClient} authenticated with the bot's
32
+ * pre-resolved Graph token; any identity without configured credentials resolves to `null` and is
33
+ * skipped this sweep (the watcher tolerates that). Google binding activates when a Google auth client
34
+ * is wired into the deployment (none configured today → Google-backed identities are skipped).
35
+ */
36
+ export function buildCalendarSourceResolver(teamsConfig) {
37
+ return (_identity, provider) => {
38
+ const driver = provider?.DriverClass?.trim();
39
+ if (driver === TEAMS_PROVIDER_DRIVER && teamsConfig.botAccessToken) {
40
+ return new GraphCalendarSource(new GraphCalendarClient({ Credentials: { AccessToken: teamsConfig.botAccessToken } }));
41
+ }
42
+ // Google Calendar is a deliberate, CLOSED seam — intentionally not bound here. The
43
+ // GoogleCalendarClient is built + unit-tested, but binding it would be dead code today:
44
+ // 1. there is no Google Meet *join* path for a detected invite to trigger (the scheduled-join
45
+ // factory is Teams-only), and
46
+ // 2. Google's Meet Media API is Developer-Preview + allowlist-gated regardless (every meeting
47
+ // participant must be enrolled), so it isn't a shippable target.
48
+ // To activate: define a Google auth client from config AND wire a Google Meet join. Until then
49
+ // Google identities are skipped rather than erroring the sweep.
50
+ return null;
51
+ };
52
+ }
53
+ /**
54
+ * Builds the {@link ScheduledBridgeSessionFactory} that turns a due bridge into start params. Resolves
55
+ * the bridge's agent (via its `AIAgentSession`) and, for a Teams bridge, delegates to the shared
56
+ * {@link TeamsMeetingsService} so the scheduled join reuses the exact provider/session/bind-sdk path as
57
+ * an on-demand join. Returns `null` (skip) for a provider with no scheduled-join wiring yet, or when the
58
+ * bridge has no join address.
59
+ */
60
+ export function buildScheduledSessionFactory(teamsService) {
61
+ return async (ctx) => {
62
+ const joinUrl = ctx.BridgeRow.Address?.trim();
63
+ if (!joinUrl) {
64
+ LogStatus(`[CalendarScheduler] bridge ${ctx.BridgeRow.ID} has no join address; skipping.`);
65
+ return null;
66
+ }
67
+ if (ctx.Provider.DriverClass?.trim() !== TEAMS_PROVIDER_DRIVER) {
68
+ LogStatus(`[CalendarScheduler] no scheduled-join wiring for provider '${ctx.Provider.Name}'; skipping bridge ${ctx.BridgeRow.ID}.`);
69
+ return null;
70
+ }
71
+ const agentID = await resolveAgentID(ctx.BridgeRow.AgentSessionID, ctx.ContextUser, ctx.MetadataProvider);
72
+ if (!agentID) {
73
+ LogStatus(`[CalendarScheduler] could not resolve agent for session ${ctx.BridgeRow.AgentSessionID}; skipping.`);
74
+ return null;
75
+ }
76
+ const params = await teamsService.BuildScheduledStartParams({
77
+ agentID,
78
+ joinUrl,
79
+ agentSessionID: ctx.BridgeRow.AgentSessionID,
80
+ contextUser: ctx.ContextUser,
81
+ provider: ctx.MetadataProvider,
82
+ });
83
+ return params;
84
+ };
85
+ }
86
+ /** Loads the `AIAgentSession` to resolve the agent the scheduled bridge belongs to. */
87
+ async function resolveAgentID(agentSessionID, contextUser, provider) {
88
+ const session = await provider.GetEntityObject('MJ: AI Agent Sessions', contextUser);
89
+ if (!(await session.Load(agentSessionID))) {
90
+ return null;
91
+ }
92
+ return session.AgentID;
93
+ }
94
+ /**
95
+ * Starts the calendar/scheduled-bridge loop: sweeps calendars and runs due bridges once immediately,
96
+ * then on a fixed interval. Mirrors {@link SessionJanitor.Start}. A sweep/run failure is logged and the
97
+ * loop continues — a transient calendar/transport error never kills the scheduler.
98
+ */
99
+ export function StartCalendarScheduler(options) {
100
+ const watcher = new CalendarWatcher({
101
+ SourceResolver: buildCalendarSourceResolver(options.TeamsConfig),
102
+ ContextUser: options.ContextUser,
103
+ MetadataProvider: options.Provider,
104
+ });
105
+ const runner = new ScheduledBridgeRunner({
106
+ SessionFactory: buildScheduledSessionFactory(options.TeamsService),
107
+ ContextUser: options.ContextUser,
108
+ MetadataProvider: options.Provider,
109
+ });
110
+ const tick = async () => {
111
+ try {
112
+ const swept = await watcher.Sweep();
113
+ const ran = await runner.RunDueBridges();
114
+ if (swept.BridgesCreated > 0 || ran.Started > 0) {
115
+ LogStatus(`[CalendarScheduler] swept ${swept.BridgesCreated} new bridge(s); started ${ran.Started} due bridge(s).`);
116
+ }
117
+ }
118
+ catch (err) {
119
+ LogError(`[CalendarScheduler] sweep/run pass failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
120
+ }
121
+ };
122
+ void tick(); // run-once at boot
123
+ const timer = setInterval(() => void tick(), options.PollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
124
+ // Don't let the poll timer keep the process alive at shutdown (the loop is best-effort background work).
125
+ timer.unref?.();
126
+ LogStatus(`[CalendarScheduler] started (every ${(options.PollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS) / 1000}s).`);
127
+ return {
128
+ Stop() {
129
+ clearInterval(timer);
130
+ },
131
+ };
132
+ }
133
+ //# 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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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview Public exports for the MJAPI telephony + meetings ingress.
3
+ *
4
+ * Each vendor ingress is a quartet: a per-call media registry, a bridge-orchestration service, an
5
+ * Express/WSS router (the `create*Handler` factory + mount-path consts), and a process-wide runtime
6
+ * holder (`Set*`/`Get*`). The routers + runtimes are star-exported; the service + registry modules are
7
+ * re-exported by name to avoid star-export ambiguity on their internal, per-vendor-identical helper
8
+ * types (`InboundCallInput`, `InboundCallResult`, `ITelephonyMediaSocket`). Those internal types are
9
+ * not part of the package's public surface — code that needs them imports from the source module.
10
+ *
11
+ * @module @memberjunction/server/telephony
12
+ */
13
+ export * from './media-upgrade-router.js';
14
+ export { TwilioCallMediaRegistry } from './twilioMediaRegistry.js';
15
+ export { TwilioTelephonyService, type TwilioTelephonyServiceDeps } from './TwilioTelephonyService.js';
16
+ export * from './TwilioTelephonyRouter.js';
17
+ export * from './telephony-runtime.js';
18
+ export { VonageCallMediaRegistry } from './vonageMediaRegistry.js';
19
+ export { VonageTelephonyService, type VonageTelephonyServiceDeps } from './VonageTelephonyService.js';
20
+ export * from './VonageTelephonyRouter.js';
21
+ export * from './vonage-runtime.js';
22
+ export { RingCentralTelephonyService, type RingCentralTelephonyServiceDeps } from './RingCentralTelephonyService.js';
23
+ export * from './ringcentral-runtime.js';
24
+ export * from './teamsAcsMediaRegistry.js';
25
+ export * from './TeamsMeetingsService.js';
26
+ export * from './TeamsMeetingsRouter.js';
27
+ export * from './teams-meetings-runtime.js';
28
+ export * from './calendar-scheduler.js';
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telephony/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,cAAc,2BAA2B,CAAC;AAG1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACtG,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AAGvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,KAAK,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACtG,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AAMpC,OAAO,EAAE,2BAA2B,EAAE,KAAK,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AACrH,cAAc,0BAA0B,CAAC;AAGzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAG5C,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @fileoverview Public exports for the MJAPI telephony + meetings ingress.
3
+ *
4
+ * Each vendor ingress is a quartet: a per-call media registry, a bridge-orchestration service, an
5
+ * Express/WSS router (the `create*Handler` factory + mount-path consts), and a process-wide runtime
6
+ * holder (`Set*`/`Get*`). The routers + runtimes are star-exported; the service + registry modules are
7
+ * re-exported by name to avoid star-export ambiguity on their internal, per-vendor-identical helper
8
+ * types (`InboundCallInput`, `InboundCallResult`, `ITelephonyMediaSocket`). Those internal types are
9
+ * not part of the package's public surface — code that needs them imports from the source module.
10
+ *
11
+ * @module @memberjunction/server/telephony
12
+ */
13
+ // ── Shared WebSocket-upgrade dispatcher (routes GraphQL + all media sockets by path) ──────
14
+ export * from './media-upgrade-router.js';
15
+ // ── Twilio Programmable Voice + Media Streams ──────────────────────────────────────────
16
+ export { TwilioCallMediaRegistry } from './twilioMediaRegistry.js';
17
+ export { TwilioTelephonyService } from './TwilioTelephonyService.js';
18
+ export * from './TwilioTelephonyRouter.js';
19
+ export * from './telephony-runtime.js';
20
+ // ── Vonage Voice + WebSocket-media ─────────────────────────────────────────────────────
21
+ export { VonageCallMediaRegistry } from './vonageMediaRegistry.js';
22
+ export { VonageTelephonyService } from './VonageTelephonyService.js';
23
+ export * from './VonageTelephonyRouter.js';
24
+ export * from './vonage-runtime.js';
25
+ // ── RingCentral SIP softphone (the only RingCentral transport with bidirectional call audio) ──
26
+ // No media registry / webhook router: the softphone is an outbound SIP registration that receives inbound
27
+ // INVITEs directly. The service owns the registration; the runtime holder shares it with the outbound
28
+ // PlaceRingCentralCall resolver.
29
+ export { RingCentralTelephonyService } from './RingCentralTelephonyService.js';
30
+ export * from './ringcentral-runtime.js';
31
+ // ── Teams meetings (Microsoft Graph cloud-communications + ACS application-hosted media) ──
32
+ export * from './teamsAcsMediaRegistry.js';
33
+ export * from './TeamsMeetingsService.js';
34
+ export * from './TeamsMeetingsRouter.js';
35
+ export * from './teams-meetings-runtime.js';
36
+ // ── Scheduled / invite-driven meeting join loop (M2: calendar watcher + due-bridge runner) ──
37
+ export * from './calendar-scheduler.js';
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/telephony/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,6FAA6F;AAC7F,cAAc,2BAA2B,CAAC;AAE1C,0FAA0F;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAmC,MAAM,6BAA6B,CAAC;AACtG,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AAEvC,0FAA0F;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAmC,MAAM,6BAA6B,CAAC;AACtG,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AAEpC,iGAAiG;AACjG,0GAA0G;AAC1G,sGAAsG;AACtG,iCAAiC;AACjC,OAAO,EAAE,2BAA2B,EAAwC,MAAM,kCAAkC,CAAC;AACrH,cAAc,0BAA0B,CAAC;AAEzC,6FAA6F;AAC7F,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAE5C,+FAA+F;AAC/F,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @fileoverview Single WebSocket-upgrade dispatcher for the shared HTTP server.
3
+ *
4
+ * Why this exists: in `ws` 8.x, every `new WebSocketServer({ server })` attaches its OWN `upgrade`
5
+ * listener that calls `handleUpgrade` UNCONDITIONALLY, and `handleUpgrade` does `abortHandshake(400)` for
6
+ * any request whose path it doesn't own. So two `{server}`-bound servers on one HTTP server (e.g. the
7
+ * GraphQL subscriptions socket on `/` AND a telephony Media-Streams socket on `/telephony/.../media`)
8
+ * fight on every upgrade — the non-owning server 400s the request. That's exactly what made Twilio's
9
+ * `<Connect><Stream>` fail with error 31920 ("Stream WebSocket failed to connect").
10
+ *
11
+ * The fix: telephony/meetings media servers are created with `{ noServer: true }` (no auto-listener) and
12
+ * register their path here; at boot we strip the auto-listeners and install ONE `upgrade` listener that
13
+ * routes by path — GraphQL on its root path, each media socket on its own. When no media routes are
14
+ * registered (telephony disabled), we leave the GraphQL server's own listener untouched (zero change).
15
+ *
16
+ * @module @memberjunction/server/telephony
17
+ */
18
+ import type { Server as HttpServer } from 'node:http';
19
+ import type { WebSocketServer } from 'ws';
20
+ /** Registers a media WebSocket route. Called by each vendor router's attach step. */
21
+ export declare function RegisterMediaUpgradeRoute(path: string, wss: WebSocketServer): void;
22
+ /**
23
+ * Installs the single path-routing `upgrade` dispatcher. No-op when no media routes are registered, so
24
+ * the GraphQL server keeps its own listener untouched. Otherwise it removes the auto-attached listeners
25
+ * (GraphQL's included) and dispatches every upgrade by pathname — GraphQL on `graphqlPath`, each media
26
+ * socket on its registered path; unknown paths are destroyed.
27
+ *
28
+ * @param httpServer the shared HTTP server.
29
+ * @param graphqlWss the GraphQL subscriptions WebSocketServer (kept, re-dispatched on its path).
30
+ * @param graphqlPath the GraphQL root path (the path GraphQL's socket listens on).
31
+ */
32
+ export declare function InstallMediaUpgradeDispatcher(httpServer: HttpServer, graphqlWss: WebSocketServer, graphqlPath: string): void;
33
+ //# sourceMappingURL=media-upgrade-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-upgrade-router.d.ts","sourceRoot":"","sources":["../../src/telephony/media-upgrade-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAmB,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAK1C,qFAAqF;AACrF,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAElF;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAqB5H"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview Single WebSocket-upgrade dispatcher for the shared HTTP server.
3
+ *
4
+ * Why this exists: in `ws` 8.x, every `new WebSocketServer({ server })` attaches its OWN `upgrade`
5
+ * listener that calls `handleUpgrade` UNCONDITIONALLY, and `handleUpgrade` does `abortHandshake(400)` for
6
+ * any request whose path it doesn't own. So two `{server}`-bound servers on one HTTP server (e.g. the
7
+ * GraphQL subscriptions socket on `/` AND a telephony Media-Streams socket on `/telephony/.../media`)
8
+ * fight on every upgrade — the non-owning server 400s the request. That's exactly what made Twilio's
9
+ * `<Connect><Stream>` fail with error 31920 ("Stream WebSocket failed to connect").
10
+ *
11
+ * The fix: telephony/meetings media servers are created with `{ noServer: true }` (no auto-listener) and
12
+ * register their path here; at boot we strip the auto-listeners and install ONE `upgrade` listener that
13
+ * routes by path — GraphQL on its root path, each media socket on its own. When no media routes are
14
+ * registered (telephony disabled), we leave the GraphQL server's own listener untouched (zero change).
15
+ *
16
+ * @module @memberjunction/server/telephony
17
+ */
18
+ /** path → the `{ noServer:true }` WebSocketServer that owns it. */
19
+ const mediaRoutes = new Map();
20
+ /** Registers a media WebSocket route. Called by each vendor router's attach step. */
21
+ export function RegisterMediaUpgradeRoute(path, wss) {
22
+ mediaRoutes.set(path, wss);
23
+ }
24
+ /**
25
+ * Installs the single path-routing `upgrade` dispatcher. No-op when no media routes are registered, so
26
+ * the GraphQL server keeps its own listener untouched. Otherwise it removes the auto-attached listeners
27
+ * (GraphQL's included) and dispatches every upgrade by pathname — GraphQL on `graphqlPath`, each media
28
+ * socket on its registered path; unknown paths are destroyed.
29
+ *
30
+ * @param httpServer the shared HTTP server.
31
+ * @param graphqlWss the GraphQL subscriptions WebSocketServer (kept, re-dispatched on its path).
32
+ * @param graphqlPath the GraphQL root path (the path GraphQL's socket listens on).
33
+ */
34
+ export function InstallMediaUpgradeDispatcher(httpServer, graphqlWss, graphqlPath) {
35
+ if (mediaRoutes.size === 0) {
36
+ return;
37
+ }
38
+ httpServer.removeAllListeners('upgrade');
39
+ const dispatch = (wss, req, socket, head) => {
40
+ wss.handleUpgrade(req, socket, head, (ws) => wss.emit('connection', ws, req));
41
+ };
42
+ httpServer.on('upgrade', (req, socket, head) => {
43
+ const pathname = (req.url ?? '').split('?')[0];
44
+ if (pathname === graphqlPath) {
45
+ dispatch(graphqlWss, req, socket, head);
46
+ return;
47
+ }
48
+ const wss = mediaRoutes.get(pathname);
49
+ if (wss) {
50
+ dispatch(wss, req, socket, head);
51
+ return;
52
+ }
53
+ socket.destroy();
54
+ });
55
+ }
56
+ //# sourceMappingURL=media-upgrade-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-upgrade-router.js","sourceRoot":"","sources":["../../src/telephony/media-upgrade-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,mEAAmE;AACnE,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEvD,qFAAqF;AACrF,MAAM,UAAU,yBAAyB,CAAC,IAAY,EAAE,GAAoB;IACxE,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,6BAA6B,CAAC,UAAsB,EAAE,UAA2B,EAAE,WAAmB;IAClH,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;IACX,CAAC;IACD,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,CAAC,GAAoB,EAAE,GAAoB,EAAE,MAAc,EAAE,IAAY,EAAQ,EAAE;QAChG,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC;IACF,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAoB,EAAE,MAAc,EAAE,IAAY,EAAE,EAAE;QAC5E,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC3B,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YACxC,OAAO;QACX,CAAC;QACD,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,GAAG,EAAE,CAAC;YACN,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YACjC,OAAO;QACX,CAAC;QACD,MAAM,CAAC,OAAO,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Process-wide holder for the startup-constructed RingCentral telephony service, so the
3
+ * outbound `PlaceRingCentralCall` GraphQL resolver reaches the SAME {@link RingCentralTelephonyService}
4
+ * (and thus the same long-lived SIP-softphone registration) that the inbound INVITE coordinator uses. Set
5
+ * once during server boot; read by the resolver.
6
+ *
7
+ * @module @memberjunction/server/telephony
8
+ */
9
+ import type { RingCentralTelephonyService } from './RingCentralTelephonyService.js';
10
+ /** Binds the startup-constructed RingCentral telephony service (called from server boot). */
11
+ export declare function SetRingCentralTelephonyService(service: RingCentralTelephonyService): void;
12
+ /** Returns the bound RingCentral telephony service, or `undefined` when telephony is not configured. */
13
+ export declare function GetRingCentralTelephonyService(): RingCentralTelephonyService | undefined;
14
+ //# sourceMappingURL=ringcentral-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ringcentral-runtime.d.ts","sourceRoot":"","sources":["../../src/telephony/ringcentral-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAIpF,6FAA6F;AAC7F,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,2BAA2B,GAAG,IAAI,CAEzF;AAED,wGAAwG;AACxG,wBAAgB,8BAA8B,IAAI,2BAA2B,GAAG,SAAS,CAExF"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview Process-wide holder for the startup-constructed RingCentral telephony service, so the
3
+ * outbound `PlaceRingCentralCall` GraphQL resolver reaches the SAME {@link RingCentralTelephonyService}
4
+ * (and thus the same long-lived SIP-softphone registration) that the inbound INVITE coordinator uses. Set
5
+ * once during server boot; read by the resolver.
6
+ *
7
+ * @module @memberjunction/server/telephony
8
+ */
9
+ let ringCentralService;
10
+ /** Binds the startup-constructed RingCentral telephony service (called from server boot). */
11
+ export function SetRingCentralTelephonyService(service) {
12
+ ringCentralService = service;
13
+ }
14
+ /** Returns the bound RingCentral telephony service, or `undefined` when telephony is not configured. */
15
+ export function GetRingCentralTelephonyService() {
16
+ return ringCentralService;
17
+ }
18
+ //# sourceMappingURL=ringcentral-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ringcentral-runtime.js","sourceRoot":"","sources":["../../src/telephony/ringcentral-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,IAAI,kBAA2D,CAAC;AAEhE,6FAA6F;AAC7F,MAAM,UAAU,8BAA8B,CAAC,OAAoC;IAC/E,kBAAkB,GAAG,OAAO,CAAC;AACjC,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,8BAA8B;IAC1C,OAAO,kBAAkB,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @fileoverview Process-wide holder for the startup-constructed Teams meetings service, so the
3
+ * `StartTeamsMeetingSession` GraphQL resolver reaches the SAME {@link TeamsMeetingsService} (and thus the
4
+ * same {@link TeamsAcsMediaRegistry} the ACS media adapter attaches transports to) that the Graph
5
+ * change-notification webhook router uses. Set once during server boot; read by the resolver + the router.
6
+ *
7
+ * Mirrors `telephony-runtime.ts` (the Twilio equivalent).
8
+ *
9
+ * @module @memberjunction/server/telephony
10
+ */
11
+ import type { TeamsMeetingsService } from './TeamsMeetingsService.js';
12
+ /** Binds the startup-constructed Teams meetings service (called from server boot). */
13
+ export declare function SetTeamsMeetingsService(service: TeamsMeetingsService): void;
14
+ /** Returns the bound Teams meetings service, or `undefined` when Teams meetings are not configured. */
15
+ export declare function GetTeamsMeetingsService(): TeamsMeetingsService | undefined;
16
+ //# sourceMappingURL=teams-meetings-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teams-meetings-runtime.d.ts","sourceRoot":"","sources":["../../src/telephony/teams-meetings-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAItE,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAE3E;AAED,uGAAuG;AACvG,wBAAgB,uBAAuB,IAAI,oBAAoB,GAAG,SAAS,CAE1E"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview Process-wide holder for the startup-constructed Teams meetings service, so the
3
+ * `StartTeamsMeetingSession` GraphQL resolver reaches the SAME {@link TeamsMeetingsService} (and thus the
4
+ * same {@link TeamsAcsMediaRegistry} the ACS media adapter attaches transports to) that the Graph
5
+ * change-notification webhook router uses. Set once during server boot; read by the resolver + the router.
6
+ *
7
+ * Mirrors `telephony-runtime.ts` (the Twilio equivalent).
8
+ *
9
+ * @module @memberjunction/server/telephony
10
+ */
11
+ let teamsService;
12
+ /** Binds the startup-constructed Teams meetings service (called from server boot). */
13
+ export function SetTeamsMeetingsService(service) {
14
+ teamsService = service;
15
+ }
16
+ /** Returns the bound Teams meetings service, or `undefined` when Teams meetings are not configured. */
17
+ export function GetTeamsMeetingsService() {
18
+ return teamsService;
19
+ }
20
+ //# sourceMappingURL=teams-meetings-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teams-meetings-runtime.js","sourceRoot":"","sources":["../../src/telephony/teams-meetings-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,IAAI,YAA8C,CAAC;AAEnD,sFAAsF;AACtF,MAAM,UAAU,uBAAuB,CAAC,OAA6B;IACjE,YAAY,GAAG,OAAO,CAAC;AAC3B,CAAC;AAED,uGAAuG;AACvG,MAAM,UAAU,uBAAuB;IACnC,OAAO,YAAY,CAAC;AACxB,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @fileoverview Per-call ACS application-hosted-media pump registry for the Teams meetings ingress.
3
+ *
4
+ * This is the server half of the Teams audio plane — the analogue of {@link TwilioCallMediaRegistry} for
5
+ * telephony. It implements the Teams provider package's `IAcsMediaPump` seam (which `PumpBackedAcsMedia` →
6
+ * `RealTeamsBindings` drive) on top of the live ACS application-hosted-media audio socket(s) the server owns.
7
+ *
8
+ * Like telephony, there is a lifecycle gap: when a meeting bridge session starts, `RealTeamsBindings`
9
+ * registers its inbound-audio handler before the ACS media socket has connected its inbound stream. The
10
+ * registry bridges that gap by buffering handler registrations + outbound PCM per call id and binding them to
11
+ * the media transport once it attaches (the server's native ACS media adapter calls {@link AttachTransport}
12
+ * when the application-hosted-media socket is up for the call).
13
+ *
14
+ * Pure + unit-testable: the media transport is injected as the minimal {@link IAcsMediaTransport} surface, so
15
+ * the registry's buffering / dispatch logic is exercised with a fake transport and no ACS install or network.
16
+ *
17
+ * @module @memberjunction/server/telephony
18
+ */
19
+ import type { AcsInboundAudioFrame, IAcsMediaPump } from '@memberjunction/ai-bridge-teams';
20
+ /**
21
+ * The minimal ACS media-transport surface the registry drives — a structural subset of the server's native
22
+ * application-hosted-media socket adapter, so the registry never imports the ACS SDK and is testable with a
23
+ * fake. Outbound frames are raw PCM16 `ArrayBuffer`s for the call.
24
+ */
25
+ export interface IAcsMediaTransport {
26
+ /** Sends one outbound PCM16 frame on the call's application-hosted-media outbound audio socket. */
27
+ sendAudioFrame(pcm: ArrayBuffer): void;
28
+ /** Closes the call's media transport (best-effort; called on call end). */
29
+ close(): void;
30
+ }
31
+ /**
32
+ * Coordinates ACS application-hosted-media transports with the bridge bindings, keyed by Graph call id. One
33
+ * instance per server, shared between the meetings service (which binds `PumpBackedAcsMedia` over this as the
34
+ * `IAcsMediaPump`) and the server's native ACS media adapter (which attaches transports + dispatches inbound
35
+ * audio).
36
+ */
37
+ export declare class TeamsAcsMediaRegistry implements IAcsMediaPump {
38
+ readonly SampleRate: number;
39
+ private readonly channels;
40
+ /**
41
+ * @param SampleRate The ACS audio-socket sample rate in Hz (the application-hosted-media PCM rate the
42
+ * server negotiates). Drives T0 resampling in `RealTeamsBindings`. Defaults to 16000.
43
+ */
44
+ constructor(SampleRate?: number);
45
+ /** Ensures a channel exists for a call (called when a meeting bridge session for the call starts). */
46
+ RegisterCall(callId: string): void;
47
+ /** @inheritdoc — buffers when the transport has not yet attached; sends immediately once it has. */
48
+ Send(callId: string, pcm: ArrayBuffer): void;
49
+ /** @inheritdoc — stores the handler so frames delivered before AND after transport attach reach it. */
50
+ OnFrame(callId: string, handler: (frame: AcsInboundAudioFrame) => void): void;
51
+ /** @inheritdoc — stores the hand-raise handler (Teams hand-raise is partial; tolerated if it never fires). */
52
+ OnHandRaise(callId: string, handler: (participantId: string, raised: boolean) => void): void;
53
+ /**
54
+ * Binds a connected ACS media transport to a call, flushing any outbound PCM produced while the transport
55
+ * was still connecting. Called by the server's native ACS media adapter once the application-hosted-media
56
+ * socket is up for the call.
57
+ */
58
+ AttachTransport(callId: string, transport: IAcsMediaTransport): void;
59
+ /** Dispatches one inbound per-participant audio frame to all registered handlers for the call. */
60
+ DispatchInbound(callId: string, frame: AcsInboundAudioFrame): void;
61
+ /** Dispatches one raised-hand signal to all registered hand-raise handlers for the call. */
62
+ DispatchHandRaise(callId: string, participantId: string, raised: boolean): void;
63
+ /** Tears down a call's channel and closes its transport (called on call end / meeting ended). */
64
+ EndCall(callId: string): void;
65
+ /** Whether a channel is currently tracked for the call (test/observability helper). */
66
+ HasCall(callId: string): boolean;
67
+ private ensureChannel;
68
+ }
69
+ //# sourceMappingURL=teamsAcsMediaRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teamsAcsMediaRegistry.d.ts","sourceRoot":"","sources":["../../src/telephony/teamsAcsMediaRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAE3F;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAC/B,mGAAmG;IACnG,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACvC,2EAA2E;IAC3E,KAAK,IAAI,IAAI,CAAC;CACjB;AAaD;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,aAAa;aAO3B,UAAU;IANtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAEhE;;;OAGG;gBACyB,UAAU,SAAQ;IAE9C,sGAAsG;IAC/F,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMzC,oGAAoG;IAC7F,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI;IASnD,uGAAuG;IAChG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,IAAI;IAIpF,8GAA8G;IACvG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAMnG;;;;OAIG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,GAAG,IAAI;IAS3E,kGAAkG;IAC3F,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,IAAI;IAUzE,4FAA4F;IACrF,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAUtF,iGAAiG;IAC1F,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAapC,uFAAuF;IAChF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIvC,OAAO,CAAC,aAAa;CAQxB"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @fileoverview Per-call ACS application-hosted-media pump registry for the Teams meetings ingress.
3
+ *
4
+ * This is the server half of the Teams audio plane — the analogue of {@link TwilioCallMediaRegistry} for
5
+ * telephony. It implements the Teams provider package's `IAcsMediaPump` seam (which `PumpBackedAcsMedia` →
6
+ * `RealTeamsBindings` drive) on top of the live ACS application-hosted-media audio socket(s) the server owns.
7
+ *
8
+ * Like telephony, there is a lifecycle gap: when a meeting bridge session starts, `RealTeamsBindings`
9
+ * registers its inbound-audio handler before the ACS media socket has connected its inbound stream. The
10
+ * registry bridges that gap by buffering handler registrations + outbound PCM per call id and binding them to
11
+ * the media transport once it attaches (the server's native ACS media adapter calls {@link AttachTransport}
12
+ * when the application-hosted-media socket is up for the call).
13
+ *
14
+ * Pure + unit-testable: the media transport is injected as the minimal {@link IAcsMediaTransport} surface, so
15
+ * the registry's buffering / dispatch logic is exercised with a fake transport and no ACS install or network.
16
+ *
17
+ * @module @memberjunction/server/telephony
18
+ */
19
+ /**
20
+ * Coordinates ACS application-hosted-media transports with the bridge bindings, keyed by Graph call id. One
21
+ * instance per server, shared between the meetings service (which binds `PumpBackedAcsMedia` over this as the
22
+ * `IAcsMediaPump`) and the server's native ACS media adapter (which attaches transports + dispatches inbound
23
+ * audio).
24
+ */
25
+ export class TeamsAcsMediaRegistry {
26
+ /**
27
+ * @param SampleRate The ACS audio-socket sample rate in Hz (the application-hosted-media PCM rate the
28
+ * server negotiates). Drives T0 resampling in `RealTeamsBindings`. Defaults to 16000.
29
+ */
30
+ constructor(SampleRate = 16000) {
31
+ this.SampleRate = SampleRate;
32
+ this.channels = new Map();
33
+ }
34
+ /** Ensures a channel exists for a call (called when a meeting bridge session for the call starts). */
35
+ RegisterCall(callId) {
36
+ this.ensureChannel(callId);
37
+ }
38
+ // ── IAcsMediaPump ─────────────────────────────────────────────────────────────
39
+ /** @inheritdoc — buffers when the transport has not yet attached; sends immediately once it has. */
40
+ Send(callId, pcm) {
41
+ const channel = this.ensureChannel(callId);
42
+ if (channel.transport) {
43
+ channel.transport.sendAudioFrame(pcm);
44
+ }
45
+ else {
46
+ channel.outboundBuffer.push(pcm);
47
+ }
48
+ }
49
+ /** @inheritdoc — stores the handler so frames delivered before AND after transport attach reach it. */
50
+ OnFrame(callId, handler) {
51
+ this.ensureChannel(callId).frameHandlers.push(handler);
52
+ }
53
+ /** @inheritdoc — stores the hand-raise handler (Teams hand-raise is partial; tolerated if it never fires). */
54
+ OnHandRaise(callId, handler) {
55
+ this.ensureChannel(callId).handRaiseHandlers.push(handler);
56
+ }
57
+ // ── native-adapter side ─────────────────────────────────────────────────────
58
+ /**
59
+ * Binds a connected ACS media transport to a call, flushing any outbound PCM produced while the transport
60
+ * was still connecting. Called by the server's native ACS media adapter once the application-hosted-media
61
+ * socket is up for the call.
62
+ */
63
+ AttachTransport(callId, transport) {
64
+ const channel = this.ensureChannel(callId);
65
+ channel.transport = transport;
66
+ const buffered = channel.outboundBuffer.splice(0, channel.outboundBuffer.length);
67
+ for (const pcm of buffered) {
68
+ transport.sendAudioFrame(pcm);
69
+ }
70
+ }
71
+ /** Dispatches one inbound per-participant audio frame to all registered handlers for the call. */
72
+ DispatchInbound(callId, frame) {
73
+ const channel = this.channels.get(callId);
74
+ if (!channel) {
75
+ return;
76
+ }
77
+ for (const handler of channel.frameHandlers) {
78
+ handler(frame);
79
+ }
80
+ }
81
+ /** Dispatches one raised-hand signal to all registered hand-raise handlers for the call. */
82
+ DispatchHandRaise(callId, participantId, raised) {
83
+ const channel = this.channels.get(callId);
84
+ if (!channel) {
85
+ return;
86
+ }
87
+ for (const handler of channel.handRaiseHandlers) {
88
+ handler(participantId, raised);
89
+ }
90
+ }
91
+ /** Tears down a call's channel and closes its transport (called on call end / meeting ended). */
92
+ EndCall(callId) {
93
+ const channel = this.channels.get(callId);
94
+ if (!channel) {
95
+ return;
96
+ }
97
+ try {
98
+ channel.transport?.close();
99
+ }
100
+ catch {
101
+ /* best-effort */
102
+ }
103
+ this.channels.delete(callId);
104
+ }
105
+ /** Whether a channel is currently tracked for the call (test/observability helper). */
106
+ HasCall(callId) {
107
+ return this.channels.has(callId);
108
+ }
109
+ ensureChannel(callId) {
110
+ let channel = this.channels.get(callId);
111
+ if (!channel) {
112
+ channel = { frameHandlers: [], handRaiseHandlers: [], outboundBuffer: [] };
113
+ this.channels.set(callId, channel);
114
+ }
115
+ return channel;
116
+ }
117
+ }
118
+ //# sourceMappingURL=teamsAcsMediaRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teamsAcsMediaRegistry.js","sourceRoot":"","sources":["../../src/telephony/teamsAcsMediaRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Process-wide holder for the startup-constructed telephony service, so the
3
+ * outbound `PlaceTwilioCall` GraphQL resolver reaches the SAME {@link TwilioTelephonyService}
4
+ * (and thus the same {@link TwilioCallMediaRegistry} the Media-Streams WSS attaches sockets to)
5
+ * that the inbound webhook router uses. Set once during server boot; read by the resolver.
6
+ *
7
+ * @module @memberjunction/server/telephony
8
+ */
9
+ import type { TwilioTelephonyService } from './TwilioTelephonyService.js';
10
+ /** Binds the startup-constructed Twilio telephony service (called from server boot). */
11
+ export declare function SetTwilioTelephonyService(service: TwilioTelephonyService): void;
12
+ /** Returns the bound Twilio telephony service, or `undefined` when telephony is not configured. */
13
+ export declare function GetTwilioTelephonyService(): TwilioTelephonyService | undefined;
14
+ //# sourceMappingURL=telephony-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telephony-runtime.d.ts","sourceRoot":"","sources":["../../src/telephony/telephony-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAI1E,wFAAwF;AACxF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAE/E;AAED,mGAAmG;AACnG,wBAAgB,yBAAyB,IAAI,sBAAsB,GAAG,SAAS,CAE9E"}