@fabric-harness/channels 0.16.1 → 0.17.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.
- package/NOTICE +4 -0
- package/README.md +6 -1
- package/dist/compatibility.d.ts +143 -0
- package/dist/compatibility.d.ts.map +1 -0
- package/dist/compatibility.js +30 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/discord.d.ts +53 -0
- package/dist/discord.d.ts.map +1 -0
- package/dist/discord.js +95 -0
- package/dist/discord.js.map +1 -0
- package/dist/github.d.ts +37 -1
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +5 -5
- package/dist/github.js.map +1 -1
- package/dist/google-chat.d.ts +59 -0
- package/dist/google-chat.d.ts.map +1 -0
- package/dist/google-chat.js +127 -0
- package/dist/google-chat.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/intercom.d.ts +47 -0
- package/dist/intercom.d.ts.map +1 -0
- package/dist/intercom.js +40 -0
- package/dist/intercom.js.map +1 -0
- package/dist/linear.d.ts +46 -0
- package/dist/linear.d.ts.map +1 -0
- package/dist/linear.js +27 -0
- package/dist/linear.js.map +1 -0
- package/dist/messenger.d.ts +59 -0
- package/dist/messenger.d.ts.map +1 -0
- package/dist/messenger.js +49 -0
- package/dist/messenger.js.map +1 -0
- package/dist/notion.d.ts +46 -0
- package/dist/notion.d.ts.map +1 -0
- package/dist/notion.js +32 -0
- package/dist/notion.js.map +1 -0
- package/dist/resend.d.ts +44 -0
- package/dist/resend.d.ts.map +1 -0
- package/dist/resend.js +49 -0
- package/dist/resend.js.map +1 -0
- package/dist/salesforce-marketing-cloud.d.ts +39 -0
- package/dist/salesforce-marketing-cloud.d.ts.map +1 -0
- package/dist/salesforce-marketing-cloud.js +21 -0
- package/dist/salesforce-marketing-cloud.js.map +1 -0
- package/dist/shopify.d.ts +38 -0
- package/dist/shopify.d.ts.map +1 -0
- package/dist/shopify.js +29 -0
- package/dist/shopify.js.map +1 -0
- package/dist/slack.d.ts +19 -1
- package/dist/slack.d.ts.map +1 -1
- package/dist/slack.js +19 -7
- package/dist/slack.js.map +1 -1
- package/dist/stripe.d.ts +40 -0
- package/dist/stripe.d.ts.map +1 -0
- package/dist/stripe.js +58 -0
- package/dist/stripe.js.map +1 -0
- package/dist/teams.d.ts +58 -0
- package/dist/teams.d.ts.map +1 -0
- package/dist/teams.js +154 -0
- package/dist/teams.js.map +1 -0
- package/dist/telegram.d.ts +53 -0
- package/dist/telegram.d.ts.map +1 -0
- package/dist/telegram.js +76 -0
- package/dist/telegram.js.map +1 -0
- package/dist/twilio.d.ts +39 -0
- package/dist/twilio.d.ts.map +1 -0
- package/dist/twilio.js +83 -0
- package/dist/twilio.js.map +1 -0
- package/dist/webhook-shared.d.ts +43 -0
- package/dist/webhook-shared.d.ts.map +1 -0
- package/dist/webhook-shared.js +100 -0
- package/dist/webhook-shared.js.map +1 -0
- package/dist/whatsapp.d.ts +53 -0
- package/dist/whatsapp.d.ts.map +1 -0
- package/dist/whatsapp.js +98 -0
- package/dist/whatsapp.js.map +1 -0
- package/dist/zendesk.d.ts +48 -0
- package/dist/zendesk.d.ts.map +1 -0
- package/dist/zendesk.js +36 -0
- package/dist/zendesk.js.map +1 -0
- package/package.json +74 -5
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createJsonWebhookChannel, jsonWriteTool, parseSimpleConversationKey, simpleConversationKey, } from './webhook-shared.js';
|
|
2
|
+
export function googleChatConversationKey(ref) {
|
|
3
|
+
return simpleConversationKey('google-chat', ref);
|
|
4
|
+
}
|
|
5
|
+
export function parseGoogleChatConversationKey(id) {
|
|
6
|
+
return parseSimpleConversationKey('google-chat', id);
|
|
7
|
+
}
|
|
8
|
+
export function createGoogleChatChannel(options) {
|
|
9
|
+
if (!options.authenticate && !options.audience)
|
|
10
|
+
throw new Error('Google Chat requires an audience or authenticate callback.');
|
|
11
|
+
return createJsonWebhookChannel({
|
|
12
|
+
name: 'google-chat', agent: options.agent,
|
|
13
|
+
authenticate: (request) => options.authenticate?.(request) ?? verifyGoogleChatRequest(request, {
|
|
14
|
+
audience: options.audience ?? '', fetchImpl: options.fetchImpl, now: options.now,
|
|
15
|
+
}),
|
|
16
|
+
normalize: (event) => {
|
|
17
|
+
const space = event.space?.name;
|
|
18
|
+
const thread = event.thread?.name ?? event.message?.name;
|
|
19
|
+
const actor = event.user?.name ?? event.message?.sender?.name;
|
|
20
|
+
const tenantId = typeof options.tenantId === 'function' ? options.tenantId(event) : options.tenantId ?? space;
|
|
21
|
+
if (!space || !thread || !actor || !tenantId || event.user?.type === 'BOT' || event.message?.sender?.type === 'BOT')
|
|
22
|
+
return undefined;
|
|
23
|
+
return {
|
|
24
|
+
ref: { tenantId, conversationId: `${space}/${thread}` },
|
|
25
|
+
dedupeKey: event.message?.name ?? `${event.type ?? 'event'}:${event.eventTime ?? thread}`,
|
|
26
|
+
actorId: actor,
|
|
27
|
+
input: { type: `google-chat.${(event.type ?? 'message').toLowerCase()}`, text: event.message?.text, space, thread, locale: event.common?.userLocale },
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export async function verifyGoogleChatRequest(request, options) {
|
|
33
|
+
const authorization = request.headers.get('authorization');
|
|
34
|
+
if (!authorization?.startsWith('Bearer '))
|
|
35
|
+
return false;
|
|
36
|
+
const parts = authorization.slice(7).split('.');
|
|
37
|
+
if (parts.length !== 3)
|
|
38
|
+
return false;
|
|
39
|
+
try {
|
|
40
|
+
const [headerPart, claimsPart, signaturePart] = parts;
|
|
41
|
+
if (!headerPart || !claimsPart || !signaturePart)
|
|
42
|
+
return false;
|
|
43
|
+
const header = decodeJwtPart(headerPart);
|
|
44
|
+
const claims = decodeJwtPart(claimsPart);
|
|
45
|
+
if (header.alg !== 'RS256' || !header.kid || claims.iss !== 'chat@system.gserviceaccount.com')
|
|
46
|
+
return false;
|
|
47
|
+
const audiences = typeof options.audience === 'string' ? [options.audience] : options.audience;
|
|
48
|
+
const tokenAudiences = typeof claims.aud === 'string' ? [claims.aud] : claims.aud ?? [];
|
|
49
|
+
if (!audiences.some((audience) => tokenAudiences.includes(audience)))
|
|
50
|
+
return false;
|
|
51
|
+
const now = Math.floor((options.now?.() ?? Date.now()) / 1000);
|
|
52
|
+
if (typeof claims.exp !== 'number' || claims.exp <= now || (typeof claims.nbf === 'number' && claims.nbf > now + 60))
|
|
53
|
+
return false;
|
|
54
|
+
const response = await (options.fetchImpl ?? fetch)('https://www.googleapis.com/service_accounts/v1/metadata/x509/chat%40system.gserviceaccount.com');
|
|
55
|
+
if (!response.ok)
|
|
56
|
+
return false;
|
|
57
|
+
const certificates = await response.json();
|
|
58
|
+
const certificate = certificates[header.kid];
|
|
59
|
+
if (!certificate)
|
|
60
|
+
return false;
|
|
61
|
+
const publicKey = await crypto.subtle.importKey('spki', new Uint8Array(pemPublicKey(certificate)).buffer, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, ['verify']);
|
|
62
|
+
return crypto.subtle.verify('RSASSA-PKCS1-v1_5', publicKey, new Uint8Array(base64UrlBytes(signaturePart)).buffer, new TextEncoder().encode(`${headerPart}.${claimsPart}`));
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function decodeJwtPart(value) {
|
|
69
|
+
return JSON.parse(new TextDecoder().decode(base64UrlBytes(value)));
|
|
70
|
+
}
|
|
71
|
+
function base64UrlBytes(value) {
|
|
72
|
+
const normalized = value.replaceAll('-', '+').replaceAll('_', '/').padEnd(Math.ceil(value.length / 4) * 4, '=');
|
|
73
|
+
return Uint8Array.from(atob(normalized), (character) => character.charCodeAt(0));
|
|
74
|
+
}
|
|
75
|
+
function pemPublicKey(certificate) {
|
|
76
|
+
const isPublicKey = certificate.includes('BEGIN PUBLIC KEY');
|
|
77
|
+
const body = certificate.replace(/-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----|\s/g, '');
|
|
78
|
+
if (isPublicKey) {
|
|
79
|
+
const publicKeyBody = certificate.replace(/-----BEGIN PUBLIC KEY-----|-----END PUBLIC KEY-----|\s/g, '');
|
|
80
|
+
return Uint8Array.from(atob(publicKeyBody), (character) => character.charCodeAt(0));
|
|
81
|
+
}
|
|
82
|
+
const der = Uint8Array.from(atob(body), (character) => character.charCodeAt(0));
|
|
83
|
+
return extractSubjectPublicKeyInfo(der);
|
|
84
|
+
}
|
|
85
|
+
function extractSubjectPublicKeyInfo(certificate) {
|
|
86
|
+
// X.509 certificate -> TBSCertificate -> subjectPublicKeyInfo. The tiny DER walker keeps the
|
|
87
|
+
// adapter dependency-free and only accepts definite-length DER emitted by Google's cert service.
|
|
88
|
+
const root = readDer(certificate, 0);
|
|
89
|
+
const tbs = readDer(certificate, root.contentOffset);
|
|
90
|
+
let offset = tbs.contentOffset;
|
|
91
|
+
if (certificate[offset] === 0xa0)
|
|
92
|
+
offset = readDer(certificate, offset).end;
|
|
93
|
+
for (let index = 0; index < 5; index += 1)
|
|
94
|
+
offset = readDer(certificate, offset).end;
|
|
95
|
+
const spki = readDer(certificate, offset);
|
|
96
|
+
return certificate.slice(spki.offset, spki.end);
|
|
97
|
+
}
|
|
98
|
+
function readDer(bytes, offset) {
|
|
99
|
+
if (offset + 2 > bytes.length)
|
|
100
|
+
throw new Error('Invalid DER value.');
|
|
101
|
+
const firstLength = bytes[offset + 1] ?? 0;
|
|
102
|
+
let length = firstLength;
|
|
103
|
+
let contentOffset = offset + 2;
|
|
104
|
+
if (firstLength & 0x80) {
|
|
105
|
+
const count = firstLength & 0x7f;
|
|
106
|
+
if (count === 0 || count > 4 || contentOffset + count > bytes.length)
|
|
107
|
+
throw new Error('Invalid DER length.');
|
|
108
|
+
length = 0;
|
|
109
|
+
for (let index = 0; index < count; index += 1)
|
|
110
|
+
length = length * 256 + (bytes[contentOffset + index] ?? 0);
|
|
111
|
+
contentOffset += count;
|
|
112
|
+
}
|
|
113
|
+
const end = contentOffset + length;
|
|
114
|
+
if (end > bytes.length)
|
|
115
|
+
throw new Error('Invalid DER bounds.');
|
|
116
|
+
return { offset, contentOffset, end };
|
|
117
|
+
}
|
|
118
|
+
export function replyInGoogleChat(ref, options) {
|
|
119
|
+
return jsonWriteTool({
|
|
120
|
+
name: 'reply_in_google_chat', description: 'Reply in the Google Chat space this agent is handling.', provider: 'google-chat', fetchImpl: options.fetchImpl,
|
|
121
|
+
url: `https://chat.googleapis.com/v1/${options.space}/messages`,
|
|
122
|
+
headers: { authorization: `Bearer ${options.accessToken}` },
|
|
123
|
+
inputSchema: { properties: { text: { type: 'string', minLength: 1 } }, required: ['text'] },
|
|
124
|
+
body: ({ text }) => ({ text, ...(options.thread ? { thread: { name: options.thread } } : {}) }),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=google-chat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-chat.js","sourceRoot":"","sources":["../src/google-chat.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { defineChannel, hmacSha256, verifyHmacSha256, bytesToHex, hexToBytes, conversationKey, parseConversationKey, readRequestBody, } from '@fabric-harness/sdk';
|
|
2
|
-
export type { Channel, ChannelRoute, ChannelContext, ChannelDispatch, ChannelDispatchRequest, ParsedConversationKey } from '@fabric-harness/sdk';
|
|
1
|
+
export { defineChannel, hmacSha256, verifyHmacSha256, bytesToHex, hexToBytes, conversationKey, parseConversationKey, readRequestBody, } from '@fabric-harness/sdk/channel';
|
|
2
|
+
export type { Channel, ChannelRoute, ChannelContext, ChannelDispatch, ChannelDispatchRequest, ParsedConversationKey } from '@fabric-harness/sdk/channel';
|
|
3
|
+
export { channelCompatibility, channelCompatibilityPolicy } from './compatibility.js';
|
|
4
|
+
export type { ChannelCompatibility, ChannelCompatibilityStatus, FirstPartyChannelName } from './compatibility.js';
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,eAAe,GAChB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,eAAe,GAChB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzJ,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACtF,YAAY,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Convenience re-export of the core channel seam (defined in @fabric-harness/sdk). Vendor adapters
|
|
2
2
|
// live behind subpath exports, e.g. `@fabric-harness/channels/slack`.
|
|
3
|
-
export { defineChannel, hmacSha256, verifyHmacSha256, bytesToHex, hexToBytes, conversationKey, parseConversationKey, readRequestBody, } from '@fabric-harness/sdk';
|
|
3
|
+
export { defineChannel, hmacSha256, verifyHmacSha256, bytesToHex, hexToBytes, conversationKey, parseConversationKey, readRequestBody, } from '@fabric-harness/sdk/channel';
|
|
4
|
+
export { channelCompatibility, channelCompatibilityPolicy } from './compatibility.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,sEAAsE;AACtE,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,eAAe,GAChB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,sEAAsE;AACtE,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,eAAe,GAChB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Channel, ToolDef } from '@fabric-harness/sdk/channel';
|
|
2
|
+
import { type SimpleConversationRef } from './webhook-shared.js';
|
|
3
|
+
export interface IntercomConversationRef extends SimpleConversationRef {
|
|
4
|
+
}
|
|
5
|
+
export interface IntercomWebhookPayload {
|
|
6
|
+
type?: string;
|
|
7
|
+
id?: string;
|
|
8
|
+
topic?: string;
|
|
9
|
+
app_id?: string;
|
|
10
|
+
created_at?: number;
|
|
11
|
+
data?: {
|
|
12
|
+
item?: {
|
|
13
|
+
id?: string;
|
|
14
|
+
conversation_id?: string;
|
|
15
|
+
ticket_id?: string;
|
|
16
|
+
user_id?: string;
|
|
17
|
+
contact?: {
|
|
18
|
+
id?: string;
|
|
19
|
+
};
|
|
20
|
+
contacts?: Array<{
|
|
21
|
+
id?: string;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface IntercomChannelOptions {
|
|
27
|
+
clientSecret: string;
|
|
28
|
+
agent: string;
|
|
29
|
+
tenantId?: string | ((payload: IntercomWebhookPayload) => string | undefined);
|
|
30
|
+
}
|
|
31
|
+
export interface IntercomChannel extends Channel {
|
|
32
|
+
conversationKey(ref: IntercomConversationRef): string;
|
|
33
|
+
parseConversationKey(id: string): IntercomConversationRef;
|
|
34
|
+
}
|
|
35
|
+
export declare const intercomConversationKey: (ref: IntercomConversationRef) => string;
|
|
36
|
+
export declare const parseIntercomConversationKey: (id: string) => SimpleConversationRef;
|
|
37
|
+
export declare function createIntercomChannel(options: IntercomChannelOptions): IntercomChannel;
|
|
38
|
+
export declare function replyInIntercom(ref: IntercomConversationRef, options: {
|
|
39
|
+
accessToken: string;
|
|
40
|
+
conversationId: string;
|
|
41
|
+
adminId: string;
|
|
42
|
+
apiVersion?: string;
|
|
43
|
+
fetchImpl?: typeof fetch;
|
|
44
|
+
}): ToolDef<{
|
|
45
|
+
text: string;
|
|
46
|
+
}, unknown>;
|
|
47
|
+
//# sourceMappingURL=intercom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intercom.d.ts","sourceRoot":"","sources":["../src/intercom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAA8F,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE7J,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;CAAG;AACzE,MAAM,WAAW,sBAAsB;IAAG,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE;YAAE,EAAE,CAAC,EAAE,MAAM,CAAC;YAAC,eAAe,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE;gBAAE,EAAE,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;gBAAE,EAAE,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE;AAC7R,MAAM,WAAW,sBAAsB;IAAG,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,sBAAsB,KAAK,MAAM,GAAG,SAAS,CAAC,CAAA;CAAE;AAC9J,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAAG,eAAe,CAAC,GAAG,EAAE,uBAAuB,GAAG,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE;AAErK,eAAO,MAAM,uBAAuB,GAAI,KAAK,uBAAuB,WAA2C,CAAC;AAChH,eAAO,MAAM,4BAA4B,GAAI,IAAI,MAAM,0BAA+C,CAAC;AAWvG,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CAatF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,uBAAuB,EAAE,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,CAQ1N"}
|
package/dist/intercom.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createJsonWebhookChannel, jsonWriteTool, parseSimpleConversationKey, simpleConversationKey } from './webhook-shared.js';
|
|
2
|
+
export const intercomConversationKey = (ref) => simpleConversationKey('intercom', ref);
|
|
3
|
+
export const parseIntercomConversationKey = (id) => parseSimpleConversationKey('intercom', id);
|
|
4
|
+
async function verifyIntercom(secret, raw, signature) {
|
|
5
|
+
if (!signature?.startsWith('sha1='))
|
|
6
|
+
return false;
|
|
7
|
+
try {
|
|
8
|
+
const expected = Uint8Array.from(signature.slice(5).match(/.{2}/g) ?? [], (value) => Number.parseInt(value, 16));
|
|
9
|
+
const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-1' }, false, ['verify']);
|
|
10
|
+
return expected.length === 20 && await crypto.subtle.verify('HMAC', key, new Uint8Array(expected).buffer, new Uint8Array(raw).buffer);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function createIntercomChannel(options) {
|
|
17
|
+
return createJsonWebhookChannel({
|
|
18
|
+
name: 'intercom', agent: options.agent,
|
|
19
|
+
authenticate: (request, raw) => verifyIntercom(options.clientSecret, raw, request.headers.get('x-hub-signature')),
|
|
20
|
+
normalize: (payload) => {
|
|
21
|
+
const item = payload.data?.item;
|
|
22
|
+
const conversationId = item?.conversation_id ?? item?.ticket_id ?? item?.id;
|
|
23
|
+
const actor = item?.user_id ?? item?.contact?.id ?? item?.contacts?.[0]?.id;
|
|
24
|
+
const tenantId = (typeof options.tenantId === 'function' ? options.tenantId(payload) : options.tenantId) ?? payload.app_id;
|
|
25
|
+
if (!payload.id || !conversationId || !actor || !tenantId)
|
|
26
|
+
return undefined;
|
|
27
|
+
return { ref: { tenantId, conversationId }, dedupeKey: payload.id, actorId: actor, input: { type: `intercom.${payload.topic ?? 'event'}`, item, createdAt: payload.created_at } };
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export function replyInIntercom(ref, options) {
|
|
32
|
+
return jsonWriteTool({
|
|
33
|
+
name: 'reply_in_intercom', description: 'Reply to the Intercom conversation this agent is handling.', provider: 'intercom', fetchImpl: options.fetchImpl,
|
|
34
|
+
url: `https://api.intercom.io/conversations/${encodeURIComponent(options.conversationId)}/reply`,
|
|
35
|
+
headers: { authorization: `Bearer ${options.accessToken}`, 'intercom-version': options.apiVersion ?? '2.14' },
|
|
36
|
+
inputSchema: { properties: { text: { type: 'string', minLength: 1 } }, required: ['text'] },
|
|
37
|
+
body: ({ text }) => ({ message_type: 'comment', type: 'admin', admin_id: options.adminId, body: text }),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=intercom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intercom.js","sourceRoot":"","sources":["../src/intercom.ts"],"names":[],"mappings":"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"}
|
package/dist/linear.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Channel, ToolDef } from '@fabric-harness/sdk/channel';
|
|
2
|
+
import { type SimpleConversationRef } from './webhook-shared.js';
|
|
3
|
+
export interface LinearConversationRef extends SimpleConversationRef {
|
|
4
|
+
}
|
|
5
|
+
export interface LinearWebhookPayload {
|
|
6
|
+
action?: string;
|
|
7
|
+
type?: string;
|
|
8
|
+
organizationId?: string;
|
|
9
|
+
webhookId?: string;
|
|
10
|
+
webhookTimestamp?: number;
|
|
11
|
+
data?: {
|
|
12
|
+
id?: string;
|
|
13
|
+
teamId?: string;
|
|
14
|
+
creatorId?: string;
|
|
15
|
+
userId?: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
body?: string;
|
|
19
|
+
url?: string;
|
|
20
|
+
};
|
|
21
|
+
actor?: {
|
|
22
|
+
id?: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
type?: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface LinearChannelOptions {
|
|
28
|
+
signingSecret: string;
|
|
29
|
+
agent: string;
|
|
30
|
+
tenantId?: string | ((payload: LinearWebhookPayload) => string | undefined);
|
|
31
|
+
}
|
|
32
|
+
export interface LinearChannel extends Channel {
|
|
33
|
+
conversationKey(ref: LinearConversationRef): string;
|
|
34
|
+
parseConversationKey(id: string): LinearConversationRef;
|
|
35
|
+
}
|
|
36
|
+
export declare const linearConversationKey: (ref: LinearConversationRef) => string;
|
|
37
|
+
export declare const parseLinearConversationKey: (id: string) => SimpleConversationRef;
|
|
38
|
+
export declare function createLinearChannel(options: LinearChannelOptions): LinearChannel;
|
|
39
|
+
export declare function commentOnLinearIssue(ref: LinearConversationRef, options: {
|
|
40
|
+
apiKey: string;
|
|
41
|
+
issueId: string;
|
|
42
|
+
fetchImpl?: typeof fetch;
|
|
43
|
+
}): ToolDef<{
|
|
44
|
+
text: string;
|
|
45
|
+
}, unknown>;
|
|
46
|
+
//# sourceMappingURL=linear.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../src/linear.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAA6G,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5K,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;CAAG;AACvE,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChJ,KAAK,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AACD,MAAM,WAAW,oBAAoB;IAAG,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,GAAG,SAAS,CAAC,CAAA;CAAE;AAC3J,MAAM,WAAW,aAAc,SAAQ,OAAO;IAAG,eAAe,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,CAAA;CAAE;AAE/J,eAAO,MAAM,qBAAqB,GAAI,KAAK,qBAAqB,WAAyC,CAAC;AAC1G,eAAO,MAAM,0BAA0B,GAAI,IAAI,MAAM,0BAA6C,CAAC;AAEnG,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAahF;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,CAO3K"}
|
package/dist/linear.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createJsonWebhookChannel, jsonWriteTool, parseSimpleConversationKey, simpleConversationKey, verifyHexHmac } from './webhook-shared.js';
|
|
2
|
+
export const linearConversationKey = (ref) => simpleConversationKey('linear', ref);
|
|
3
|
+
export const parseLinearConversationKey = (id) => parseSimpleConversationKey('linear', id);
|
|
4
|
+
export function createLinearChannel(options) {
|
|
5
|
+
return createJsonWebhookChannel({
|
|
6
|
+
name: 'linear', agent: options.agent,
|
|
7
|
+
authenticate: (request, raw) => verifyHexHmac(options.signingSecret, raw, request.headers.get('linear-signature')),
|
|
8
|
+
normalize: (payload) => {
|
|
9
|
+
const objectId = payload.data?.id;
|
|
10
|
+
const tenantId = typeof options.tenantId === 'function' ? options.tenantId(payload) : options.tenantId ?? payload.organizationId;
|
|
11
|
+
const actor = payload.actor?.id ?? payload.data?.creatorId ?? payload.data?.userId;
|
|
12
|
+
const delivery = payload.webhookId ?? `${payload.type}:${payload.action}:${objectId}:${payload.webhookTimestamp}`;
|
|
13
|
+
if (!objectId || !tenantId || !actor || payload.actor?.type === 'application')
|
|
14
|
+
return undefined;
|
|
15
|
+
return { ref: { tenantId, conversationId: objectId }, dedupeKey: delivery, actorId: actor, input: { type: `linear.${payload.type ?? 'event'}`, action: payload.action, ...payload.data } };
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function commentOnLinearIssue(ref, options) {
|
|
20
|
+
return jsonWriteTool({
|
|
21
|
+
name: 'comment_on_linear_issue', description: 'Post a comment on the Linear issue this agent is handling.', provider: 'linear', fetchImpl: options.fetchImpl,
|
|
22
|
+
url: 'https://api.linear.app/graphql', headers: { authorization: options.apiKey },
|
|
23
|
+
inputSchema: { properties: { text: { type: 'string', minLength: 1 } }, required: ['text'] },
|
|
24
|
+
body: ({ text }) => ({ query: 'mutation CommentCreate($input: CommentCreateInput!) { commentCreate(input: $input) { success comment { id } } }', variables: { input: { issueId: options.issueId, body: text } } }),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=linear.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear.js","sourceRoot":"","sources":["../src/linear.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,aAAa,EAA8B,MAAM,qBAAqB,CAAC;AAe5K,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAA0B,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AAC1G,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,0BAA0B,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAEnG,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,OAAO,wBAAwB,CAAuB;QACpD,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK;QACpC,YAAY,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAClH,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,OAAO,OAAO,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;YACjI,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;YACnF,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,QAAQ,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAClH,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,KAAK,aAAa;gBAAE,OAAO,SAAS,CAAC;YAChG,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7L,CAAC;KACF,CAAkB,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAA0B,EAAE,OAAsE;IACrI,OAAO,aAAa,CAAC;QACnB,IAAI,EAAE,yBAAyB,EAAE,WAAW,EAAE,4DAA4D,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5J,GAAG,EAAE,gCAAgC,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE;QACjF,WAAW,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;QAC3F,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,iHAAiH,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KACnN,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Channel, ToolDef } from '@fabric-harness/sdk/channel';
|
|
2
|
+
export interface MessengerConversationRef {
|
|
3
|
+
pageId: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
}
|
|
6
|
+
export interface MessengerWebhookPayload {
|
|
7
|
+
object?: string;
|
|
8
|
+
entry?: Array<{
|
|
9
|
+
id?: string;
|
|
10
|
+
time?: number;
|
|
11
|
+
messaging?: Array<{
|
|
12
|
+
sender?: {
|
|
13
|
+
id?: string;
|
|
14
|
+
};
|
|
15
|
+
recipient?: {
|
|
16
|
+
id?: string;
|
|
17
|
+
};
|
|
18
|
+
timestamp?: number;
|
|
19
|
+
message?: {
|
|
20
|
+
mid?: string;
|
|
21
|
+
text?: string;
|
|
22
|
+
is_echo?: boolean;
|
|
23
|
+
};
|
|
24
|
+
postback?: {
|
|
25
|
+
mid?: string;
|
|
26
|
+
payload?: string;
|
|
27
|
+
title?: string;
|
|
28
|
+
};
|
|
29
|
+
delivery?: {
|
|
30
|
+
mids?: string[];
|
|
31
|
+
watermark?: number;
|
|
32
|
+
};
|
|
33
|
+
read?: {
|
|
34
|
+
watermark?: number;
|
|
35
|
+
};
|
|
36
|
+
}>;
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
export interface MessengerChannelOptions {
|
|
40
|
+
appSecret: string;
|
|
41
|
+
verifyToken: string;
|
|
42
|
+
agent: string;
|
|
43
|
+
tenantId?: string | ((pageId: string) => string | undefined);
|
|
44
|
+
}
|
|
45
|
+
export interface MessengerChannel extends Channel {
|
|
46
|
+
conversationKey(ref: MessengerConversationRef): string;
|
|
47
|
+
parseConversationKey(id: string): MessengerConversationRef;
|
|
48
|
+
}
|
|
49
|
+
export declare function messengerConversationKey(ref: MessengerConversationRef): string;
|
|
50
|
+
export declare function parseMessengerConversationKey(id: string): MessengerConversationRef;
|
|
51
|
+
export declare function createMessengerChannel(options: MessengerChannelOptions): MessengerChannel;
|
|
52
|
+
export declare function replyInMessenger(ref: MessengerConversationRef, options: {
|
|
53
|
+
pageAccessToken: string;
|
|
54
|
+
apiVersion?: string;
|
|
55
|
+
fetchImpl?: typeof fetch;
|
|
56
|
+
}): ToolDef<{
|
|
57
|
+
text: string;
|
|
58
|
+
}, unknown>;
|
|
59
|
+
//# sourceMappingURL=messenger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messenger.d.ts","sourceRoot":"","sources":["../src/messenger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAkB,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAGpF,MAAM,WAAW,wBAAwB;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC5E,MAAM,WAAW,uBAAuB;IAAG,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,KAAK,CAAC;YAAE,MAAM,CAAC,EAAE;gBAAE,EAAE,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,SAAS,CAAC,EAAE;gBAAE,EAAE,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE;gBAAE,GAAG,CAAC,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,OAAO,CAAC,EAAE,OAAO,CAAA;aAAE,CAAC;YAAC,QAAQ,CAAC,EAAE;gBAAE,GAAG,CAAC,EAAE,MAAM,CAAC;gBAAC,OAAO,CAAC,EAAE,MAAM,CAAC;gBAAC,KAAK,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,QAAQ,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;gBAAC,SAAS,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,IAAI,CAAC,EAAE;gBAAE,SAAS,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAA;CAAE;AAC7Z,MAAM,WAAW,uBAAuB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAA;CAAE;AAChK,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAAG,eAAe,CAAC,GAAG,EAAE,wBAAwB,GAAG,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,wBAAwB,CAAA;CAAE;AAExK,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,wBAAwB,GAAG,MAAM,CAAuE;AACtJ,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,MAAM,GAAG,wBAAwB,CAGlF;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAsBzF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,wBAAwB,EAAE,OAAO,EAAE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,CAMvL"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { conversationKey, defineChannel, parseConversationKey, readJsonBody } from '@fabric-harness/sdk/channel';
|
|
2
|
+
import { jsonWriteTool, verifyHexHmac } from './webhook-shared.js';
|
|
3
|
+
export function messengerConversationKey(ref) { return conversationKey('messenger', 'v1', ref.pageId, ref.userId); }
|
|
4
|
+
export function parseMessengerConversationKey(id) {
|
|
5
|
+
const parsed = parseConversationKey(id);
|
|
6
|
+
if (parsed.provider !== 'messenger' || parsed.version !== 'v1' || parsed.segments.length !== 2)
|
|
7
|
+
throw new Error(`Invalid Messenger conversation key: "${id}".`);
|
|
8
|
+
const [pageId, userId] = parsed.segments;
|
|
9
|
+
return { pageId, userId };
|
|
10
|
+
}
|
|
11
|
+
export function createMessengerChannel(options) {
|
|
12
|
+
async function verify(request) {
|
|
13
|
+
const url = new URL(request.url);
|
|
14
|
+
if (url.searchParams.get('hub.mode') !== 'subscribe' || url.searchParams.get('hub.verify_token') !== options.verifyToken)
|
|
15
|
+
return new Response(null, { status: 403 });
|
|
16
|
+
return new Response(url.searchParams.get('hub.challenge') ?? '', { status: 200 });
|
|
17
|
+
}
|
|
18
|
+
async function webhook(request, context) {
|
|
19
|
+
const body = await readJsonBody(request);
|
|
20
|
+
if (!body)
|
|
21
|
+
return new Response(null, { status: 413 });
|
|
22
|
+
if (!(await verifyHexHmac(options.appSecret, body.raw, request.headers.get('x-hub-signature-256'), 'sha256=')))
|
|
23
|
+
return new Response(null, { status: 401 });
|
|
24
|
+
const payload = body.json;
|
|
25
|
+
for (const entry of payload.entry ?? [])
|
|
26
|
+
for (const event of entry.messaging ?? []) {
|
|
27
|
+
if (event.message?.is_echo)
|
|
28
|
+
continue;
|
|
29
|
+
const pageId = entry.id ?? event.recipient?.id;
|
|
30
|
+
const userId = event.sender?.id;
|
|
31
|
+
const text = event.message?.text ?? event.postback?.payload;
|
|
32
|
+
const dedupe = event.message?.mid ?? event.postback?.mid;
|
|
33
|
+
const tenantId = pageId ? (typeof options.tenantId === 'function' ? options.tenantId(pageId) : options.tenantId) ?? pageId : undefined;
|
|
34
|
+
if (!pageId || !userId || !text || !dedupe || !tenantId)
|
|
35
|
+
continue;
|
|
36
|
+
await context.dispatch(options.agent, { instanceId: messengerConversationKey({ pageId, userId }), dedupeKey: dedupe, tenantId, actor: { onBehalfOf: userId }, input: { type: event.postback ? 'messenger.postback' : 'messenger.message', text, messageId: dedupe, timestamp: event.timestamp } });
|
|
37
|
+
}
|
|
38
|
+
return new Response(null, { status: 200 });
|
|
39
|
+
}
|
|
40
|
+
return defineChannel({ name: 'messenger', routes: [{ method: 'GET', path: '/webhook', handler: verify }, { method: 'POST', path: '/webhook', handler: webhook }], conversationKey: (ref) => messengerConversationKey(ref), parseConversationKey: parseMessengerConversationKey });
|
|
41
|
+
}
|
|
42
|
+
export function replyInMessenger(ref, options) {
|
|
43
|
+
return jsonWriteTool({
|
|
44
|
+
name: 'reply_in_messenger', description: 'Reply to the Messenger user this agent is handling.', provider: 'messenger', fetchImpl: options.fetchImpl,
|
|
45
|
+
url: `https://graph.facebook.com/${options.apiVersion ?? 'v23.0'}/${encodeURIComponent(ref.pageId)}/messages`, headers: { authorization: `Bearer ${options.pageAccessToken}` },
|
|
46
|
+
inputSchema: { properties: { text: { type: 'string', minLength: 1 } }, required: ['text'] }, body: ({ text }) => ({ recipient: { id: ref.userId }, messaging_type: 'RESPONSE', message: { text } }),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=messenger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messenger.js","sourceRoot":"","sources":["../src/messenger.ts"],"names":[],"mappings":"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"}
|
package/dist/notion.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Channel, ToolDef } from '@fabric-harness/sdk/channel';
|
|
2
|
+
import { type SimpleConversationRef } from './webhook-shared.js';
|
|
3
|
+
export interface NotionConversationRef extends SimpleConversationRef {
|
|
4
|
+
}
|
|
5
|
+
export interface NotionWebhookPayload {
|
|
6
|
+
id?: string;
|
|
7
|
+
type?: string;
|
|
8
|
+
timestamp?: string;
|
|
9
|
+
workspace_id?: string;
|
|
10
|
+
workspace_name?: string;
|
|
11
|
+
subscription_id?: string;
|
|
12
|
+
integration_id?: string;
|
|
13
|
+
authors?: Array<{
|
|
14
|
+
id?: string;
|
|
15
|
+
type?: string;
|
|
16
|
+
}>;
|
|
17
|
+
entity?: {
|
|
18
|
+
id?: string;
|
|
19
|
+
type?: string;
|
|
20
|
+
};
|
|
21
|
+
data?: Record<string, unknown>;
|
|
22
|
+
verification_token?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface NotionChannelOptions {
|
|
25
|
+
verificationToken: string;
|
|
26
|
+
agent: string;
|
|
27
|
+
tenantId?: string | ((payload: NotionWebhookPayload) => string | undefined);
|
|
28
|
+
/** Persist or display the one-time token sent while creating a subscription. */
|
|
29
|
+
onVerificationToken?: (token: string) => void | Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export interface NotionChannel extends Channel {
|
|
32
|
+
conversationKey(ref: NotionConversationRef): string;
|
|
33
|
+
parseConversationKey(id: string): NotionConversationRef;
|
|
34
|
+
}
|
|
35
|
+
export declare const notionConversationKey: (ref: NotionConversationRef) => string;
|
|
36
|
+
export declare const parseNotionConversationKey: (id: string) => SimpleConversationRef;
|
|
37
|
+
export declare function createNotionChannel(options: NotionChannelOptions): NotionChannel;
|
|
38
|
+
export declare function commentOnNotionPage(ref: NotionConversationRef, options: {
|
|
39
|
+
token: string;
|
|
40
|
+
parentId: string;
|
|
41
|
+
notionVersion?: string;
|
|
42
|
+
fetchImpl?: typeof fetch;
|
|
43
|
+
}): ToolDef<{
|
|
44
|
+
text: string;
|
|
45
|
+
}, unknown>;
|
|
46
|
+
//# sourceMappingURL=notion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notion.d.ts","sourceRoot":"","sources":["../src/notion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAA6G,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5K,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;CAAG;AACvE,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AACD,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5E,gFAAgF;IAChF,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AACD,MAAM,WAAW,aAAc,SAAQ,OAAO;IAAG,eAAe,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,CAAA;CAAE;AAE/J,eAAO,MAAM,qBAAqB,GAAI,KAAK,qBAAqB,WAAyC,CAAC;AAC1G,eAAO,MAAM,0BAA0B,GAAI,IAAI,MAAM,0BAA6C,CAAC;AAEnG,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAiBhF;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,CAOlM"}
|
package/dist/notion.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createJsonWebhookChannel, jsonWriteTool, parseSimpleConversationKey, simpleConversationKey, verifyHexHmac } from './webhook-shared.js';
|
|
2
|
+
export const notionConversationKey = (ref) => simpleConversationKey('notion', ref);
|
|
3
|
+
export const parseNotionConversationKey = (id) => parseSimpleConversationKey('notion', id);
|
|
4
|
+
export function createNotionChannel(options) {
|
|
5
|
+
return createJsonWebhookChannel({
|
|
6
|
+
name: 'notion', agent: options.agent,
|
|
7
|
+
authenticate: (request, raw, payload) => Boolean(payload.verification_token) || verifyHexHmac(options.verificationToken, raw, request.headers.get('x-notion-signature'), 'sha256='),
|
|
8
|
+
handshake: async (payload) => {
|
|
9
|
+
if (!payload.verification_token)
|
|
10
|
+
return undefined;
|
|
11
|
+
await options.onVerificationToken?.(payload.verification_token);
|
|
12
|
+
return Response.json({ ok: true });
|
|
13
|
+
},
|
|
14
|
+
normalize: (payload) => {
|
|
15
|
+
const entityId = payload.entity?.id;
|
|
16
|
+
const tenantId = typeof options.tenantId === 'function' ? options.tenantId(payload) : options.tenantId ?? payload.workspace_id;
|
|
17
|
+
const actor = payload.authors?.find((author) => author.type !== 'integration')?.id;
|
|
18
|
+
if (!payload.id || !entityId || !tenantId || !actor)
|
|
19
|
+
return undefined;
|
|
20
|
+
return { ref: { tenantId, conversationId: entityId }, dedupeKey: payload.id, actorId: actor, input: { type: `notion.${payload.type ?? 'event'}`, entity: payload.entity, data: payload.data, timestamp: payload.timestamp } };
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function commentOnNotionPage(ref, options) {
|
|
25
|
+
return jsonWriteTool({
|
|
26
|
+
name: 'comment_on_notion_page', description: 'Add a comment to the Notion page this agent is handling.', provider: 'notion', fetchImpl: options.fetchImpl,
|
|
27
|
+
url: 'https://api.notion.com/v1/comments', headers: { authorization: `Bearer ${options.token}`, 'notion-version': options.notionVersion ?? '2022-06-28' },
|
|
28
|
+
inputSchema: { properties: { text: { type: 'string', minLength: 1 } }, required: ['text'] },
|
|
29
|
+
body: ({ text }) => ({ parent: { page_id: options.parentId }, rich_text: [{ type: 'text', text: { content: text } }] }),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=notion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notion.js","sourceRoot":"","sources":["../src/notion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,aAAa,EAA8B,MAAM,qBAAqB,CAAC;AAyB5K,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAA0B,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AAC1G,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,0BAA0B,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAEnG,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,OAAO,wBAAwB,CAAuB;QACpD,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK;QACpC,YAAY,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC;QACnL,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC3B,IAAI,CAAC,OAAO,CAAC,kBAAkB;gBAAE,OAAO,SAAS,CAAC;YAClD,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YAChE,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,OAAO,OAAO,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;YAC/H,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,EAAE,EAAE,CAAC;YACnF,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK;gBAAE,OAAO,SAAS,CAAC;YACtE,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QAChO,CAAC;KACF,CAAkB,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAA0B,EAAE,OAA8F;IAC5J,OAAO,aAAa,CAAC;QACnB,IAAI,EAAE,wBAAwB,EAAE,WAAW,EAAE,0DAA0D,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS;QACzJ,GAAG,EAAE,oCAAoC,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE,EAAE,gBAAgB,EAAE,OAAO,CAAC,aAAa,IAAI,YAAY,EAAE;QACzJ,WAAW,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;QAC3F,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;KACxH,CAAC,CAAC;AACL,CAAC"}
|
package/dist/resend.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Channel, ToolDef } from '@fabric-harness/sdk/channel';
|
|
2
|
+
import { type SimpleConversationRef } from './webhook-shared.js';
|
|
3
|
+
export interface ResendConversationRef extends SimpleConversationRef {
|
|
4
|
+
}
|
|
5
|
+
export interface ResendWebhookPayload {
|
|
6
|
+
type?: string;
|
|
7
|
+
created_at?: string;
|
|
8
|
+
data?: {
|
|
9
|
+
email_id?: string;
|
|
10
|
+
broadcast_id?: string;
|
|
11
|
+
from?: string;
|
|
12
|
+
to?: string[];
|
|
13
|
+
subject?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface ResendChannelOptions {
|
|
18
|
+
signingSecret: string;
|
|
19
|
+
agent: string;
|
|
20
|
+
tenantId: string | ((payload: ResendWebhookPayload) => string | undefined);
|
|
21
|
+
toleranceSeconds?: number;
|
|
22
|
+
now?: () => number;
|
|
23
|
+
}
|
|
24
|
+
export interface ResendChannel extends Channel {
|
|
25
|
+
conversationKey(ref: ResendConversationRef): string;
|
|
26
|
+
parseConversationKey(id: string): ResendConversationRef;
|
|
27
|
+
}
|
|
28
|
+
export declare const resendConversationKey: (ref: ResendConversationRef) => string;
|
|
29
|
+
export declare const parseResendConversationKey: (id: string) => SimpleConversationRef;
|
|
30
|
+
export declare function verifyResendSignature(secret: string, raw: Uint8Array, headers: Headers, options?: {
|
|
31
|
+
toleranceSeconds?: number;
|
|
32
|
+
now?: () => number;
|
|
33
|
+
}): Promise<boolean>;
|
|
34
|
+
export declare function createResendChannel(options: ResendChannelOptions): ResendChannel;
|
|
35
|
+
export declare function sendWithResend(ref: ResendConversationRef, options: {
|
|
36
|
+
apiKey: string;
|
|
37
|
+
from: string;
|
|
38
|
+
to: string;
|
|
39
|
+
fetchImpl?: typeof fetch;
|
|
40
|
+
}): ToolDef<{
|
|
41
|
+
subject: string;
|
|
42
|
+
text: string;
|
|
43
|
+
}, unknown>;
|
|
44
|
+
//# sourceMappingURL=resend.d.ts.map
|