@lssm-tech/integration.builder-whatsapp 0.2.11

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/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @contractspec/integration.builder-whatsapp
2
+
3
+ Meta and Twilio WhatsApp normalization for Builder control-channel workflows.
@@ -0,0 +1 @@
1
+ import{parseMetaWebhookPayload as B,parseTwilioFormPayload as N,verifyMetaSignature as x,verifyTwilioSignature as S}from"@contractspec/integration.runtime/channel";import{defineIntegration as $}from"@contractspec/lib.contracts-integrations";import{defineSchemaModel as Z}from"@contractspec/lib.schema";var z=Z({name:"BuilderWhatsappIntegrationConfig",description:"Managed configuration for @contractspec/integration.builder-whatsapp.",fields:{}}),F=Z({name:"BuilderWhatsappIntegrationSecret",description:"Secret material for @contractspec/integration.builder-whatsapp.",fields:{}}),P=$({meta:{...{key:"integrations.builder-whatsapp",version:"1.0.0",title:"Builder Whatsapp",description:"WhatsApp Builder control-channel integration.",domain:"builder-whatsapp",owners:["@contractspec-core"],tags:["package","integrations","builder-whatsapp"],stability:"experimental"},category:"custom"},supportedModes:["managed"],capabilities:{provides:[]},configSchema:{schema:z,example:{}},secretSchema:{schema:F,example:{}},healthCheck:{method:"ping",timeoutMs:5000}});function O(j){return j&&typeof j==="object"?j:null}function K(j,E,G,D,A){let C=typeof A.from==="string"?A.from:void 0,q=typeof A.id==="string"?A.id:void 0;if(!C||!q)return null;let L=O(A.text)?.body,Q=O(A.interactive),V=typeof Q?.type==="string"?Q.type:void 0,H=O(Q?.button_reply),J=O(Q?.list_reply),U=O(A.audio),X=O(A.document),Y=O(A.image),_=U?"voice":H?"button":J?"list_selection":"text";return{workspaceId:j,conversationId:E,channelType:"whatsapp",eventType:`whatsapp.meta.${typeof A.type==="string"?A.type:"message"}`,externalEventId:q,externalConversationId:C,externalChannelId:D,externalMessageId:q,participantBindingId:G,externalIdentityRef:C,externalUserId:C,messageKind:_,text:typeof L==="string"?L:typeof H?.title==="string"?H.title:typeof J?.title==="string"?J.title:void 0,interactiveSelection:H&&typeof H.id==="string"?{selectionType:"button",selectionId:H.id,label:typeof H.title==="string"?H.title:void 0,payload:{interactiveType:V}}:J&&typeof J.id==="string"?{selectionType:"list_selection",selectionId:J.id,label:typeof J.title==="string"?J.title:void 0,payload:{interactiveType:V}}:void 0,metadata:{phoneNumberId:D??"",audioId:typeof U?.id==="string"?U.id:"",documentId:typeof X?.id==="string"?X.id:"",imageId:typeof Y?.id==="string"?Y.id:""}}}function f(j){let E=[];for(let G of j.payload.entry??[])for(let D of G.changes??[]){let A=D.value;if(!A)continue;let C=A.metadata?.phone_number_id;for(let q of A.messages??[]){let L=K(j.workspaceId,j.conversationId,j.participantBindingId,C,q);if(L)E.push(L)}for(let q of A.statuses??[]){if(!q.id)continue;E.push({workspaceId:j.workspaceId,conversationId:j.conversationId,channelType:"whatsapp",eventType:"whatsapp.meta.status",externalEventId:q.id,externalConversationId:q.recipient_id??q.id,externalChannelId:C,externalMessageId:q.id,participantBindingId:j.participantBindingId,externalIdentityRef:q.recipient_id??void 0,externalUserId:q.recipient_id??void 0,messageKind:"system",statusEvent:{status:q.status??"unknown",providerMessageId:q.id},text:`status ${q.status??"unknown"}`})}}return E}function h(j){let E=j.formBody.get("MessageSid"),G=j.formBody.get("From");if(!E||!G)return null;let D=j.formBody.get("ButtonText"),A=j.formBody.get("ButtonPayload"),C=j.formBody.get("ListTitle")??j.formBody.get("ListSelection"),q=j.formBody.get("MediaContentType0"),L=D?"button":C?"list_selection":q?.startsWith("audio/")?"voice":"text";return{workspaceId:j.workspaceId,conversationId:j.conversationId,channelType:"whatsapp",eventType:"whatsapp.twilio.message",externalEventId:E,externalConversationId:G,externalChannelId:j.formBody.get("To")??void 0,externalMessageId:E,participantBindingId:j.participantBindingId,externalIdentityRef:G,externalUserId:G,messageKind:L,text:D??C??j.formBody.get("Body")??(q?`media ${q}`:void 0)??"",interactiveSelection:D?{selectionType:"button",selectionId:A??D,label:D}:C?{selectionType:"list_selection",selectionId:C,label:C}:void 0,metadata:{accountSid:j.formBody.get("AccountSid")??"",profileName:j.formBody.get("ProfileName")??"",mediaContentType0:q??"",mediaUrl0:j.formBody.get("MediaUrl0")??""}}}export{S as verifyTwilioSignature,x as verifyMetaSignature,N as parseTwilioFormPayload,B as parseMetaWebhookPayload,h as normalizeBuilderTwilioWhatsappEnvelope,f as normalizeBuilderMetaWhatsappEnvelopes,P as BuilderWhatsappIntegrationSpec};
@@ -0,0 +1,20 @@
1
+ import { type MetaWhatsappWebhookPayload, parseMetaWebhookPayload, parseTwilioFormPayload, verifyMetaSignature, verifyTwilioSignature } from '@contractspec/integration.runtime/channel';
2
+ import type { BuilderChannelInboundEnvelope } from '@contractspec/lib.builder-runtime';
3
+ export { type MetaWhatsappWebhookPayload, parseMetaWebhookPayload, parseTwilioFormPayload, verifyMetaSignature, verifyTwilioSignature, };
4
+ export declare function normalizeBuilderMetaWhatsappEnvelopes(input: {
5
+ workspaceId: string;
6
+ conversationId: string;
7
+ payload: MetaWhatsappWebhookPayload;
8
+ rawBody?: string;
9
+ traceId?: string;
10
+ participantBindingId?: string;
11
+ }): BuilderChannelInboundEnvelope[];
12
+ export declare function normalizeBuilderTwilioWhatsappEnvelope(input: {
13
+ workspaceId: string;
14
+ conversationId: string;
15
+ formBody: URLSearchParams;
16
+ rawBody?: string;
17
+ traceId?: string;
18
+ participantBindingId?: string;
19
+ }): BuilderChannelInboundEnvelope | null;
20
+ export * from './integration';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{parseMetaWebhookPayload as B,parseTwilioFormPayload as N,verifyMetaSignature as x,verifyTwilioSignature as S}from"@contractspec/integration.runtime/channel";import{defineIntegration as $}from"@contractspec/lib.contracts-integrations";import{defineSchemaModel as Z}from"@contractspec/lib.schema";var z=Z({name:"BuilderWhatsappIntegrationConfig",description:"Managed configuration for @contractspec/integration.builder-whatsapp.",fields:{}}),F=Z({name:"BuilderWhatsappIntegrationSecret",description:"Secret material for @contractspec/integration.builder-whatsapp.",fields:{}}),P=$({meta:{...{key:"integrations.builder-whatsapp",version:"1.0.0",title:"Builder Whatsapp",description:"WhatsApp Builder control-channel integration.",domain:"builder-whatsapp",owners:["@contractspec-core"],tags:["package","integrations","builder-whatsapp"],stability:"experimental"},category:"custom"},supportedModes:["managed"],capabilities:{provides:[]},configSchema:{schema:z,example:{}},secretSchema:{schema:F,example:{}},healthCheck:{method:"ping",timeoutMs:5000}});function O(j){return j&&typeof j==="object"?j:null}function K(j,E,G,D,A){let C=typeof A.from==="string"?A.from:void 0,q=typeof A.id==="string"?A.id:void 0;if(!C||!q)return null;let L=O(A.text)?.body,Q=O(A.interactive),V=typeof Q?.type==="string"?Q.type:void 0,H=O(Q?.button_reply),J=O(Q?.list_reply),U=O(A.audio),X=O(A.document),Y=O(A.image),_=U?"voice":H?"button":J?"list_selection":"text";return{workspaceId:j,conversationId:E,channelType:"whatsapp",eventType:`whatsapp.meta.${typeof A.type==="string"?A.type:"message"}`,externalEventId:q,externalConversationId:C,externalChannelId:D,externalMessageId:q,participantBindingId:G,externalIdentityRef:C,externalUserId:C,messageKind:_,text:typeof L==="string"?L:typeof H?.title==="string"?H.title:typeof J?.title==="string"?J.title:void 0,interactiveSelection:H&&typeof H.id==="string"?{selectionType:"button",selectionId:H.id,label:typeof H.title==="string"?H.title:void 0,payload:{interactiveType:V}}:J&&typeof J.id==="string"?{selectionType:"list_selection",selectionId:J.id,label:typeof J.title==="string"?J.title:void 0,payload:{interactiveType:V}}:void 0,metadata:{phoneNumberId:D??"",audioId:typeof U?.id==="string"?U.id:"",documentId:typeof X?.id==="string"?X.id:"",imageId:typeof Y?.id==="string"?Y.id:""}}}function f(j){let E=[];for(let G of j.payload.entry??[])for(let D of G.changes??[]){let A=D.value;if(!A)continue;let C=A.metadata?.phone_number_id;for(let q of A.messages??[]){let L=K(j.workspaceId,j.conversationId,j.participantBindingId,C,q);if(L)E.push(L)}for(let q of A.statuses??[]){if(!q.id)continue;E.push({workspaceId:j.workspaceId,conversationId:j.conversationId,channelType:"whatsapp",eventType:"whatsapp.meta.status",externalEventId:q.id,externalConversationId:q.recipient_id??q.id,externalChannelId:C,externalMessageId:q.id,participantBindingId:j.participantBindingId,externalIdentityRef:q.recipient_id??void 0,externalUserId:q.recipient_id??void 0,messageKind:"system",statusEvent:{status:q.status??"unknown",providerMessageId:q.id},text:`status ${q.status??"unknown"}`})}}return E}function h(j){let E=j.formBody.get("MessageSid"),G=j.formBody.get("From");if(!E||!G)return null;let D=j.formBody.get("ButtonText"),A=j.formBody.get("ButtonPayload"),C=j.formBody.get("ListTitle")??j.formBody.get("ListSelection"),q=j.formBody.get("MediaContentType0"),L=D?"button":C?"list_selection":q?.startsWith("audio/")?"voice":"text";return{workspaceId:j.workspaceId,conversationId:j.conversationId,channelType:"whatsapp",eventType:"whatsapp.twilio.message",externalEventId:E,externalConversationId:G,externalChannelId:j.formBody.get("To")??void 0,externalMessageId:E,participantBindingId:j.participantBindingId,externalIdentityRef:G,externalUserId:G,messageKind:L,text:D??C??j.formBody.get("Body")??(q?`media ${q}`:void 0)??"",interactiveSelection:D?{selectionType:"button",selectionId:A??D,label:D}:C?{selectionType:"list_selection",selectionId:C,label:C}:void 0,metadata:{accountSid:j.formBody.get("AccountSid")??"",profileName:j.formBody.get("ProfileName")??"",mediaContentType0:q??"",mediaUrl0:j.formBody.get("MediaUrl0")??""}}}export{S as verifyTwilioSignature,x as verifyMetaSignature,N as parseTwilioFormPayload,B as parseMetaWebhookPayload,h as normalizeBuilderTwilioWhatsappEnvelope,f as normalizeBuilderMetaWhatsappEnvelopes,P as BuilderWhatsappIntegrationSpec};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export declare const BuilderWhatsappIntegrationSpec: import("@contractspec/lib.contracts-integrations").IntegrationSpec;
@@ -0,0 +1 @@
1
+ import{parseMetaWebhookPayload as B,parseTwilioFormPayload as N,verifyMetaSignature as x,verifyTwilioSignature as S}from"@contractspec/integration.runtime/channel";import{defineIntegration as $}from"@contractspec/lib.contracts-integrations";import{defineSchemaModel as Z}from"@contractspec/lib.schema";var z=Z({name:"BuilderWhatsappIntegrationConfig",description:"Managed configuration for @contractspec/integration.builder-whatsapp.",fields:{}}),F=Z({name:"BuilderWhatsappIntegrationSecret",description:"Secret material for @contractspec/integration.builder-whatsapp.",fields:{}}),P=$({meta:{...{key:"integrations.builder-whatsapp",version:"1.0.0",title:"Builder Whatsapp",description:"WhatsApp Builder control-channel integration.",domain:"builder-whatsapp",owners:["@contractspec-core"],tags:["package","integrations","builder-whatsapp"],stability:"experimental"},category:"custom"},supportedModes:["managed"],capabilities:{provides:[]},configSchema:{schema:z,example:{}},secretSchema:{schema:F,example:{}},healthCheck:{method:"ping",timeoutMs:5000}});function O(j){return j&&typeof j==="object"?j:null}function K(j,E,G,D,A){let C=typeof A.from==="string"?A.from:void 0,q=typeof A.id==="string"?A.id:void 0;if(!C||!q)return null;let L=O(A.text)?.body,Q=O(A.interactive),V=typeof Q?.type==="string"?Q.type:void 0,H=O(Q?.button_reply),J=O(Q?.list_reply),U=O(A.audio),X=O(A.document),Y=O(A.image),_=U?"voice":H?"button":J?"list_selection":"text";return{workspaceId:j,conversationId:E,channelType:"whatsapp",eventType:`whatsapp.meta.${typeof A.type==="string"?A.type:"message"}`,externalEventId:q,externalConversationId:C,externalChannelId:D,externalMessageId:q,participantBindingId:G,externalIdentityRef:C,externalUserId:C,messageKind:_,text:typeof L==="string"?L:typeof H?.title==="string"?H.title:typeof J?.title==="string"?J.title:void 0,interactiveSelection:H&&typeof H.id==="string"?{selectionType:"button",selectionId:H.id,label:typeof H.title==="string"?H.title:void 0,payload:{interactiveType:V}}:J&&typeof J.id==="string"?{selectionType:"list_selection",selectionId:J.id,label:typeof J.title==="string"?J.title:void 0,payload:{interactiveType:V}}:void 0,metadata:{phoneNumberId:D??"",audioId:typeof U?.id==="string"?U.id:"",documentId:typeof X?.id==="string"?X.id:"",imageId:typeof Y?.id==="string"?Y.id:""}}}function f(j){let E=[];for(let G of j.payload.entry??[])for(let D of G.changes??[]){let A=D.value;if(!A)continue;let C=A.metadata?.phone_number_id;for(let q of A.messages??[]){let L=K(j.workspaceId,j.conversationId,j.participantBindingId,C,q);if(L)E.push(L)}for(let q of A.statuses??[]){if(!q.id)continue;E.push({workspaceId:j.workspaceId,conversationId:j.conversationId,channelType:"whatsapp",eventType:"whatsapp.meta.status",externalEventId:q.id,externalConversationId:q.recipient_id??q.id,externalChannelId:C,externalMessageId:q.id,participantBindingId:j.participantBindingId,externalIdentityRef:q.recipient_id??void 0,externalUserId:q.recipient_id??void 0,messageKind:"system",statusEvent:{status:q.status??"unknown",providerMessageId:q.id},text:`status ${q.status??"unknown"}`})}}return E}function h(j){let E=j.formBody.get("MessageSid"),G=j.formBody.get("From");if(!E||!G)return null;let D=j.formBody.get("ButtonText"),A=j.formBody.get("ButtonPayload"),C=j.formBody.get("ListTitle")??j.formBody.get("ListSelection"),q=j.formBody.get("MediaContentType0"),L=D?"button":C?"list_selection":q?.startsWith("audio/")?"voice":"text";return{workspaceId:j.workspaceId,conversationId:j.conversationId,channelType:"whatsapp",eventType:"whatsapp.twilio.message",externalEventId:E,externalConversationId:G,externalChannelId:j.formBody.get("To")??void 0,externalMessageId:E,participantBindingId:j.participantBindingId,externalIdentityRef:G,externalUserId:G,messageKind:L,text:D??C??j.formBody.get("Body")??(q?`media ${q}`:void 0)??"",interactiveSelection:D?{selectionType:"button",selectionId:A??D,label:D}:C?{selectionType:"list_selection",selectionId:C,label:C}:void 0,metadata:{accountSid:j.formBody.get("AccountSid")??"",profileName:j.formBody.get("ProfileName")??"",mediaContentType0:q??"",mediaUrl0:j.formBody.get("MediaUrl0")??""}}}export{S as verifyTwilioSignature,x as verifyMetaSignature,N as parseTwilioFormPayload,B as parseMetaWebhookPayload,h as normalizeBuilderTwilioWhatsappEnvelope,f as normalizeBuilderMetaWhatsappEnvelopes,P as BuilderWhatsappIntegrationSpec};
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@lssm-tech/integration.builder-whatsapp",
3
+ "version": "0.2.11",
4
+ "description": "WhatsApp Builder control-channel integration.",
5
+ "keywords": [
6
+ "contractspec",
7
+ "builder",
8
+ "whatsapp",
9
+ "integration"
10
+ ],
11
+ "type": "module",
12
+ "types": "./dist/index.d.ts",
13
+ "files": [
14
+ "dist",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
19
+ "publish:pkg:canary": "bun publish:pkg --tag canary",
20
+ "build": "bun run build:bundle && bun run build:types",
21
+ "build:bundle": "contractspec-bun-build transpile",
22
+ "build:types": "contractspec-bun-build types",
23
+ "dev": "contractspec-bun-build dev",
24
+ "clean": "rimraf dist .turbo",
25
+ "lint": "bun lint:fix",
26
+ "lint:fix": "node ../../../scripts/biome.cjs check --write --unsafe --only=nursery/useSortedClasses . && node ../../../scripts/biome.cjs check --write .",
27
+ "lint:check": "node ../../../scripts/biome.cjs check .",
28
+ "test": "bun test",
29
+ "prebuild": "contractspec-bun-build prebuild",
30
+ "typecheck": "tsc --noEmit"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/lssm-tech/contractspec.git",
35
+ "directory": "packages/integrations/builder-whatsapp"
36
+ },
37
+ "dependencies": {
38
+ "@contractspec/lib.builder-spec": "0.2.11",
39
+ "@contractspec/lib.builder-runtime": "0.2.11",
40
+ "@contractspec/lib.provider-spec": "0.2.9",
41
+ "@contractspec/integration.runtime": "3.10.1",
42
+ "@contractspec/lib.contracts-integrations": "3.10.0",
43
+ "@contractspec/lib.schema": "3.7.14"
44
+ },
45
+ "devDependencies": {
46
+ "@contractspec/tool.bun": "3.7.18",
47
+ "@contractspec/tool.typescript": "3.7.13",
48
+ "typescript": "^5.9.3"
49
+ },
50
+ "exports": {
51
+ ".": {
52
+ "types": "./dist/index.d.ts",
53
+ "browser": "./dist/browser/index.js",
54
+ "bun": "./dist/index.js",
55
+ "node": "./dist/node/index.js",
56
+ "default": "./dist/index.js"
57
+ }
58
+ },
59
+ "publishConfig": {
60
+ "access": "public",
61
+ "registry": "https://registry.npmjs.org",
62
+ "exports": {
63
+ ".": {
64
+ "types": "./dist/index.d.ts",
65
+ "browser": "./dist/browser/index.js",
66
+ "bun": "./dist/index.js",
67
+ "node": "./dist/node/index.js",
68
+ "default": "./dist/index.js"
69
+ }
70
+ }
71
+ }
72
+ }