@cpilot-wange/clawdbot-webhook-server 1.0.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.
@@ -0,0 +1,97 @@
1
+ {
2
+ "id": "webhook-server",
3
+ "name": "Webhook Server",
4
+ "version": "1.0.2",
5
+ "description": "Exposes a webhook HTTP server for receiving external messages and triggering agent tasks",
6
+ "author": "",
7
+ "license": "MIT",
8
+ "main": "dist/index.js",
9
+ "configSchema": {
10
+ "type": "object",
11
+ "properties": {
12
+ "port": {
13
+ "type": "number",
14
+ "default": 8765,
15
+ "description": "Port number for the webhook server"
16
+ },
17
+ "host": {
18
+ "type": "string",
19
+ "default": "0.0.0.0",
20
+ "description": "Host address to bind to"
21
+ },
22
+ "authToken": {
23
+ "type": "string",
24
+ "description": "Authentication token for incoming requests (Bearer token). Auto-generated if not provided."
25
+ },
26
+ "timeout": {
27
+ "type": "number",
28
+ "default": 300000,
29
+ "description": "Maximum time (ms) to wait for agent task completion"
30
+ },
31
+ "agentId": {
32
+ "type": "string",
33
+ "default": "default",
34
+ "description": "Agent ID to use for processing messages (e.g., 'default', 'main')"
35
+ },
36
+ "useNgrok": {
37
+ "type": "boolean",
38
+ "default": false,
39
+ "description": "Enable ngrok tunnel on startup"
40
+ },
41
+ "ngrokAuthToken": {
42
+ "type": "string",
43
+ "description": "Ngrok authtoken"
44
+ },
45
+ "ngrokPort": {
46
+ "type": "number",
47
+ "default": 18789,
48
+ "description": "Port to tunnel (default: 18789)"
49
+ },
50
+ "ngrokRegion": {
51
+ "type": "string",
52
+ "description": "Ngrok region (us, eu, au, ap, sa, jp, in)"
53
+ }
54
+ },
55
+ "required": []
56
+ },
57
+ "configDefaults": {
58
+ "port": 8765,
59
+ "host": "0.0.0.0",
60
+ "authToken": "$auto:uuid",
61
+ "timeout": 300000,
62
+ "agentId": "default",
63
+ "useNgrok": false,
64
+ "ngrokPort": 18789
65
+ },
66
+ "uiHints": {
67
+ "authToken": {
68
+ "label": "Auth Token",
69
+ "sensitive": true,
70
+ "placeholder": "Auto-generated secure token"
71
+ },
72
+ "port": {
73
+ "label": "Server Port",
74
+ "placeholder": "8765"
75
+ },
76
+ "host": {
77
+ "label": "Bind Host",
78
+ "placeholder": "0.0.0.0"
79
+ },
80
+ "timeout": {
81
+ "label": "Task Timeout (ms)",
82
+ "placeholder": "300000"
83
+ },
84
+ "useNgrok": {
85
+ "label": "Enable Ngrok"
86
+ },
87
+ "ngrokAuthToken": {
88
+ "label": "Ngrok AuthToken",
89
+ "sensitive": true,
90
+ "placeholder": "Your ngrok authtoken"
91
+ },
92
+ "ngrokPort": {
93
+ "label": "Ngrok Tunnel Port",
94
+ "placeholder": "18789"
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,9 @@
1
+ import type { ClawdbotPluginApi } from 'clawdbot/plugin-sdk';
2
+ declare const _default: {
3
+ id: string;
4
+ name: string;
5
+ description: string;
6
+ configSchema: any;
7
+ register(api: ClawdbotPluginApi): void;
8
+ };
9
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const plugin_sdk_1 = require("clawdbot/plugin-sdk");
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const runtime_js_1 = require("./runtime.js");
9
+ const zod_1 = require("zod");
10
+ const ngrok_1 = __importDefault(require("ngrok"));
11
+ // --- Webhook Handler ---
12
+ async function readJsonBody(req) {
13
+ const chunks = [];
14
+ return new Promise((resolve, reject) => {
15
+ req.on('data', (chunk) => chunks.push(chunk));
16
+ req.on('end', () => {
17
+ try {
18
+ const raw = Buffer.concat(chunks).toString('utf8');
19
+ resolve(raw ? JSON.parse(raw) : {});
20
+ }
21
+ catch (e) {
22
+ reject(e);
23
+ }
24
+ });
25
+ req.on('error', reject);
26
+ });
27
+ }
28
+ // Global map to store callback URLs for sessions if needed,
29
+ // though we prefer to pass it through the pipeline via context or assume configuration.
30
+ // For this refactor, we'll try to extract it from the context during delivery.
31
+ async function handleWebhookRequest(req, res) {
32
+ // Only handle POST /webhook (or configured path)
33
+ // The bridge might send to /, so we check method.
34
+ if (req.method !== 'POST')
35
+ return false;
36
+ // Simple path check - in a real plugin we might want configurable paths
37
+ if (req.url && !req.url.endsWith('/webhook') && req.url !== '/')
38
+ return false;
39
+ try {
40
+ const body = await readJsonBody(req);
41
+ // Basic Validation
42
+ if (!body.task) {
43
+ res.statusCode = 400;
44
+ res.end(JSON.stringify({ error: 'Missing task' }));
45
+ return true;
46
+ }
47
+ // We accept the request immediately
48
+ res.statusCode = 202;
49
+ res.end(JSON.stringify({ status: 'accepted' }));
50
+ // Process in background
51
+ processMessageWithPipeline(body).catch(err => {
52
+ console.error('Pipeline processing error:', err);
53
+ });
54
+ return true;
55
+ }
56
+ catch (err) {
57
+ console.error('Webhook handler error:', err);
58
+ res.statusCode = 500;
59
+ res.end('Internal Server Error');
60
+ return true;
61
+ }
62
+ }
63
+ // --- Pipeline ---
64
+ async function processMessageWithPipeline(payload) {
65
+ const core = (0, runtime_js_1.getRuntime)();
66
+ // Assuming single-tenant/default account for now as per original code
67
+ // In a full implementation, we'd resolve the account based on the request (e.g. auth token)
68
+ const accountId = plugin_sdk_1.DEFAULT_ACCOUNT_ID;
69
+ // We need access to the config.
70
+ // Since we don't have the full config object passed in, we might need to fetch it from runtime or similar.
71
+ // However, `dispatchReplyWithBufferedBlockDispatcher` takes `cfg`.
72
+ // In the Zalo example, `processUpdate` receives `config`.
73
+ // Here, we'll assume we can get the global config or pass a minimal one.
74
+ // For now, we'll try to read it from the core if possible or construct a placeholder.
75
+ // NOTE: In the original code, `pluginApi.config` was available.
76
+ // In the new SDK structure, we should be careful.
77
+ // `core.config` might not be directly exposed.
78
+ // BUT! `api.registerChannel` passes `cfg` to methods. `handleWebhookRequest` is outside that flow.
79
+ // We strictly need the config.
80
+ // WORKAROUND: We will store the latest config in a global variable when the plugin is loaded/reloaded.
81
+ const config = _globalConfig || {};
82
+ const senderId = payload.metadata?.openid || 'unknown_user';
83
+ const senderName = payload.metadata?.nickname || `User ${senderId.slice(0, 4)}`;
84
+ const text = payload.task;
85
+ const chatId = senderId; // For DM, chat ID is usually user ID
86
+ // Construct IDs
87
+ const fromLabel = `wechat:${senderId}`;
88
+ // Authorization / Pairing Logic
89
+ // Simplified: Check allowFrom list
90
+ // In a full implementation, follow Zalo's `isSenderAllowed` and `pairing` logic
91
+ // Ensure config is not null
92
+ const safeConfig = config || {};
93
+ const route = core.channel.routing?.resolveAgentRoute?.({
94
+ cfg: safeConfig,
95
+ channel: 'wechat',
96
+ accountId: accountId,
97
+ peer: { kind: 'dm', id: chatId }
98
+ }) || {
99
+ // Fallback if routing fails (e.g. config not updated)
100
+ agentId: safeConfig?.plugins?.entries?.['webhook-server']?.config?.agentId || 'default',
101
+ accountId: accountId,
102
+ sessionKey: `wechat:${senderId}`
103
+ };
104
+ if (!route) {
105
+ // Should not happen with fallback, but TS check
106
+ console.error('Failed to resolve agent route');
107
+ return;
108
+ }
109
+ const sessionKey = route.sessionKey || `wechat:${senderId}`;
110
+ // Construct Context
111
+ // We need to pass the callback_url through to the delivery phase.
112
+ // We can use the 'Ctx' fields or `Originating...` fields if they allow custom data,
113
+ // or rely on `InboundContext` having flexible fields.
114
+ const callbackUrl = payload.callback_url;
115
+ // Get Store Path (using config.session?.store if available)
116
+ // We try to access config.session from the global config
117
+ const storePath = core.channel.session?.resolveStorePath?.(safeConfig.session?.store, { agentId: route.agentId });
118
+ // Format Envelope
119
+ const envelopeOptions = core.channel.reply?.resolveEnvelopeFormatOptions?.(safeConfig);
120
+ const previousTimestamp = core.channel.session?.readSessionUpdatedAt?.({
121
+ storePath,
122
+ sessionKey
123
+ });
124
+ const timestamp = payload.metadata?.timestamp ? payload.metadata.timestamp * 1000 : Date.now();
125
+ const formattedBody = core.channel.reply?.formatAgentEnvelope?.({
126
+ channel: 'WeChat',
127
+ from: senderName, // User friendly name
128
+ timestamp,
129
+ previousTimestamp,
130
+ envelope: envelopeOptions,
131
+ body: text
132
+ }) || text; // Fallback to raw text if formatter missing
133
+ const ctxPayload = core.channel.reply?.finalizeInboundContext?.({
134
+ Body: formattedBody,
135
+ RawBody: text,
136
+ From: `wechat:${senderId}`,
137
+ To: `wechat:bot`,
138
+ SessionKey: sessionKey,
139
+ AccountId: accountId,
140
+ AgentId: route.agentId || accountId, // Fix: Explicitly pass AgentId
141
+ ChatType: 'direct',
142
+ ConversationLabel: senderName,
143
+ SenderName: senderName,
144
+ SenderId: senderId,
145
+ Provider: 'wechat',
146
+ Surface: 'wechat',
147
+ // Pass callback_url here so we can retrieve it in deliver
148
+ _CallbackUrl: callbackUrl,
149
+ });
150
+ if (!ctxPayload)
151
+ return;
152
+ // Record Session
153
+ await core.channel.session?.recordInboundSession?.({
154
+ storePath,
155
+ sessionKey,
156
+ ctx: ctxPayload
157
+ });
158
+ // Dispatch
159
+ await core.channel.reply?.dispatchReplyWithBufferedBlockDispatcher?.({
160
+ ctx: ctxPayload,
161
+ cfg: config,
162
+ dispatcherOptions: {
163
+ deliver: async (deliverPayload) => {
164
+ await deliverWeChatReply({
165
+ text: deliverPayload.text,
166
+ callbackUrl: callbackUrl || (_globalConfig?.channels?.wechat?.config?.callbackUrl),
167
+ originalPayload: payload
168
+ });
169
+ },
170
+ onError: (err, info) => {
171
+ console.error(`WeChat dispatch error (${info.kind}):`, err);
172
+ }
173
+ }
174
+ });
175
+ }
176
+ // --- Delivery ---
177
+ async function deliverWeChatReply(params) {
178
+ const { text, callbackUrl } = params;
179
+ if (!text || !callbackUrl)
180
+ return;
181
+ try {
182
+ await axios_1.default.post(callbackUrl, {
183
+ success: true,
184
+ result: text,
185
+ // Add metadata if needed by Bridge
186
+ metadata: {
187
+ // model: ... (Not easily available in this callback without extra context)
188
+ }
189
+ });
190
+ }
191
+ catch (error) {
192
+ console.error(`Failed to deliver reply to ${callbackUrl}:`, error);
193
+ }
194
+ }
195
+ // --- Plugin Definition ---
196
+ let _globalConfig = null;
197
+ const wechatPlugin = {
198
+ id: 'wechat',
199
+ meta: {
200
+ id: 'wechat',
201
+ label: 'WeChat',
202
+ selectionLabel: 'WeChat (Bridge)',
203
+ description: 'WeChat integration via Bridge Webhook',
204
+ docsPath: '',
205
+ },
206
+ configSchema: (0, plugin_sdk_1.buildChannelConfigSchema)(zod_1.z.object({
207
+ callbackUrl: zod_1.z.string().optional().describe('URL to send replies to (e.g. Bridge URL)'),
208
+ }).extend({
209
+ accounts: zod_1.z.object({}).catchall(zod_1.z.object({
210
+ callbackUrl: zod_1.z.string().optional(),
211
+ })).optional(),
212
+ defaultAccount: zod_1.z.string().optional()
213
+ })),
214
+ capabilities: {
215
+ chatTypes: ['direct'], // Webhook acts like DM usually
216
+ media: false, // Set to true if supported
217
+ blockStreaming: true, // We prefer full blocks for webhook callbacks mostly
218
+ },
219
+ // Implement other required methods (minimal implementation)
220
+ // ...
221
+ config: {
222
+ // Minimal config helpers
223
+ listAccountIds: () => [plugin_sdk_1.DEFAULT_ACCOUNT_ID],
224
+ resolveAccount: (cfg) => ({
225
+ accountId: plugin_sdk_1.DEFAULT_ACCOUNT_ID,
226
+ name: 'Default',
227
+ enabled: true,
228
+ config: cfg?.plugins?.entries?.['webhook-server']?.config || {} // Fallback to old config location or new one?
229
+ // Ideally we move config to `channels.wechat`
230
+ }),
231
+ defaultAccountId: () => plugin_sdk_1.DEFAULT_ACCOUNT_ID,
232
+ isConfigured: () => true, // Always considered configured for now
233
+ describeAccount: () => ({ accountId: plugin_sdk_1.DEFAULT_ACCOUNT_ID, name: 'Default', enabled: true, configured: true }),
234
+ },
235
+ // We wrap 'reload' to capture config
236
+ reload: {
237
+ configPrefixes: ['channels.wechat', 'plugins.entries.webhook-server']
238
+ }
239
+ };
240
+ const wechatDock = {
241
+ id: 'wechat',
242
+ capabilities: {
243
+ chatTypes: ['direct'],
244
+ media: false,
245
+ blockStreaming: true
246
+ },
247
+ config: {
248
+ // Helpers for UI
249
+ resolveAllowFrom: () => [],
250
+ formatAllowFrom: () => []
251
+ }
252
+ };
253
+ // Main Export
254
+ exports.default = {
255
+ id: 'wechat',
256
+ name: 'WeChat',
257
+ description: 'WeChat Channel Plugin',
258
+ configSchema: (0, plugin_sdk_1.emptyPluginConfigSchema)(),
259
+ register(api) {
260
+ (0, runtime_js_1.setRuntime)(api.runtime);
261
+ _globalConfig = api.config;
262
+ const webhookConfig = api.config.plugins?.entries?.['webhook-server']?.config || {};
263
+ if (webhookConfig.useNgrok) {
264
+ const port = webhookConfig.ngrokPort || 18789;
265
+ const authtoken = process.env.NGROK_AUTHTOKEN || webhookConfig.ngrokAuthToken;
266
+ const region = webhookConfig.ngrokRegion;
267
+ (async () => {
268
+ try {
269
+ api.logger.info(`Starting ngrok tunnel on port ${port}...`);
270
+ const url = await ngrok_1.default.connect({
271
+ addr: port,
272
+ authtoken,
273
+ region
274
+ });
275
+ api.logger.info(`Ngrok tunnel established: ${url}`);
276
+ }
277
+ catch (err) {
278
+ api.logger.error(`Failed to start ngrok: ${err instanceof Error ? err.message : String(err)}`);
279
+ }
280
+ })();
281
+ }
282
+ // Register as a channel
283
+ api.registerChannel({
284
+ plugin: wechatPlugin,
285
+ dock: wechatDock
286
+ });
287
+ // Register the HTTP handler for webhooks
288
+ // Note: The 'webhook-server' service is no longer needed in this pattern
289
+ // as registerHttpHandler hooks into the main server.
290
+ api.registerHttpHandler(handleWebhookRequest);
291
+ // Keep a listener for config changes if API supports it,
292
+ // or just rely on the fact that `api.config` is a reference
293
+ // (though usually it's a snapshot at register time).
294
+ // Ideally we implement the `reload` capability in the plugin definition.
295
+ api.logger.info('WeChat Webhook Channel registered');
296
+ }
297
+ };
298
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { PluginRuntime } from "clawdbot/plugin-sdk";
2
+ export declare function setRuntime(next: PluginRuntime): void;
3
+ export declare function getRuntime(): PluginRuntime;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setRuntime = setRuntime;
4
+ exports.getRuntime = getRuntime;
5
+ let runtime = null;
6
+ function setRuntime(next) {
7
+ runtime = next;
8
+ }
9
+ function getRuntime() {
10
+ if (!runtime) {
11
+ throw new Error("WeChat runtime not initialized");
12
+ }
13
+ return runtime;
14
+ }
15
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":";;AAIA,gCAEC;AAED,gCAKC;AAXD,IAAI,OAAO,GAAyB,IAAI,CAAC;AAEzC,SAAgB,UAAU,CAAC,IAAmB;IAC1C,OAAO,GAAG,IAAI,CAAC;AACnB,CAAC;AAED,SAAgB,UAAU;IACtB,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@cpilot-wange/clawdbot-webhook-server",
3
+ "version": "1.0.0",
4
+ "description": "CPilot webhook server plugin for WeChat Official Account integration",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "clawdbot.plugin.json"
14
+ ],
15
+ "keywords": [
16
+ "cpilot",
17
+ "clawdbot",
18
+ "plugin",
19
+ "webhook",
20
+ "wechat"
21
+ ],
22
+ "license": "MIT",
23
+ "clawdbot": {
24
+ "extensions": [
25
+ "dist/index.js"
26
+ ]
27
+ },
28
+ "dependencies": {
29
+ "axios": "^1.6.7",
30
+ "fastify": "^4.26.1",
31
+ "ngrok": "^5.0.0-beta.2"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^20.11.19",
35
+ "typescript": "^5.3.3"
36
+ },
37
+ "peerDependencies": {
38
+ "clawdbot": ">=1.0.0"
39
+ }
40
+ }