@crewhaus/channel-adapter-slack 0.4.0 → 0.4.2
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/index.d.ts +46 -1
- package/dist/index.js +4 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -88,14 +88,59 @@ export type ParsedInbound = {
|
|
|
88
88
|
} | {
|
|
89
89
|
readonly kind: "skip";
|
|
90
90
|
};
|
|
91
|
+
/**
|
|
92
|
+
* An UNSIGNED, GET-based subscription handshake — the shape Meta (WhatsApp)
|
|
93
|
+
* uses to verify a callback URL before it will deliver any webhook. There is
|
|
94
|
+
* no body and no HMAC header to check, so the gateway cannot route it through
|
|
95
|
+
* `verify()`/`parseInbound()`; instead the platform proves itself with a
|
|
96
|
+
* shared verify token carried in the query string.
|
|
97
|
+
*
|
|
98
|
+
* The gateway hands the parsed request URL (query string included) plus the
|
|
99
|
+
* headers; the adapter decides. Slack and Discord verify inside a signed POST
|
|
100
|
+
* body (`{kind:"challenge"}` from `parseInbound`) and leave `handshake`
|
|
101
|
+
* undefined — for them the gateway's behaviour is unchanged.
|
|
102
|
+
*/
|
|
103
|
+
export type HandshakeRequest = {
|
|
104
|
+
readonly headers: Headers;
|
|
105
|
+
readonly url: URL;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* `{kind:"challenge"}` ⇒ the gateway echoes `challenge` back with 200; any
|
|
109
|
+
* other outcome ⇒ 403. An adapter that cannot authenticate the caller (bad
|
|
110
|
+
* token, missing params, or no verify token configured on this daemon) MUST
|
|
111
|
+
* return `{kind:"reject"}` — echoing an unauthenticated challenge would let
|
|
112
|
+
* anyone bind their own Meta app to this daemon's callback URL.
|
|
113
|
+
*/
|
|
114
|
+
export type HandshakeResult = {
|
|
115
|
+
readonly kind: "challenge";
|
|
116
|
+
readonly challenge: string;
|
|
117
|
+
} | {
|
|
118
|
+
readonly kind: "reject";
|
|
119
|
+
};
|
|
91
120
|
export interface ChannelAdapter {
|
|
92
121
|
readonly id: string;
|
|
93
122
|
verify(req: RawRequest): boolean;
|
|
94
123
|
parseInbound(req: RawRequest): ParsedInbound;
|
|
124
|
+
/**
|
|
125
|
+
* Answer an unsigned GET subscription handshake (Meta's `hub.challenge`
|
|
126
|
+
* flow). Optional — adapters whose platform has no such handshake leave it
|
|
127
|
+
* undefined and the gateway falls through to the normal signed path.
|
|
128
|
+
*/
|
|
129
|
+
handshake?(req: HandshakeRequest): HandshakeResult;
|
|
130
|
+
/**
|
|
131
|
+
* D40 — post the reply; when the channel API returns a post receipt, the
|
|
132
|
+
* adapter surfaces the posted message's ts as `{ messageTs }` so the
|
|
133
|
+
* generated session-router can append its outbound-ts reaction join
|
|
134
|
+
* (exact-turn 👍/👎 attribution). Resolving void stays legal — an adapter
|
|
135
|
+
* without a receipt simply produces no join line, and reactions on its
|
|
136
|
+
* replies take the router's per-key fallback.
|
|
137
|
+
*/
|
|
95
138
|
sendReply(args: {
|
|
96
139
|
event: InboundEvent;
|
|
97
140
|
text: string;
|
|
98
|
-
}): Promise<
|
|
141
|
+
}): Promise<{
|
|
142
|
+
messageTs?: string;
|
|
143
|
+
} | void>;
|
|
99
144
|
setTyping(args: {
|
|
100
145
|
event: InboundEvent;
|
|
101
146
|
}): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -171,6 +171,10 @@ export function createSlackAdapter(config, opts = {}) {
|
|
|
171
171
|
if (body.ok === false) {
|
|
172
172
|
throw new SlackAdapterError(`chat.postMessage error: ${body.error ?? "unknown"}`);
|
|
173
173
|
}
|
|
174
|
+
// D40 — surface the posted message's ts (mirroring postApproval's
|
|
175
|
+
// receipt) so the session-router can record the outbound-ts → turn
|
|
176
|
+
// join for exact-turn reaction attribution.
|
|
177
|
+
return typeof body.ts === "string" ? { messageTs: body.ts } : undefined;
|
|
174
178
|
}
|
|
175
179
|
},
|
|
176
180
|
async setTyping(_args) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewhaus/channel-adapter-slack",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Slack channel adapter: webhook signature verification, event parsing, reply-to-thread (Section 12)",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"test": "bun test src"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@crewhaus/errors": "0.4.
|
|
18
|
+
"@crewhaus/errors": "0.4.2"
|
|
19
19
|
},
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"author": {
|