@memberjunction/server 5.44.0 → 5.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentSessions/ReturningVisitorRecap.d.ts +39 -0
- package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js +198 -0
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -0
- package/dist/agentSessions/SessionJanitor.d.ts +13 -0
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +65 -7
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +37 -0
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +10 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +16 -0
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +1 -1
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +1 -1
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +26 -0
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/config.d.ts +1883 -144
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +160 -36
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +45 -2
- package/dist/context.js.map +1 -1
- package/dist/generated/generated.d.ts +522 -0
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +2860 -0
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +13 -0
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +22 -0
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +4 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +101 -3
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +6 -0
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.d.ts +26 -0
- package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -0
- package/dist/realtimeWidget/WidgetRouter.js +182 -0
- package/dist/realtimeWidget/WidgetRouter.js.map +1 -0
- package/dist/realtimeWidget/WidgetSessionService.d.ts +265 -0
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -0
- package/dist/realtimeWidget/WidgetSessionService.js +477 -0
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -0
- package/dist/realtimeWidget/host-identity.d.ts +40 -0
- package/dist/realtimeWidget/host-identity.d.ts.map +1 -0
- package/dist/realtimeWidget/host-identity.js +58 -0
- package/dist/realtimeWidget/host-identity.js.map +1 -0
- package/dist/realtimeWidget/index.d.ts +10 -0
- package/dist/realtimeWidget/index.d.ts.map +1 -0
- package/dist/realtimeWidget/index.js +9 -0
- package/dist/realtimeWidget/index.js.map +1 -0
- package/dist/realtimeWidget/visitorIdentity.d.ts +76 -0
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -0
- package/dist/realtimeWidget/visitorIdentity.js +202 -0
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -0
- package/dist/realtimeWidget/widgetCore.d.ts +106 -0
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -0
- package/dist/realtimeWidget/widgetCore.js +173 -0
- package/dist/realtimeWidget/widgetCore.js.map +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +51 -0
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.js +79 -0
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -0
- package/dist/resolvers/ComponentRegistryResolver.d.ts +7 -0
- package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.js +31 -8
- package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
- package/dist/resolvers/EntityPermissionResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityPermissionResolver.js +1 -2
- package/dist/resolvers/EntityPermissionResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +9 -6
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +15 -13
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +10 -0
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +47 -3
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RingCentralTelephonyResolver.d.ts +27 -0
- package/dist/resolvers/RingCentralTelephonyResolver.d.ts.map +1 -0
- package/dist/resolvers/RingCentralTelephonyResolver.js +87 -0
- package/dist/resolvers/RingCentralTelephonyResolver.js.map +1 -0
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +14 -3
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/SearchKnowledgeResolver.d.ts.map +1 -1
- package/dist/resolvers/SearchKnowledgeResolver.js +2 -0
- package/dist/resolvers/SearchKnowledgeResolver.js.map +1 -1
- package/dist/resolvers/TeamsMeetingsResolver.d.ts +28 -0
- package/dist/resolvers/TeamsMeetingsResolver.d.ts.map +1 -0
- package/dist/resolvers/TeamsMeetingsResolver.js +91 -0
- package/dist/resolvers/TeamsMeetingsResolver.js.map +1 -0
- package/dist/resolvers/TelephonyResolver.d.ts +26 -0
- package/dist/resolvers/TelephonyResolver.d.ts.map +1 -0
- package/dist/resolvers/TelephonyResolver.js +86 -0
- package/dist/resolvers/TelephonyResolver.js.map +1 -0
- package/dist/resolvers/TestQuerySQLResolver.d.ts +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +2 -3
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/VonageTelephonyResolver.d.ts +26 -0
- package/dist/resolvers/VonageTelephonyResolver.d.ts.map +1 -0
- package/dist/resolvers/VonageTelephonyResolver.js +86 -0
- package/dist/resolvers/VonageTelephonyResolver.js.map +1 -0
- package/dist/rest/MediaStreamHandler.js +4 -1
- package/dist/rest/MediaStreamHandler.js.map +1 -1
- package/dist/telephony/RingCentralTelephonyService.d.ts +115 -0
- package/dist/telephony/RingCentralTelephonyService.d.ts.map +1 -0
- package/dist/telephony/RingCentralTelephonyService.js +262 -0
- package/dist/telephony/RingCentralTelephonyService.js.map +1 -0
- package/dist/telephony/TeamsMeetingsRouter.d.ts +40 -0
- package/dist/telephony/TeamsMeetingsRouter.d.ts.map +1 -0
- package/dist/telephony/TeamsMeetingsRouter.js +96 -0
- package/dist/telephony/TeamsMeetingsRouter.js.map +1 -0
- package/dist/telephony/TeamsMeetingsService.d.ts +113 -0
- package/dist/telephony/TeamsMeetingsService.d.ts.map +1 -0
- package/dist/telephony/TeamsMeetingsService.js +196 -0
- package/dist/telephony/TeamsMeetingsService.js.map +1 -0
- package/dist/telephony/TwilioTelephonyRouter.d.ts +36 -0
- package/dist/telephony/TwilioTelephonyRouter.d.ts.map +1 -0
- package/dist/telephony/TwilioTelephonyRouter.js +143 -0
- package/dist/telephony/TwilioTelephonyRouter.js.map +1 -0
- package/dist/telephony/TwilioTelephonyService.d.ts +95 -0
- package/dist/telephony/TwilioTelephonyService.d.ts.map +1 -0
- package/dist/telephony/TwilioTelephonyService.js +193 -0
- package/dist/telephony/TwilioTelephonyService.js.map +1 -0
- package/dist/telephony/VonageTelephonyRouter.d.ts +41 -0
- package/dist/telephony/VonageTelephonyRouter.d.ts.map +1 -0
- package/dist/telephony/VonageTelephonyRouter.js +201 -0
- package/dist/telephony/VonageTelephonyRouter.js.map +1 -0
- package/dist/telephony/VonageTelephonyService.d.ts +90 -0
- package/dist/telephony/VonageTelephonyService.d.ts.map +1 -0
- package/dist/telephony/VonageTelephonyService.js +191 -0
- package/dist/telephony/VonageTelephonyService.js.map +1 -0
- package/dist/telephony/calendar-scheduler.d.ts +67 -0
- package/dist/telephony/calendar-scheduler.d.ts.map +1 -0
- package/dist/telephony/calendar-scheduler.js +133 -0
- package/dist/telephony/calendar-scheduler.js.map +1 -0
- package/dist/telephony/index.d.ts +29 -0
- package/dist/telephony/index.d.ts.map +1 -0
- package/dist/telephony/index.js +38 -0
- package/dist/telephony/index.js.map +1 -0
- package/dist/telephony/media-upgrade-router.d.ts +33 -0
- package/dist/telephony/media-upgrade-router.d.ts.map +1 -0
- package/dist/telephony/media-upgrade-router.js +56 -0
- package/dist/telephony/media-upgrade-router.js.map +1 -0
- package/dist/telephony/ringcentral-runtime.d.ts +14 -0
- package/dist/telephony/ringcentral-runtime.d.ts.map +1 -0
- package/dist/telephony/ringcentral-runtime.js +18 -0
- package/dist/telephony/ringcentral-runtime.js.map +1 -0
- package/dist/telephony/teams-meetings-runtime.d.ts +16 -0
- package/dist/telephony/teams-meetings-runtime.d.ts.map +1 -0
- package/dist/telephony/teams-meetings-runtime.js +20 -0
- package/dist/telephony/teams-meetings-runtime.js.map +1 -0
- package/dist/telephony/teamsAcsMediaRegistry.d.ts +69 -0
- package/dist/telephony/teamsAcsMediaRegistry.d.ts.map +1 -0
- package/dist/telephony/teamsAcsMediaRegistry.js +118 -0
- package/dist/telephony/teamsAcsMediaRegistry.js.map +1 -0
- package/dist/telephony/telephony-runtime.d.ts +14 -0
- package/dist/telephony/telephony-runtime.d.ts.map +1 -0
- package/dist/telephony/telephony-runtime.js +18 -0
- package/dist/telephony/telephony-runtime.js.map +1 -0
- package/dist/telephony/twilioMediaRegistry.d.ts +60 -0
- package/dist/telephony/twilioMediaRegistry.d.ts.map +1 -0
- package/dist/telephony/twilioMediaRegistry.js +106 -0
- package/dist/telephony/twilioMediaRegistry.js.map +1 -0
- package/dist/telephony/vonage-runtime.d.ts +14 -0
- package/dist/telephony/vonage-runtime.d.ts.map +1 -0
- package/dist/telephony/vonage-runtime.js +18 -0
- package/dist/telephony/vonage-runtime.js.map +1 -0
- package/dist/telephony/vonageMediaRegistry.d.ts +78 -0
- package/dist/telephony/vonageMediaRegistry.d.ts.map +1 -0
- package/dist/telephony/vonageMediaRegistry.js +158 -0
- package/dist/telephony/vonageMediaRegistry.js.map +1 -0
- package/package.json +88 -83
- package/src/__tests__/search-knowledge-tags.test.ts +9 -9
- package/src/__tests__/teams-meetings-service.test.ts +65 -0
- package/src/__tests__/teamsAcsMediaRegistry.test.ts +82 -0
- package/src/__tests__/twilio-telephony-service.test.ts +23 -0
- package/src/__tests__/twilioMediaRegistry.test.ts +103 -0
- package/src/__tests__/vonageMediaRegistry.test.ts +180 -0
- package/src/__tests__/widget.test.ts +204 -0
- package/src/__tests__/widgetGuestElevation.test.ts +57 -0
- package/src/__tests__/widgetHostIdentity.test.ts +117 -0
- package/src/agentSessions/ReturningVisitorRecap.ts +242 -0
- package/src/agentSessions/SessionJanitor.ts +66 -6
- package/src/agentSessions/SessionManager.ts +38 -0
- package/src/auth/magicLink/MagicLinkRouter.ts +17 -0
- package/src/auth/magicLink/index.ts +1 -0
- package/src/auth/magicLink/types.ts +26 -0
- package/src/config.ts +172 -38
- package/src/context.ts +50 -3
- package/src/generated/generated.ts +1991 -1
- package/src/generic/ResolverBase.ts +28 -0
- package/src/generic/RunViewResolver.ts +4 -0
- package/src/index.ts +109 -3
- package/src/integration/CustomColumnPromoter.ts +6 -0
- package/src/realtimeWidget/WidgetRouter.ts +204 -0
- package/src/realtimeWidget/WidgetSessionService.ts +714 -0
- package/src/realtimeWidget/host-identity.ts +84 -0
- package/src/realtimeWidget/index.ts +15 -0
- package/src/realtimeWidget/visitorIdentity.ts +258 -0
- package/src/realtimeWidget/widgetCore.ts +231 -0
- package/src/realtimeWidget/widgetGuestElevation.ts +115 -0
- package/src/resolvers/ComponentRegistryResolver.ts +36 -10
- package/src/resolvers/EntityPermissionResolver.ts +1 -2
- package/src/resolvers/QuerySystemUserResolver.ts +14 -10
- package/src/resolvers/RealtimeClientSessionResolver.ts +59 -2
- package/src/resolvers/RingCentralTelephonyResolver.ts +64 -0
- package/src/resolvers/RunAIAgentResolver.ts +16 -4
- package/src/resolvers/SearchKnowledgeResolver.ts +2 -0
- package/src/resolvers/TeamsMeetingsResolver.ts +68 -0
- package/src/resolvers/TelephonyResolver.ts +63 -0
- package/src/resolvers/TestQuerySQLResolver.ts +2 -3
- package/src/resolvers/VonageTelephonyResolver.ts +63 -0
- package/src/rest/MediaStreamHandler.ts +4 -1
- package/src/telephony/RingCentralTelephonyService.ts +342 -0
- package/src/telephony/TeamsMeetingsRouter.ts +124 -0
- package/src/telephony/TeamsMeetingsService.ts +268 -0
- package/src/telephony/TwilioTelephonyRouter.ts +184 -0
- package/src/telephony/TwilioTelephonyService.ts +261 -0
- package/src/telephony/VonageTelephonyRouter.ts +239 -0
- package/src/telephony/VonageTelephonyService.ts +259 -0
- package/src/telephony/calendar-scheduler.ts +176 -0
- package/src/telephony/index.ts +43 -0
- package/src/telephony/media-upgrade-router.ts +62 -0
- package/src/telephony/ringcentral-runtime.ts +22 -0
- package/src/telephony/teams-meetings-runtime.ts +24 -0
- package/src/telephony/teamsAcsMediaRegistry.ts +152 -0
- package/src/telephony/telephony-runtime.ts +22 -0
- package/src/telephony/twilioMediaRegistry.ts +137 -0
- package/src/telephony/vonage-runtime.ts +22 -0
- package/src/telephony/vonageMediaRegistry.ts +200 -0
- package/dist/agents/skip-agent.d.ts +0 -111
- package/dist/agents/skip-agent.d.ts.map +0 -1
- package/dist/agents/skip-agent.js +0 -1487
- package/dist/agents/skip-agent.js.map +0 -1
- package/dist/agents/skip-sdk.d.ts +0 -261
- package/dist/agents/skip-sdk.d.ts.map +0 -1
- package/dist/agents/skip-sdk.js +0 -909
- package/dist/agents/skip-sdk.js.map +0 -1
- package/src/agents/skip-agent.ts +0 -1594
- package/src/agents/skip-sdk.ts +0 -1210
|
@@ -13,7 +13,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
13
13
|
import { Arg, Ctx, Field, InputType, Int, ObjectType, Query, Resolver } from 'type-graphql';
|
|
14
14
|
import { GraphQLJSONObject } from 'graphql-type-json';
|
|
15
15
|
import { RunQuery, LogError, LogStatus } from '@memberjunction/core';
|
|
16
|
-
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
17
16
|
import { GetReadOnlyProvider } from '../util.js';
|
|
18
17
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
19
18
|
/**
|
|
@@ -121,7 +120,7 @@ export { TestQuerySQLResult };
|
|
|
121
120
|
* enabling external systems (e.g., Skip-Brain) to test query SQL before saving to the database.
|
|
122
121
|
*
|
|
123
122
|
* Security:
|
|
124
|
-
* - Requires
|
|
123
|
+
* - Requires `query:test` scope for API key users (no-op for JWT auth)
|
|
125
124
|
* - Uses read-only database connection (no mutation possible)
|
|
126
125
|
* - Enforces MaxRows limit (default 100) to prevent unbounded queries
|
|
127
126
|
*
|
|
@@ -130,6 +129,7 @@ export { TestQuerySQLResult };
|
|
|
130
129
|
let TestQuerySQLResolver = class TestQuerySQLResolver extends ResolverBase {
|
|
131
130
|
async TestQuerySQL(input, context) {
|
|
132
131
|
try {
|
|
132
|
+
await this.CheckAPIKeyScopeAuthorization('query:test', '*', context.userPayload);
|
|
133
133
|
// Use read-only provider for security — no mutation possible
|
|
134
134
|
const provider = GetReadOnlyProvider(context.providers, { allowFallbackToReadWrite: false });
|
|
135
135
|
if (!provider) {
|
|
@@ -172,7 +172,6 @@ let TestQuerySQLResolver = class TestQuerySQLResolver extends ResolverBase {
|
|
|
172
172
|
}
|
|
173
173
|
};
|
|
174
174
|
__decorate([
|
|
175
|
-
RequireSystemUser(),
|
|
176
175
|
Query(() => TestQuerySQLResult, {
|
|
177
176
|
description: 'Test transient SQL with full composition + Nunjucks template processing without requiring a saved query'
|
|
178
177
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestQuerySQLResolver.js","sourceRoot":"","sources":["../../src/resolvers/TestQuerySQLResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAqB,QAAQ,EAAE,SAAS,EAAsB,MAAM,sBAAsB,CAAC;AAE5G,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"TestQuerySQLResolver.js","sourceRoot":"","sources":["../../src/resolvers/TestQuerySQLResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview GraphQL surface for OUTBOUND Vonage telephony: `PlaceVonageCall` rings a real phone from
|
|
3
|
+
* an agent identity and connects the pinned agent. Thin — it authorizes the caller, then delegates to
|
|
4
|
+
* the startup-constructed {@link VonageTelephonyService} (which owns the bridge orchestration + the
|
|
5
|
+
* shared media registry). Inbound calls arrive via the public `POST /telephony/vonage/answer` webhook,
|
|
6
|
+
* not GraphQL.
|
|
7
|
+
*
|
|
8
|
+
* @module @memberjunction/server
|
|
9
|
+
*/
|
|
10
|
+
import { AppContext } from '../types.js';
|
|
11
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
12
|
+
/** Result of an outbound place-call attempt. */
|
|
13
|
+
export declare class PlaceVonageCallResult {
|
|
14
|
+
Success: boolean;
|
|
15
|
+
ErrorMessage?: string;
|
|
16
|
+
/** The placed Vonage call UUID (the bridge's external connection id). */
|
|
17
|
+
CallId: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class VonageTelephonyResolver extends ResolverBase {
|
|
20
|
+
/**
|
|
21
|
+
* Places an outbound call from the given agent identity (its phone number is the caller-id) to a
|
|
22
|
+
* destination number, connecting the pinned agent over the realtime bridge. Returns the call UUID.
|
|
23
|
+
*/
|
|
24
|
+
PlaceVonageCall(agentIdentityId: string, toNumber: string, context?: AppContext): Promise<PlaceVonageCallResult>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=VonageTelephonyResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VonageTelephonyResolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/VonageTelephonyResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI1D,gDAAgD;AAChD,qBACa,qBAAqB;IAE9B,OAAO,EAAE,OAAO,CAAC;IAGjB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yEAAyE;IAEzE,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,qBACa,uBAAwB,SAAQ,YAAY;IACrD;;;OAGG;IAEG,eAAe,CACqB,eAAe,EAAE,MAAM,EAC9B,QAAQ,EAAE,MAAM,EACxC,OAAO,GAAE,UAA6B,GAC9C,OAAO,CAAC,qBAAqB,CAAC;CAoBpC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview GraphQL surface for OUTBOUND Vonage telephony: `PlaceVonageCall` rings a real phone from
|
|
3
|
+
* an agent identity and connects the pinned agent. Thin — it authorizes the caller, then delegates to
|
|
4
|
+
* the startup-constructed {@link VonageTelephonyService} (which owns the bridge orchestration + the
|
|
5
|
+
* shared media registry). Inbound calls arrive via the public `POST /telephony/vonage/answer` webhook,
|
|
6
|
+
* not GraphQL.
|
|
7
|
+
*
|
|
8
|
+
* @module @memberjunction/server
|
|
9
|
+
*/
|
|
10
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
11
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
12
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
13
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
14
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
15
|
+
};
|
|
16
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
17
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
18
|
+
};
|
|
19
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
20
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
21
|
+
};
|
|
22
|
+
import { Resolver, Mutation, Arg, Ctx, ObjectType, Field } from 'type-graphql';
|
|
23
|
+
import { LogError } from '@memberjunction/core';
|
|
24
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
25
|
+
import { GetReadWriteProvider } from '../util.js';
|
|
26
|
+
import { GetVonageTelephonyService } from '../telephony/vonage-runtime.js';
|
|
27
|
+
/** Result of an outbound place-call attempt. */
|
|
28
|
+
let PlaceVonageCallResult = class PlaceVonageCallResult {
|
|
29
|
+
};
|
|
30
|
+
__decorate([
|
|
31
|
+
Field(() => Boolean),
|
|
32
|
+
__metadata("design:type", Boolean)
|
|
33
|
+
], PlaceVonageCallResult.prototype, "Success", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
Field(() => String, { nullable: true }),
|
|
36
|
+
__metadata("design:type", String)
|
|
37
|
+
], PlaceVonageCallResult.prototype, "ErrorMessage", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
Field(() => String),
|
|
40
|
+
__metadata("design:type", String)
|
|
41
|
+
], PlaceVonageCallResult.prototype, "CallId", void 0);
|
|
42
|
+
PlaceVonageCallResult = __decorate([
|
|
43
|
+
ObjectType()
|
|
44
|
+
], PlaceVonageCallResult);
|
|
45
|
+
export { PlaceVonageCallResult };
|
|
46
|
+
let VonageTelephonyResolver = class VonageTelephonyResolver extends ResolverBase {
|
|
47
|
+
/**
|
|
48
|
+
* Places an outbound call from the given agent identity (its phone number is the caller-id) to a
|
|
49
|
+
* destination number, connecting the pinned agent over the realtime bridge. Returns the call UUID.
|
|
50
|
+
*/
|
|
51
|
+
async PlaceVonageCall(agentIdentityId, toNumber, context = {}) {
|
|
52
|
+
const failure = (msg) => ({ Success: false, ErrorMessage: msg, CallId: '' });
|
|
53
|
+
try {
|
|
54
|
+
const user = this.GetUserFromPayload(context.userPayload);
|
|
55
|
+
if (!user) {
|
|
56
|
+
return failure('Unable to determine current user.');
|
|
57
|
+
}
|
|
58
|
+
const service = GetVonageTelephonyService();
|
|
59
|
+
if (!service) {
|
|
60
|
+
return failure('Vonage telephony is not configured on this server.');
|
|
61
|
+
}
|
|
62
|
+
const provider = GetReadWriteProvider(context.providers);
|
|
63
|
+
const callId = await service.PlaceOutboundCall(agentIdentityId, toNumber, user, provider);
|
|
64
|
+
return { Success: true, CallId: callId };
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
68
|
+
LogError(`PlaceVonageCall failed: ${msg}`);
|
|
69
|
+
return failure(msg);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
__decorate([
|
|
74
|
+
Mutation(() => PlaceVonageCallResult),
|
|
75
|
+
__param(0, Arg('agentIdentityId', () => String)),
|
|
76
|
+
__param(1, Arg('toNumber', () => String)),
|
|
77
|
+
__param(2, Ctx()),
|
|
78
|
+
__metadata("design:type", Function),
|
|
79
|
+
__metadata("design:paramtypes", [String, String, Object]),
|
|
80
|
+
__metadata("design:returntype", Promise)
|
|
81
|
+
], VonageTelephonyResolver.prototype, "PlaceVonageCall", null);
|
|
82
|
+
VonageTelephonyResolver = __decorate([
|
|
83
|
+
Resolver()
|
|
84
|
+
], VonageTelephonyResolver);
|
|
85
|
+
export { VonageTelephonyResolver };
|
|
86
|
+
//# sourceMappingURL=VonageTelephonyResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VonageTelephonyResolver.js","sourceRoot":"","sources":["../../src/resolvers/VonageTelephonyResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;;;;;;;;;;;;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAqB,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,gDAAgD;AAEzC,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;CAUjC,CAAA;AARG;IADC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC;;sDACJ;AAGjB;IADC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2DAClB;AAItB;IADC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;qDACL;AATN,qBAAqB;IADjC,UAAU,EAAE;GACA,qBAAqB,CAUjC;;AAGM,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,YAAY;IACrD;;;OAGG;IAEG,AAAN,KAAK,CAAC,eAAe,CACqB,eAAuB,EAC9B,QAAgB,EACxC,UAAsB,EAAgB;QAE7C,MAAM,OAAO,GAAG,CAAC,GAAW,EAAyB,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5G,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,OAAO,OAAO,CAAC,mCAAmC,CAAC,CAAC;YACxD,CAAC;YACD,MAAM,OAAO,GAAG,yBAAyB,EAAE,CAAC;YAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,OAAO,OAAO,CAAC,oDAAoD,CAAC,CAAC;YACzE,CAAC;YACD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAiC,CAAC;YACzF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC1F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,QAAQ,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;YAC3C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACL,CAAC;CACJ,CAAA;AAxBS;IADL,QAAQ,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC;IAEjC,WAAA,GAAG,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAA;IACpC,WAAA,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAA;IAC7B,WAAA,GAAG,EAAE,CAAA;;;;8DAoBT;AA7BQ,uBAAuB;IADnC,QAAQ,EAAE;GACE,uBAAuB,CA8BnC"}
|
|
@@ -36,7 +36,10 @@ export function createMediaStreamRouter() {
|
|
|
36
36
|
}
|
|
37
37
|
/** Top-level request handler: verify token → resolve bytes → stream/buffer with Range support. */
|
|
38
38
|
async function handleMediaRequest(req, res) {
|
|
39
|
-
|
|
39
|
+
// Express type defs allow req.params values to be string | string[]; normalize to string
|
|
40
|
+
// so downstream consumers with moduleResolution:"node" type-check cleanly (see SignatureWebhookHandler).
|
|
41
|
+
const rawFileId = req.params.fileId;
|
|
42
|
+
const fileId = Array.isArray(rawFileId) ? rawFileId[0] : rawFileId;
|
|
40
43
|
const token = typeof req.query.token === 'string' ? req.query.token : '';
|
|
41
44
|
const claims = verifyMediaToken(token, fileId);
|
|
42
45
|
if (!claims) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaStreamHandler.js","sourceRoot":"","sources":["../../src/rest/MediaStreamHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,OAAqD,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAUpE;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC3D,MAAM,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,kGAAkG;AAClG,KAAK,UAAU,kBAAkB,CAAC,GAAY,EAAE,GAAa;IAC3D,
|
|
1
|
+
{"version":3,"file":"MediaStreamHandler.js","sourceRoot":"","sources":["../../src/rest/MediaStreamHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Orchestrates RingCentral telephony bridge sessions (inbound + outbound) for MJAPI over the
|
|
3
|
+
* **SIP softphone** transport.
|
|
4
|
+
*
|
|
5
|
+
* RingCentral's only product that carries bidirectional call audio is a registered SIP softphone (the
|
|
6
|
+
* `ringcentral-softphone` SDK over SIP/TLS + RTP/SRTP) — its WebSocket "Call Streaming" product is
|
|
7
|
+
* receive-only and cannot inject the agent's voice. So unlike the Twilio/Vonage ingresses (public webhook
|
|
8
|
+
* + media WSS), this service owns a **long-lived SIP registration**: one
|
|
9
|
+
* {@link RingCentralSoftphoneHandle} created + registered at boot, shared across all calls. Inbound calls
|
|
10
|
+
* arrive as SIP INVITEs on that registration (no HTTP webhook); outbound calls place SIP calls through it.
|
|
11
|
+
*
|
|
12
|
+
* It does NOT re-implement bridge logic: it resolves the RingCentral provider + the agent identity, opens a
|
|
13
|
+
* server-side realtime session via the agent layer's `CreateBridgeRealtimeSession` factory, binds a
|
|
14
|
+
* {@link RingCentralSoftphoneCallSdk} (drawing its session from the shared handle) onto the driver, and
|
|
15
|
+
* hands everything to `AIBridgeEngine.StartBridgeSession` — the same seam the Twilio/Vonage services use.
|
|
16
|
+
*
|
|
17
|
+
* @module @memberjunction/server/telephony
|
|
18
|
+
*/
|
|
19
|
+
import { UserInfo, IMetadataProvider } from '@memberjunction/core';
|
|
20
|
+
import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
|
|
21
|
+
import { CreateBridgeRealtimeSession } from '@memberjunction/ai-agents';
|
|
22
|
+
import { type BridgeNativeSdkBinding } from '@memberjunction/ai-bridge-base';
|
|
23
|
+
import { createRingCentralSoftphone } from '@memberjunction/ai-bridge-ringcentral';
|
|
24
|
+
import type { RingCentralTelephonyConfig } from '../config.js';
|
|
25
|
+
import { SessionManager } from '../agentSessions/SessionManager.js';
|
|
26
|
+
/** A resolved inbound call's identifying fields (mapped from a RingCentral SIP INVITE). */
|
|
27
|
+
export interface InboundCallInput {
|
|
28
|
+
/** The SIP `Call-ID` (the per-call id the handle parked the INVITE under + the bridge's inbound id). */
|
|
29
|
+
sessionId: string;
|
|
30
|
+
/** The caller's number (the INVITE's `From`). */
|
|
31
|
+
from: string;
|
|
32
|
+
/** The dialed DID (the INVITE's `To`) — resolved to an agent identity. */
|
|
33
|
+
to: string;
|
|
34
|
+
}
|
|
35
|
+
/** Result of starting an inbound bridge session. */
|
|
36
|
+
export interface InboundCallResult {
|
|
37
|
+
/** Whether a pinned agent was resolved + a bridge session started. */
|
|
38
|
+
accepted: boolean;
|
|
39
|
+
/** Why it was rejected (no agent identity for the DID, provider missing, etc.). */
|
|
40
|
+
reason?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Injectable collaborators (production defaults wired in the constructor; fakes in tests). */
|
|
43
|
+
export interface RingCentralTelephonyServiceDeps {
|
|
44
|
+
engine?: Pick<AIBridgeEngine, 'ProviderByName' | 'ProviderByDriverClass' | 'StartBridgeSession' | 'Config'>;
|
|
45
|
+
sessionFactory?: typeof CreateBridgeRealtimeSession;
|
|
46
|
+
sessionManager?: Pick<SessionManager, 'CreateSession'>;
|
|
47
|
+
/** Test seam: a factory that builds the softphone handle (inject a fake to avoid the real SIP SDK). */
|
|
48
|
+
createHandle?: typeof createRingCentralSoftphone;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Starts RingCentral bridge sessions over a shared SIP-softphone registration. One instance per server,
|
|
52
|
+
* constructed at boot and held by the runtime holder so the outbound `PlaceRingCentralCall` resolver and the
|
|
53
|
+
* inbound INVITE coordinator share the same registration.
|
|
54
|
+
*/
|
|
55
|
+
export declare class RingCentralTelephonyService {
|
|
56
|
+
private readonly config;
|
|
57
|
+
private readonly engine;
|
|
58
|
+
private readonly sessionFactory;
|
|
59
|
+
private readonly sessionManager;
|
|
60
|
+
private readonly createHandle;
|
|
61
|
+
/** The shared SIP registration — created + registered by {@link start}; null until then. */
|
|
62
|
+
private handle;
|
|
63
|
+
/** The carrier PCM16 rate for the negotiated codec (set in {@link start}). */
|
|
64
|
+
private carrierSampleRate;
|
|
65
|
+
constructor(config: RingCentralTelephonyConfig, deps?: RingCentralTelephonyServiceDeps);
|
|
66
|
+
/**
|
|
67
|
+
* Creates + registers the shared SIP softphone and wires inbound INVITE handling. Called once at boot
|
|
68
|
+
* (fire-and-forget so SIP registration never blocks server startup); logs success/failure. Inbound calls
|
|
69
|
+
* only flow once this resolves.
|
|
70
|
+
*/
|
|
71
|
+
start(): Promise<void>;
|
|
72
|
+
/** Best-effort teardown of the SIP registration (server shutdown). */
|
|
73
|
+
dispose(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Resolves the dialed DID to a pinned agent and starts an INBOUND bridge session. The bound
|
|
76
|
+
* {@link RingCentralSoftphoneCallSdk} answers the parked INVITE for `sessionId`. Returns
|
|
77
|
+
* `{ accepted:false }` (never throws) when no agent identity matches the DID, so the coordinator can
|
|
78
|
+
* decline the INVITE cleanly.
|
|
79
|
+
*/
|
|
80
|
+
HandleInboundCall(input: InboundCallInput, contextUser: UserInfo, provider: IMetadataProvider): Promise<InboundCallResult>;
|
|
81
|
+
/**
|
|
82
|
+
* Places an OUTBOUND call from a given agent identity to a destination number. The bound
|
|
83
|
+
* {@link RingCentralSoftphoneCallSdk} places the SIP call through the shared registration; the returned
|
|
84
|
+
* SIP `Call-ID` is the bridge's external connection id.
|
|
85
|
+
*
|
|
86
|
+
* @returns The placed call's SIP `Call-ID`.
|
|
87
|
+
*/
|
|
88
|
+
PlaceOutboundCall(agentIdentityId: string, toNumber: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<string>;
|
|
89
|
+
/** Inbound INVITE coordinator: resolve the server principal, start a bridge, decline if no agent matched. */
|
|
90
|
+
private onInboundInvite;
|
|
91
|
+
/** Shared inbound/outbound bridge-start: resolve provider, open the realtime session, bind the SDK, start. */
|
|
92
|
+
private startBridge;
|
|
93
|
+
/** Resolves the seeded RingCentral provider row (by driver class, falling back to display name). */
|
|
94
|
+
private resolveProvider;
|
|
95
|
+
/**
|
|
96
|
+
* Builds the per-session SDK binding that wires a {@link RingCentralSoftphoneCallSdk} (drawing its
|
|
97
|
+
* session from the shared SIP registration handle) onto the telephony driver — overriding the package's
|
|
98
|
+
* default unbound SDK. Reads the handle lazily at call time so a call placed during the brief boot window
|
|
99
|
+
* before registration fails loudly rather than binding a null handle.
|
|
100
|
+
*/
|
|
101
|
+
buildBindSdk(): BridgeNativeSdkBinding;
|
|
102
|
+
/** Returns the live registration handle, or throws if the softphone hasn't registered yet. */
|
|
103
|
+
private requireHandle;
|
|
104
|
+
/** Assembles the per-session bridge configuration (direction / from-number / inbound-call-id / carrier rate). */
|
|
105
|
+
private buildSessionConfiguration;
|
|
106
|
+
/** Maps the server config block to the softphone SDK's SIP-device config (credentials resolved upstream). */
|
|
107
|
+
private toSoftphoneConfig;
|
|
108
|
+
/** Resolves the server-side principal + provider for an inbound call (no MJ JWT on a SIP INVITE). */
|
|
109
|
+
private resolveServerContext;
|
|
110
|
+
/** Finds the active agent identity whose phone number matches the dialed DID. */
|
|
111
|
+
private resolveAgentIdentityByPhone;
|
|
112
|
+
/** Loads a specific agent identity by id (used by outbound PlaceCall), requiring it be active. */
|
|
113
|
+
private loadAgentIdentity;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=RingCentralTelephonyService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RingCentralTelephonyService.d.ts","sourceRoot":"","sources":["../../src/telephony/RingCentralTelephonyService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAW,QAAQ,EAAE,iBAAiB,EAAiC,MAAM,sBAAsB,CAAC;AAG3G,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAEH,KAAK,sBAAsB,EAK9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACH,0BAA0B,EAK7B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAapE,2FAA2F;AAC3F,MAAM,WAAW,gBAAgB;IAC7B,wGAAwG;IACxG,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,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,+BAA+B;IAC5C,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,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IACvD,uGAAuG;IACvG,YAAY,CAAC,EAAE,OAAO,0BAA0B,CAAC;CACpD;AAED;;;;GAIG;AACH,qBAAa,2BAA2B;IAahC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAZ3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqG;IAC5H,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;IACpE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IAEjE,4FAA4F;IAC5F,OAAO,CAAC,MAAM,CAA2C;IAEzD,8EAA8E;IAC9E,OAAO,CAAC,iBAAiB,CAA4C;gBAGhD,MAAM,EAAE,0BAA0B,EACnD,IAAI,GAAE,+BAAoC;IAQ9C;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAanC,sEAAsE;IAC/D,OAAO,IAAI,IAAI;IAKtB;;;;;OAKG;IACU,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAqBvI;;;;;;OAMG;IACU,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkB9I,6GAA6G;YAC/F,eAAe;IAc7B,8GAA8G;YAChG,WAAW;IAsCzB,oGAAoG;IACpG,OAAO,CAAC,eAAe;IAQvB;;;;;OAKG;IACI,YAAY,IAAI,sBAAsB;IAO7C,8FAA8F;IAC9F,OAAO,CAAC,aAAa;IAOrB,iHAAiH;IACjH,OAAO,CAAC,yBAAyB;IAiBjC,6GAA6G;IAC7G,OAAO,CAAC,iBAAiB;IAYzB,qGAAqG;IACrG,OAAO,CAAC,oBAAoB;IAS5B,iFAAiF;YACnE,2BAA2B;IAsBzC,kGAAkG;YACpF,iBAAiB;CASlC"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Orchestrates RingCentral telephony bridge sessions (inbound + outbound) for MJAPI over the
|
|
3
|
+
* **SIP softphone** transport.
|
|
4
|
+
*
|
|
5
|
+
* RingCentral's only product that carries bidirectional call audio is a registered SIP softphone (the
|
|
6
|
+
* `ringcentral-softphone` SDK over SIP/TLS + RTP/SRTP) — its WebSocket "Call Streaming" product is
|
|
7
|
+
* receive-only and cannot inject the agent's voice. So unlike the Twilio/Vonage ingresses (public webhook
|
|
8
|
+
* + media WSS), this service owns a **long-lived SIP registration**: one
|
|
9
|
+
* {@link RingCentralSoftphoneHandle} created + registered at boot, shared across all calls. Inbound calls
|
|
10
|
+
* arrive as SIP INVITEs on that registration (no HTTP webhook); outbound calls place SIP calls through it.
|
|
11
|
+
*
|
|
12
|
+
* It does NOT re-implement bridge logic: it resolves the RingCentral provider + the agent identity, opens a
|
|
13
|
+
* server-side realtime session via the agent layer's `CreateBridgeRealtimeSession` factory, binds a
|
|
14
|
+
* {@link RingCentralSoftphoneCallSdk} (drawing its session from the shared handle) onto the driver, and
|
|
15
|
+
* hands everything to `AIBridgeEngine.StartBridgeSession` — the same seam the Twilio/Vonage services use.
|
|
16
|
+
*
|
|
17
|
+
* @module @memberjunction/server/telephony
|
|
18
|
+
*/
|
|
19
|
+
import { RunView, Metadata, LogError, LogStatus } from '@memberjunction/core';
|
|
20
|
+
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
21
|
+
import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
|
|
22
|
+
import { CreateBridgeRealtimeSession } from '@memberjunction/ai-agents';
|
|
23
|
+
import { CARRIER_SAMPLE_RATE_CONFIG_KEY, DIRECTION_CONFIG_KEY, FROM_NUMBER_CONFIG_KEY, INBOUND_CALL_ID_CONFIG_KEY, } from '@memberjunction/ai-bridge-base';
|
|
24
|
+
import { createRingCentralSoftphone, RingCentralSoftphoneCallSdk, } from '@memberjunction/ai-bridge-ringcentral';
|
|
25
|
+
import { SessionManager } from '../agentSessions/SessionManager.js';
|
|
26
|
+
const RINGCENTRAL_PROVIDER_DRIVER = 'RingCentralBridge';
|
|
27
|
+
const AGENT_IDENTITY_ENTITY = 'MJ: AI Bridge Agent Identities';
|
|
28
|
+
const PHONE_IDENTITY_TYPE = 'PhoneNumber';
|
|
29
|
+
/** PCM16 carrier rate (Hz) per softphone codec — the rate the bridge resamples to/from the model rate. */
|
|
30
|
+
const CODEC_CARRIER_RATE = {
|
|
31
|
+
'OPUS/16000': 16000,
|
|
32
|
+
'OPUS/48000/2': 48000,
|
|
33
|
+
'PCMU/8000': 8000,
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Starts RingCentral bridge sessions over a shared SIP-softphone registration. One instance per server,
|
|
37
|
+
* constructed at boot and held by the runtime holder so the outbound `PlaceRingCentralCall` resolver and the
|
|
38
|
+
* inbound INVITE coordinator share the same registration.
|
|
39
|
+
*/
|
|
40
|
+
export class RingCentralTelephonyService {
|
|
41
|
+
constructor(config, deps = {}) {
|
|
42
|
+
this.config = config;
|
|
43
|
+
/** The shared SIP registration — created + registered by {@link start}; null until then. */
|
|
44
|
+
this.handle = null;
|
|
45
|
+
/** The carrier PCM16 rate for the negotiated codec (set in {@link start}). */
|
|
46
|
+
this.carrierSampleRate = CODEC_CARRIER_RATE['OPUS/16000'];
|
|
47
|
+
this.engine = deps.engine ?? AIBridgeEngine.Instance;
|
|
48
|
+
this.sessionFactory = deps.sessionFactory ?? CreateBridgeRealtimeSession;
|
|
49
|
+
this.sessionManager = deps.sessionManager ?? new SessionManager();
|
|
50
|
+
this.createHandle = deps.createHandle ?? createRingCentralSoftphone;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates + registers the shared SIP softphone and wires inbound INVITE handling. Called once at boot
|
|
54
|
+
* (fire-and-forget so SIP registration never blocks server startup); logs success/failure. Inbound calls
|
|
55
|
+
* only flow once this resolves.
|
|
56
|
+
*/
|
|
57
|
+
async start() {
|
|
58
|
+
try {
|
|
59
|
+
this.carrierSampleRate = CODEC_CARRIER_RATE[this.config.codec ?? 'OPUS/16000'];
|
|
60
|
+
this.handle = await this.createHandle(this.toSoftphoneConfig());
|
|
61
|
+
this.handle.onInvite((info) => void this.onInboundInvite(info));
|
|
62
|
+
await this.handle.register();
|
|
63
|
+
LogStatus('[Telephony][RingCentral] softphone telephony started (inbound + outbound ready).');
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
this.handle = null;
|
|
67
|
+
LogError(`[Telephony][RingCentral] softphone start failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Best-effort teardown of the SIP registration (server shutdown). */
|
|
71
|
+
dispose() {
|
|
72
|
+
this.handle?.dispose();
|
|
73
|
+
this.handle = null;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolves the dialed DID to a pinned agent and starts an INBOUND bridge session. The bound
|
|
77
|
+
* {@link RingCentralSoftphoneCallSdk} answers the parked INVITE for `sessionId`. Returns
|
|
78
|
+
* `{ accepted:false }` (never throws) when no agent identity matches the DID, so the coordinator can
|
|
79
|
+
* decline the INVITE cleanly.
|
|
80
|
+
*/
|
|
81
|
+
async HandleInboundCall(input, contextUser, provider) {
|
|
82
|
+
try {
|
|
83
|
+
const identity = await this.resolveAgentIdentityByPhone(input.to, contextUser);
|
|
84
|
+
if (!identity) {
|
|
85
|
+
return { accepted: false, reason: `No active agent identity for dialed number '${input.to}'.` };
|
|
86
|
+
}
|
|
87
|
+
await this.startBridge({
|
|
88
|
+
agentID: identity.AgentID,
|
|
89
|
+
direction: 'Inbound',
|
|
90
|
+
address: input.from,
|
|
91
|
+
inboundCallId: input.sessionId,
|
|
92
|
+
contextUser,
|
|
93
|
+
provider,
|
|
94
|
+
});
|
|
95
|
+
return { accepted: true };
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
LogError(`[Telephony][RingCentral] inbound call ${input.sessionId} failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
99
|
+
return { accepted: false, reason: 'Internal error starting the agent.' };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Places an OUTBOUND call from a given agent identity to a destination number. The bound
|
|
104
|
+
* {@link RingCentralSoftphoneCallSdk} places the SIP call through the shared registration; the returned
|
|
105
|
+
* SIP `Call-ID` is the bridge's external connection id.
|
|
106
|
+
*
|
|
107
|
+
* @returns The placed call's SIP `Call-ID`.
|
|
108
|
+
*/
|
|
109
|
+
async PlaceOutboundCall(agentIdentityId, toNumber, contextUser, provider) {
|
|
110
|
+
const identity = await this.loadAgentIdentity(agentIdentityId, contextUser, provider);
|
|
111
|
+
if (!identity) {
|
|
112
|
+
throw new Error(`Agent identity '${agentIdentityId}' not found or inactive.`);
|
|
113
|
+
}
|
|
114
|
+
const session = await this.startBridge({
|
|
115
|
+
agentID: identity.AgentID,
|
|
116
|
+
direction: 'Outbound',
|
|
117
|
+
address: toNumber,
|
|
118
|
+
fromNumber: identity.IdentityValue,
|
|
119
|
+
contextUser,
|
|
120
|
+
provider,
|
|
121
|
+
});
|
|
122
|
+
return session.RoomKey ?? '';
|
|
123
|
+
}
|
|
124
|
+
// ── internals ────────────────────────────────────────────────────────────────
|
|
125
|
+
/** Inbound INVITE coordinator: resolve the server principal, start a bridge, decline if no agent matched. */
|
|
126
|
+
async onInboundInvite(info) {
|
|
127
|
+
const context = this.resolveServerContext();
|
|
128
|
+
if (!context) {
|
|
129
|
+
LogError('[Telephony][RingCentral] no server context user available; declining inbound call.');
|
|
130
|
+
await this.handle?.declineCall(info.callId);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const result = await this.HandleInboundCall({ sessionId: info.callId, from: info.from, to: info.to }, context.user, context.provider);
|
|
134
|
+
if (!result.accepted) {
|
|
135
|
+
LogStatus(`[Telephony][RingCentral] inbound ${info.callId} not accepted: ${result.reason ?? 'unknown'}; declining.`);
|
|
136
|
+
await this.handle?.declineCall(info.callId);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/** Shared inbound/outbound bridge-start: resolve provider, open the realtime session, bind the SDK, start. */
|
|
140
|
+
async startBridge(args) {
|
|
141
|
+
await this.engine.Config(false, args.contextUser, args.provider);
|
|
142
|
+
const ringCentralProvider = this.resolveProvider();
|
|
143
|
+
const agentSession = await this.sessionManager.CreateSession({ agentID: args.agentID, userID: args.contextUser.ID }, args.contextUser, args.provider);
|
|
144
|
+
const realtimeSession = await this.sessionFactory({
|
|
145
|
+
AgentID: args.agentID,
|
|
146
|
+
TargetAgentID: args.agentID,
|
|
147
|
+
ContextUser: args.contextUser,
|
|
148
|
+
MetadataProvider: args.provider,
|
|
149
|
+
AgentSessionID: agentSession.ID,
|
|
150
|
+
RoomName: args.address,
|
|
151
|
+
});
|
|
152
|
+
const active = await this.engine.StartBridgeSession({
|
|
153
|
+
AgentSessionID: agentSession.ID,
|
|
154
|
+
AgentID: args.agentID,
|
|
155
|
+
TargetAgentID: args.agentID,
|
|
156
|
+
Provider: ringCentralProvider,
|
|
157
|
+
RealtimeSession: realtimeSession,
|
|
158
|
+
Address: args.address,
|
|
159
|
+
Direction: args.direction,
|
|
160
|
+
Configuration: this.buildSessionConfiguration(args.direction, args.fromNumber, args.inboundCallId),
|
|
161
|
+
BindSdk: this.buildBindSdk(),
|
|
162
|
+
ContextUser: args.contextUser,
|
|
163
|
+
MetadataProvider: args.provider,
|
|
164
|
+
});
|
|
165
|
+
return { RoomKey: active.RoomKey };
|
|
166
|
+
}
|
|
167
|
+
/** Resolves the seeded RingCentral provider row (by driver class, falling back to display name). */
|
|
168
|
+
resolveProvider() {
|
|
169
|
+
const provider = this.engine.ProviderByDriverClass(RINGCENTRAL_PROVIDER_DRIVER) ?? this.engine.ProviderByName('RingCentral');
|
|
170
|
+
if (!provider) {
|
|
171
|
+
throw new Error(`No active 'MJ: AI Bridge Providers' row for the RingCentral bridge (DriverClass '${RINGCENTRAL_PROVIDER_DRIVER}').`);
|
|
172
|
+
}
|
|
173
|
+
return provider;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Builds the per-session SDK binding that wires a {@link RingCentralSoftphoneCallSdk} (drawing its
|
|
177
|
+
* session from the shared SIP registration handle) onto the telephony driver — overriding the package's
|
|
178
|
+
* default unbound SDK. Reads the handle lazily at call time so a call placed during the brief boot window
|
|
179
|
+
* before registration fails loudly rather than binding a null handle.
|
|
180
|
+
*/
|
|
181
|
+
buildBindSdk() {
|
|
182
|
+
return (driver) => {
|
|
183
|
+
const telephony = driver;
|
|
184
|
+
telephony.SetSdkFactory(() => new RingCentralSoftphoneCallSdk(this.requireHandle()));
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/** Returns the live registration handle, or throws if the softphone hasn't registered yet. */
|
|
188
|
+
requireHandle() {
|
|
189
|
+
if (!this.handle) {
|
|
190
|
+
throw new Error('[Telephony][RingCentral] softphone not registered yet (start() pending or failed).');
|
|
191
|
+
}
|
|
192
|
+
return this.handle;
|
|
193
|
+
}
|
|
194
|
+
/** Assembles the per-session bridge configuration (direction / from-number / inbound-call-id / carrier rate). */
|
|
195
|
+
buildSessionConfiguration(direction, fromNumber, inboundCallId) {
|
|
196
|
+
// The engine does NOT forward the top-level Direction into the driver's Configuration; set it here so
|
|
197
|
+
// an inbound call answers instead of wrongly taking the outbound-dial path. The carrier rate tells the
|
|
198
|
+
// base bridge the SIP leg is wideband (16 kHz for OPUS/16000), not the 8 kHz G.711 default.
|
|
199
|
+
const config = {
|
|
200
|
+
[DIRECTION_CONFIG_KEY]: direction,
|
|
201
|
+
[CARRIER_SAMPLE_RATE_CONFIG_KEY]: this.carrierSampleRate,
|
|
202
|
+
};
|
|
203
|
+
if (fromNumber) {
|
|
204
|
+
config[FROM_NUMBER_CONFIG_KEY] = fromNumber;
|
|
205
|
+
}
|
|
206
|
+
if (inboundCallId) {
|
|
207
|
+
config[INBOUND_CALL_ID_CONFIG_KEY] = inboundCallId;
|
|
208
|
+
}
|
|
209
|
+
return config;
|
|
210
|
+
}
|
|
211
|
+
/** Maps the server config block to the softphone SDK's SIP-device config (credentials resolved upstream). */
|
|
212
|
+
toSoftphoneConfig() {
|
|
213
|
+
return {
|
|
214
|
+
domain: this.config.sipDomain,
|
|
215
|
+
outboundProxy: this.config.sipOutboundProxy,
|
|
216
|
+
username: this.config.sipUsername,
|
|
217
|
+
password: this.config.sipPassword,
|
|
218
|
+
authorizationId: this.config.sipAuthorizationId,
|
|
219
|
+
codec: this.config.codec,
|
|
220
|
+
ignoreTlsCertErrors: this.config.ignoreTlsCertErrors,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/** Resolves the server-side principal + provider for an inbound call (no MJ JWT on a SIP INVITE). */
|
|
224
|
+
resolveServerContext() {
|
|
225
|
+
const user = UserCache.Instance.GetSystemUser() ?? UserCache.Users.find((u) => u.IsActive && u.Type?.trim().toLowerCase() === 'owner') ?? null;
|
|
226
|
+
const provider = Metadata.Provider; // global-provider-ok: inbound SIP INVITE has no MJ JWT / per-request provider; the server's single default provider is correct
|
|
227
|
+
if (!user || !provider) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
return { user, provider };
|
|
231
|
+
}
|
|
232
|
+
/** Finds the active agent identity whose phone number matches the dialed DID. */
|
|
233
|
+
async resolveAgentIdentityByPhone(dialedNumber, contextUser) {
|
|
234
|
+
const normalized = (dialedNumber ?? '').trim();
|
|
235
|
+
if (!normalized) {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
const rv = new RunView();
|
|
239
|
+
const result = await rv.RunView({
|
|
240
|
+
EntityName: AGENT_IDENTITY_ENTITY,
|
|
241
|
+
ExtraFilter: `IdentityType='${PHONE_IDENTITY_TYPE}' AND IdentityValue='${normalized.replace(/'/g, "''")}' AND IsActive=1`,
|
|
242
|
+
MaxRows: 1,
|
|
243
|
+
ResultType: 'entity_object',
|
|
244
|
+
}, contextUser);
|
|
245
|
+
if (!result.Success) {
|
|
246
|
+
LogError(`[Telephony][RingCentral] agent-identity lookup failed: ${result.ErrorMessage}`);
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
return result.Results?.[0] ?? null;
|
|
250
|
+
}
|
|
251
|
+
/** Loads a specific agent identity by id (used by outbound PlaceCall), requiring it be active. */
|
|
252
|
+
async loadAgentIdentity(agentIdentityId, contextUser, provider) {
|
|
253
|
+
// Use the request-scoped provider (multi-provider safe), not the global Metadata.
|
|
254
|
+
const entity = await provider.GetEntityObject(AGENT_IDENTITY_ENTITY, contextUser);
|
|
255
|
+
const loaded = await entity.Load(agentIdentityId);
|
|
256
|
+
if (!loaded || !entity.IsActive) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
return entity;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=RingCentralTelephonyService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RingCentralTelephonyService.js","sourceRoot":"","sources":["../../src/telephony/RingCentralTelephonyService.ts"],"names":[],"mappings":"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"}
|