@opencxh/domain 1.36.0 → 1.39.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/entities/channel/index.d.ts +1 -0
- package/dist/entities/channel/signature.d.ts +17 -0
- package/dist/entities/channel/types.d.ts +6 -1
- package/dist/entities/interaction/index.d.ts +1 -0
- package/dist/entities/interaction/seen.d.ts +2 -0
- package/dist/entities/interaction/types.d.ts +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +80 -56
- package/dist/platform/capabilities.d.ts +12 -0
- package/dist/platform/communication.d.ts +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CommunicationIntent } from '../../platform/capabilities';
|
|
2
|
+
import { Channel } from './types';
|
|
3
|
+
export interface ChannelSignature {
|
|
4
|
+
body: string;
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
updatedAt?: number;
|
|
7
|
+
}
|
|
8
|
+
export type ChannelSignaturesMap = Partial<Record<CommunicationIntent | string, ChannelSignature>>;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the signature a provider should append for an outbound message
|
|
11
|
+
* on this channel + intent. Returns null when no signature is configured,
|
|
12
|
+
* disabled, or empty. Providers MUST call this in their send path for
|
|
13
|
+
* intents where signatures apply (e.g. "mail", "message") and merge the
|
|
14
|
+
* body before wire-send. The merged body is what gets persisted on the
|
|
15
|
+
* resulting activity/interaction.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveSignature(channel: Channel, intent: CommunicationIntent | string): ChannelSignature | null;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { IntentCapability, Uri } from '../../platform/communication';
|
|
2
|
+
import { ChannelSignaturesMap } from './signature';
|
|
3
|
+
export interface ChannelSettings {
|
|
4
|
+
signatures?: ChannelSignaturesMap;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
2
7
|
export interface Channel {
|
|
3
8
|
id: string;
|
|
4
9
|
organizationId: string;
|
|
@@ -11,7 +16,7 @@ export interface Channel {
|
|
|
11
16
|
inboxId?: string;
|
|
12
17
|
ownerId: string;
|
|
13
18
|
externalIds?: string[];
|
|
14
|
-
settings:
|
|
19
|
+
settings: ChannelSettings;
|
|
15
20
|
disabledIntents?: string[];
|
|
16
21
|
intentOverrides?: Record<string, Partial<IntentCapability>>;
|
|
17
22
|
extraIntents?: IntentCapability[];
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=140;function i(e){return e.replace(/<style[\s\S]*?<\/style>/gi," ").replace(/<script[\s\S]*?<\/script>/gi," ").replace(/<[^>]+>/g," ").replace(/ /g," ").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/\s+/g," ").trim()}function I(e){const t=e.trim();return t.length<=u?t:t.slice(0,u-1).trimEnd()+"…"}function l(e){if(!e||e<0)return"";const t=Math.floor(e/60),n=Math.floor(e%60);return`${t}:${n.toString().padStart(2,"0")}`}function A(e){switch(e.type){case"EMAIL_RECEIVED":case"EMAIL_SENT":{const t=e.payload,n=t.bodySnippet?.trim()||i(t.body??"");return t.subject?`${t.subject} — ${n}`:n}case"CHAT_MESSAGE_SENT":case"CHAT_MESSAGE_RECEIVED":return e.payload.text??"";case"CHAT_RENAMED":return`Hernoemd naar "${e.payload.newName}"`;case"CHAT_MEMBER_JOINED":return`${e.payload.members.map(t=>t.name).join(", ")} toegevoegd`;case"CHAT_MEMBER_LEFT":return`${e.payload.members.map(t=>t.name).join(", ")} verlaten`;case"CHAT_CALL_STARTED":return"Gesprek gestart";case"CHAT_CALL_ENDED":return`Gesprek beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"CHAT_EVENT":return e.payload.text??e.payload.eventType;case"VOICE_CALL_STARTED":case"VIDEO_CALL_STARTED":return"Gesprek gestart";case"VOICE_CALL_ANSWERED":case"VIDEO_CALL_ANSWERED":return"Gesprek aangenomen";case"VOICE_CALL_HOLD":case"VIDEO_CALL_HOLD":return"In de wacht";case"VOICE_CALL_UNHOLD":case"VIDEO_CALL_UNHOLD":return"Hervat";case"VOICE_CALL_ENDED":case"VIDEO_CALL_ENDED":return`Gesprek beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"VOICE_CALL_MISSED":case"VIDEO_CALL_MISSED":return"Gemiste oproep";case"VOICE_CALL_FAILED":case"VIDEO_CALL_FAILED":return"Gesprek mislukt";case"VOICE_CALL_VOICEMAIL":return e.payload.transcription?.trim()?e.payload.transcription:"Voicemail ontvangen";case"TRANSCRIPT_ADDED":return(e.payload.segments??[]).map(t=>t.text).join(" ");case"AI_MESSAGE_ADDED":return e.payload.output?.text??e.payload.input?.text??"";case"MEETING_SCHEDULED":return`Vergadering gepland: ${e.payload.title}`;case"MEETING_STARTED":return`Vergadering gestart: ${e.payload.title}`;case"MEETING_ENDED":return`Vergadering beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"MEETING_PARTICIPANT_JOINED":return`${e.payload.name} deelgenomen`;case"MEETING_PARTICIPANT_LEFT":return`${e.payload.name} verlaten`;case"COMMENT_ADDED":return e.payload.text??"";case"FILE_UPLOADED":return`Bestand: ${e.payload.fileName}`;case"INTERACTION_CREATED":return"Interactie aangemaakt";case"INTERACTION_STATUS_CHANGED":return`Status: ${e.payload.fromStatus} → ${e.payload.toStatus}`;case"INTERACTION_ASSIGNED":return"Interactie toegewezen";default:return""}}function g(e){return{activityId:e.id,type:e.type,snippet:I(A(e)),authorName:e.author?.name??"",direction:e.direction,createdAt:e.createdAt??Date.now()}}function f(e,t){const n=e.settings?.signatures?.[t];return!n||!n.enabled||!n.body||n.body.trim()===""?null:n}function _(e){return e.endpoints??[]}const T=e=>!!e.assignedUserId||!!e.assignedInboxId,D=e=>e.status==="closed",L=e=>({urgent:10,high:5,normal:2,low:1})[e.priority]||0,C=(e,t=30)=>e.title?.length<=t?e.title:`${e.title.substring(0,t)}...`;function S(e,t){return e.lastActivityAt?!(e.seenBy??[]).includes(t):!1}function E(e,t){const n=new Set(e.disabledIntents??[]),r=e.intentOverrides??{},s=t.intents.filter(a=>!n.has(a.intent)).map(a=>b(a,r[a.intent]));if(!e.extraIntents||e.extraIntents.length===0)return s;const o=new Set(s.map(a=>a.intent));for(const a of e.extraIntents)o.has(a.intent)||(s.push(a),o.add(a.intent));return s}function d(e,t){const n={};for(const r of e.intents){if(!r.togglable)continue;const s=t?.[r.intent];n[r.intent]=s??r.defaultEnabled??!0}return n}function N(e,t){const n=d(e,t);return Object.entries(n).filter(([,r])=>!r).map(([r])=>r)}function b(e,t){return t?{intent:t.intent??e.intent,targetSchemes:t.targetSchemes??e.targetSchemes,transport:t.transport??e.transport}:e}function O(e,t){const n=[];for(const r of e){if(!r.enabled)continue;const s=t[r.providerId];if(s)for(const o of E(r,s))n.push({channel:r,description:s,capability:o})}return n}function M(e,t){return t.filter(n=>n.capability.intent===e)}function p(e,t){return t.filter(n=>n.capability.targetSchemes.includes(e))}function y(e,t){return p(e.scheme,t)}function R(e,t,n){const r=[];for(const s of e)for(const o of n)o.capability.intent===t&&o.capability.targetSchemes.includes(s.scheme)&&r.push({channelIntent:o,endpoint:s});return r}var c=(e=>(e.MAILTO="mailto",e.SIP="sip",e.TEL="tel",e.WEBHOOK="webhook",e.USERNAME="username",e.ID="id",e.CUSTOM="custom",e.URL="url",e.TELEGRAM="telegram",e.WHATSAPP="whatsapp",e.VIBER="viber",e.SMS="sms",e.FAX="fax",e.TEAMS="teams",e.CALENDAR="calendar",e))(c||{});const V=(e,t)=>({intent:e,...t}),h={ok:!1,code:"UNSUPPORTED",message:"Provider does not support this op"};exports.CommunicationScheme=c;exports.UNSUPPORTED=h;exports.buildActivityPreview=g;exports.buildChannelIntents=O;exports.defineIntent=V;exports.disabledIntentsFromCapabilities=N;exports.filterByEndpoint=y;exports.filterByIntent=M;exports.filterByTargetScheme=p;exports.getContactEndpoints=_;exports.getShortTitle=C;exports.getUrgencyScore=L;exports.isAssigned=T;exports.isClosed=D;exports.isInteractionUnseen=S;exports.matchContactToIntents=R;exports.resolveAccountCapabilities=d;exports.resolveChannelIntents=E;exports.resolveSignature=f;exports.stripHtml=i;
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
function
|
|
1
|
+
function l(e) {
|
|
2
2
|
return e.replace(/<style[\s\S]*?<\/style>/gi, " ").replace(/<script[\s\S]*?<\/script>/gi, " ").replace(/<[^>]+>/g, " ").replace(/ /g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/\s+/g, " ").trim();
|
|
3
3
|
}
|
|
4
|
-
function
|
|
4
|
+
function E(e) {
|
|
5
5
|
const t = e.trim();
|
|
6
6
|
return t.length <= 140 ? t : t.slice(0, 139).trimEnd() + "…";
|
|
7
7
|
}
|
|
8
|
-
function
|
|
8
|
+
function u(e) {
|
|
9
9
|
if (!e || e < 0) return "";
|
|
10
|
-
const t = Math.floor(e / 60),
|
|
11
|
-
return `${t}:${
|
|
10
|
+
const t = Math.floor(e / 60), n = Math.floor(e % 60);
|
|
11
|
+
return `${t}:${n.toString().padStart(2, "0")}`;
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function p(e) {
|
|
14
14
|
switch (e.type) {
|
|
15
15
|
case "EMAIL_RECEIVED":
|
|
16
16
|
case "EMAIL_SENT": {
|
|
17
|
-
const t = e.payload,
|
|
18
|
-
return t.subject ? `${t.subject} — ${
|
|
17
|
+
const t = e.payload, n = t.bodySnippet?.trim() || l(t.body ?? "");
|
|
18
|
+
return t.subject ? `${t.subject} — ${n}` : n;
|
|
19
19
|
}
|
|
20
20
|
case "CHAT_MESSAGE_SENT":
|
|
21
21
|
case "CHAT_MESSAGE_RECEIVED":
|
|
@@ -29,7 +29,7 @@ function u(e) {
|
|
|
29
29
|
case "CHAT_CALL_STARTED":
|
|
30
30
|
return "Gesprek gestart";
|
|
31
31
|
case "CHAT_CALL_ENDED":
|
|
32
|
-
return `Gesprek beëindigd${e.payload.duration ? ` (${
|
|
32
|
+
return `Gesprek beëindigd${e.payload.duration ? ` (${u(e.payload.duration)})` : ""}`;
|
|
33
33
|
case "CHAT_EVENT":
|
|
34
34
|
return e.payload.text ?? e.payload.eventType;
|
|
35
35
|
case "VOICE_CALL_STARTED":
|
|
@@ -46,7 +46,7 @@ function u(e) {
|
|
|
46
46
|
return "Hervat";
|
|
47
47
|
case "VOICE_CALL_ENDED":
|
|
48
48
|
case "VIDEO_CALL_ENDED":
|
|
49
|
-
return `Gesprek beëindigd${e.payload.duration ? ` (${
|
|
49
|
+
return `Gesprek beëindigd${e.payload.duration ? ` (${u(e.payload.duration)})` : ""}`;
|
|
50
50
|
case "VOICE_CALL_MISSED":
|
|
51
51
|
case "VIDEO_CALL_MISSED":
|
|
52
52
|
return "Gemiste oproep";
|
|
@@ -64,7 +64,7 @@ function u(e) {
|
|
|
64
64
|
case "MEETING_STARTED":
|
|
65
65
|
return `Vergadering gestart: ${e.payload.title}`;
|
|
66
66
|
case "MEETING_ENDED":
|
|
67
|
-
return `Vergadering beëindigd${e.payload.duration ? ` (${
|
|
67
|
+
return `Vergadering beëindigd${e.payload.duration ? ` (${u(e.payload.duration)})` : ""}`;
|
|
68
68
|
case "MEETING_PARTICIPANT_JOINED":
|
|
69
69
|
return `${e.payload.name} deelgenomen`;
|
|
70
70
|
case "MEETING_PARTICIPANT_LEFT":
|
|
@@ -87,80 +87,104 @@ function _(e) {
|
|
|
87
87
|
return {
|
|
88
88
|
activityId: e.id,
|
|
89
89
|
type: e.type,
|
|
90
|
-
snippet:
|
|
90
|
+
snippet: E(p(e)),
|
|
91
91
|
authorName: e.author?.name ?? "",
|
|
92
92
|
direction: e.direction,
|
|
93
93
|
createdAt: e.createdAt ?? Date.now()
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
|
-
function
|
|
96
|
+
function f(e, t) {
|
|
97
|
+
const n = e.settings?.signatures?.[t];
|
|
98
|
+
return !n || !n.enabled || !n.body || n.body.trim() === "" ? null : n;
|
|
99
|
+
}
|
|
100
|
+
function g(e) {
|
|
97
101
|
return e.endpoints ?? [];
|
|
98
102
|
}
|
|
99
|
-
const
|
|
103
|
+
const T = (e) => !!e.assignedUserId || !!e.assignedInboxId, D = (e) => e.status === "closed", L = (e) => ({
|
|
100
104
|
urgent: 10,
|
|
101
105
|
high: 5,
|
|
102
106
|
normal: 2,
|
|
103
107
|
low: 1
|
|
104
|
-
})[e.priority] || 0,
|
|
108
|
+
})[e.priority] || 0, C = (e, t = 30) => e.title?.length <= t ? e.title : `${e.title.substring(0, t)}...`;
|
|
109
|
+
function N(e, t) {
|
|
110
|
+
return e.lastActivityAt ? !(e.seenBy ?? []).includes(t) : !1;
|
|
111
|
+
}
|
|
105
112
|
function d(e, t) {
|
|
106
|
-
const
|
|
107
|
-
if (!e.extraIntents || e.extraIntents.length === 0) return
|
|
108
|
-
const o = new Set(
|
|
113
|
+
const n = new Set(e.disabledIntents ?? []), r = e.intentOverrides ?? {}, s = t.intents.filter((a) => !n.has(a.intent)).map((a) => i(a, r[a.intent]));
|
|
114
|
+
if (!e.extraIntents || e.extraIntents.length === 0) return s;
|
|
115
|
+
const o = new Set(s.map((a) => a.intent));
|
|
109
116
|
for (const a of e.extraIntents)
|
|
110
|
-
o.has(a.intent) || (
|
|
117
|
+
o.has(a.intent) || (s.push(a), o.add(a.intent));
|
|
118
|
+
return s;
|
|
119
|
+
}
|
|
120
|
+
function c(e, t) {
|
|
121
|
+
const n = {};
|
|
122
|
+
for (const r of e.intents) {
|
|
123
|
+
if (!r.togglable) continue;
|
|
124
|
+
const s = t?.[r.intent];
|
|
125
|
+
n[r.intent] = s ?? r.defaultEnabled ?? !0;
|
|
126
|
+
}
|
|
111
127
|
return n;
|
|
112
128
|
}
|
|
113
|
-
function
|
|
129
|
+
function S(e, t) {
|
|
130
|
+
const n = c(e, t);
|
|
131
|
+
return Object.entries(n).filter(([, r]) => !r).map(([r]) => r);
|
|
132
|
+
}
|
|
133
|
+
function i(e, t) {
|
|
114
134
|
return t ? {
|
|
115
135
|
intent: t.intent ?? e.intent,
|
|
116
136
|
targetSchemes: t.targetSchemes ?? e.targetSchemes,
|
|
117
137
|
transport: t.transport ?? e.transport
|
|
118
138
|
} : e;
|
|
119
139
|
}
|
|
120
|
-
function
|
|
121
|
-
const
|
|
122
|
-
for (const
|
|
123
|
-
if (!
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
126
|
-
for (const o of d(
|
|
127
|
-
|
|
140
|
+
function O(e, t) {
|
|
141
|
+
const n = [];
|
|
142
|
+
for (const r of e) {
|
|
143
|
+
if (!r.enabled) continue;
|
|
144
|
+
const s = t[r.providerId];
|
|
145
|
+
if (s)
|
|
146
|
+
for (const o of d(r, s))
|
|
147
|
+
n.push({ channel: r, description: s, capability: o });
|
|
128
148
|
}
|
|
129
|
-
return
|
|
149
|
+
return n;
|
|
130
150
|
}
|
|
131
|
-
function
|
|
132
|
-
return t.filter((
|
|
151
|
+
function b(e, t) {
|
|
152
|
+
return t.filter((n) => n.capability.intent === e);
|
|
133
153
|
}
|
|
134
|
-
function
|
|
135
|
-
return t.filter((
|
|
154
|
+
function A(e, t) {
|
|
155
|
+
return t.filter((n) => n.capability.targetSchemes.includes(e));
|
|
136
156
|
}
|
|
137
|
-
function
|
|
138
|
-
return
|
|
157
|
+
function M(e, t) {
|
|
158
|
+
return A(e.scheme, t);
|
|
139
159
|
}
|
|
140
|
-
function
|
|
141
|
-
const
|
|
142
|
-
for (const
|
|
143
|
-
for (const o of
|
|
144
|
-
o.capability.intent === t && o.capability.targetSchemes.includes(
|
|
145
|
-
return
|
|
160
|
+
function R(e, t, n) {
|
|
161
|
+
const r = [];
|
|
162
|
+
for (const s of e)
|
|
163
|
+
for (const o of n)
|
|
164
|
+
o.capability.intent === t && o.capability.targetSchemes.includes(s.scheme) && r.push({ channelIntent: o, endpoint: s });
|
|
165
|
+
return r;
|
|
146
166
|
}
|
|
147
|
-
var
|
|
148
|
-
const
|
|
167
|
+
var I = /* @__PURE__ */ ((e) => (e.MAILTO = "mailto", e.SIP = "sip", e.TEL = "tel", e.WEBHOOK = "webhook", e.USERNAME = "username", e.ID = "id", e.CUSTOM = "custom", e.URL = "url", e.TELEGRAM = "telegram", e.WHATSAPP = "whatsapp", e.VIBER = "viber", e.SMS = "sms", e.FAX = "fax", e.TEAMS = "teams", e.CALENDAR = "calendar", e))(I || {});
|
|
168
|
+
const V = (e, t) => ({ intent: e, ...t }), P = { ok: !1, code: "UNSUPPORTED", message: "Provider does not support this op" };
|
|
149
169
|
export {
|
|
150
|
-
|
|
151
|
-
|
|
170
|
+
I as CommunicationScheme,
|
|
171
|
+
P as UNSUPPORTED,
|
|
152
172
|
_ as buildActivityPreview,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
S as
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
173
|
+
O as buildChannelIntents,
|
|
174
|
+
V as defineIntent,
|
|
175
|
+
S as disabledIntentsFromCapabilities,
|
|
176
|
+
M as filterByEndpoint,
|
|
177
|
+
b as filterByIntent,
|
|
178
|
+
A as filterByTargetScheme,
|
|
179
|
+
g as getContactEndpoints,
|
|
180
|
+
C as getShortTitle,
|
|
160
181
|
L as getUrgencyScore,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
182
|
+
T as isAssigned,
|
|
183
|
+
D as isClosed,
|
|
184
|
+
N as isInteractionUnseen,
|
|
185
|
+
R as matchContactToIntents,
|
|
186
|
+
c as resolveAccountCapabilities,
|
|
164
187
|
d as resolveChannelIntents,
|
|
165
|
-
|
|
188
|
+
f as resolveSignature,
|
|
189
|
+
l as stripHtml
|
|
166
190
|
};
|
|
@@ -33,6 +33,18 @@ export interface ChannelIntentMatch {
|
|
|
33
33
|
* source of truth, channel patches it.
|
|
34
34
|
*/
|
|
35
35
|
export declare function resolveChannelIntents(channel: Channel, description: ProviderDescription): IntentCapability[];
|
|
36
|
+
/**
|
|
37
|
+
* Resolve per-account capability-state vanuit provider description + user-keuze.
|
|
38
|
+
* Alleen `togglable` intents worden teruggegeven. Onbekende keys in `accountCaps`
|
|
39
|
+
* worden genegeerd — provider is source of truth.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveAccountCapabilities(description: ProviderDescription, accountCaps: Record<string, boolean> | undefined): Record<string, boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* Lijst van intent-namen die UIT staan voor dit account. Mapt 1-op-1 naar
|
|
44
|
+
* `Channel.disabledIntents`. Niet-togglable intents komen nooit op de lijst —
|
|
45
|
+
* die kan provider hardcode'n via eigen channel-kind constraint.
|
|
46
|
+
*/
|
|
47
|
+
export declare function disabledIntentsFromCapabilities(description: ProviderDescription, accountCaps: Record<string, boolean> | undefined): string[];
|
|
36
48
|
/**
|
|
37
49
|
* Builds the full set of (channel × intent) entries across all channels —
|
|
38
50
|
* the source for the starter palette.
|
|
@@ -116,6 +116,12 @@ export interface IntentCapability {
|
|
|
116
116
|
intent: string;
|
|
117
117
|
targetSchemes: CommunicationScheme[];
|
|
118
118
|
transport: TransportConfig;
|
|
119
|
+
/** User mag deze intent aan/uit zetten per account. Default false (provider-locked). */
|
|
120
|
+
togglable?: boolean;
|
|
121
|
+
/** Default-state als togglable=true en user nog geen keuze maakte. Default true. */
|
|
122
|
+
defaultEnabled?: boolean;
|
|
123
|
+
/** Optionele i18n-key voor toggle-label; UI valt anders terug op `cap_${intent}`. */
|
|
124
|
+
labelKey?: string;
|
|
119
125
|
}
|
|
120
126
|
/**
|
|
121
127
|
* Provider-level feature flag (no routing relevance). Used for things
|