openclaw-quiubo 0.4.0 → 0.5.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/index.d.ts +12 -57
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -89
- package/dist/index.js.map +1 -1
- package/dist/src/channel.d.ts +4 -40
- package/dist/src/channel.d.ts.map +1 -1
- package/dist/src/channel.js +220 -44
- package/dist/src/channel.js.map +1 -1
- package/dist/src/runtime.d.ts +11 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +22 -0
- package/dist/src/runtime.js.map +1 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,70 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Quiubo OpenClaw Extension — Entry Point
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Fallback: Polling listMessages API (when Pusher disconnects)
|
|
7
|
-
*
|
|
8
|
-
* On startup, authenticates with the SDK API to get Pusher credentials,
|
|
9
|
-
* then connects as the bot identity for real-time message delivery.
|
|
4
|
+
* Object-based plugin registration (matching openclaw-mqtt pattern).
|
|
5
|
+
* Stores the PluginRuntime reference and registers the channel plugin.
|
|
10
6
|
*/
|
|
11
|
-
import type { QuiuboAccountConfig } from './src/types.js';
|
|
12
7
|
export { QuiuboApiClient } from './src/api.js';
|
|
13
|
-
export { quiuboPlugin
|
|
8
|
+
export { quiuboPlugin } from './src/channel.js';
|
|
14
9
|
export { RealtimeGateway } from './src/realtime-gateway.js';
|
|
15
10
|
export { PollingGateway } from './src/polling-gateway.js';
|
|
16
11
|
export type { QuiuboAccountConfig, QuiuboGroup, QuiuboMessage, QuiuboIdentity, QuiuboJoinToken, QuiuboAuthResponse, WebhookPayload, WebhookMessageData, WebhookJoinTokenRedeemedData, } from './src/types.js';
|
|
17
|
-
interface
|
|
12
|
+
interface OpenClawPluginApi {
|
|
13
|
+
runtime: unknown;
|
|
18
14
|
registerChannel: (opts: {
|
|
19
|
-
plugin:
|
|
15
|
+
plugin: any;
|
|
20
16
|
}) => void;
|
|
21
|
-
ingest: (message: Record<string, any>) => Promise<void>;
|
|
22
17
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Called when the gateway starts.
|
|
30
|
-
* Authenticates, gets Pusher config, connects real-time.
|
|
31
|
-
*/
|
|
32
|
-
start: (ctx: {
|
|
33
|
-
config: Record<string, any>;
|
|
34
|
-
accountId?: string;
|
|
35
|
-
}, api: OpenClawApi) => Promise<void>;
|
|
36
|
-
/**
|
|
37
|
-
* Called when the gateway stops.
|
|
38
|
-
*/
|
|
39
|
-
stop: () => Promise<void>;
|
|
40
|
-
};
|
|
41
|
-
id: "quiubo";
|
|
42
|
-
meta: {
|
|
43
|
-
id: string;
|
|
44
|
-
label: string;
|
|
45
|
-
selectionLabel: string;
|
|
46
|
-
blurb: string;
|
|
47
|
-
aliases: string[];
|
|
48
|
-
};
|
|
49
|
-
capabilities: {
|
|
50
|
-
chatTypes: readonly ["group"];
|
|
51
|
-
};
|
|
52
|
-
config: {
|
|
53
|
-
listAccountIds(cfg: Record<string, unknown>): string[];
|
|
54
|
-
resolveAccount(cfg: Record<string, unknown>, accountId?: string): QuiuboAccountConfig;
|
|
55
|
-
};
|
|
56
|
-
outbound: {
|
|
57
|
-
deliveryMode: "direct";
|
|
58
|
-
sendText({ text, target }: {
|
|
59
|
-
text: string;
|
|
60
|
-
target?: Record<string, any>;
|
|
61
|
-
}): Promise<{
|
|
62
|
-
ok: boolean;
|
|
63
|
-
}>;
|
|
64
|
-
};
|
|
18
|
+
declare const plugin: {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
register(api: OpenClawPluginApi): void;
|
|
65
23
|
};
|
|
66
|
-
|
|
67
|
-
* OpenClaw plugin entry point.
|
|
68
|
-
*/
|
|
69
|
-
export default function register(api: OpenClawApi): void;
|
|
24
|
+
export default plugin;
|
|
70
25
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EACV,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,gBAAgB,CAAC;AAGxB,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IAEjB,eAAe,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,CAAC;CAClD;AAED,QAAA,MAAM,MAAM;;;;kBAII,iBAAiB;CAIhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,101 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Quiubo OpenClaw Extension — Entry Point
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Fallback: Polling listMessages API (when Pusher disconnects)
|
|
7
|
-
*
|
|
8
|
-
* On startup, authenticates with the SDK API to get Pusher credentials,
|
|
9
|
-
* then connects as the bot identity for real-time message delivery.
|
|
4
|
+
* Object-based plugin registration (matching openclaw-mqtt pattern).
|
|
5
|
+
* Stores the PluginRuntime reference and registers the channel plugin.
|
|
10
6
|
*/
|
|
11
|
-
import {
|
|
7
|
+
import { setQuiuboRuntime } from './src/runtime.js';
|
|
12
8
|
import { quiuboPlugin } from './src/channel.js';
|
|
13
|
-
import { RealtimeGateway } from './src/realtime-gateway.js';
|
|
14
9
|
// Re-export for consumers
|
|
15
10
|
export { QuiuboApiClient } from './src/api.js';
|
|
16
|
-
export { quiuboPlugin
|
|
11
|
+
export { quiuboPlugin } from './src/channel.js';
|
|
17
12
|
export { RealtimeGateway } from './src/realtime-gateway.js';
|
|
18
13
|
export { PollingGateway } from './src/polling-gateway.js';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
gateway: {
|
|
27
|
-
/**
|
|
28
|
-
* Called when the gateway starts.
|
|
29
|
-
* Authenticates, gets Pusher config, connects real-time.
|
|
30
|
-
*/
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
-
start: async (ctx, api) => {
|
|
33
|
-
const { config, accountId } = ctx;
|
|
34
|
-
const accounts = config.channels?.quiubo?.accounts;
|
|
35
|
-
const account = accounts?.[accountId ?? 'default'];
|
|
36
|
-
if (!account) {
|
|
37
|
-
console.warn('[Quiubo] No account config found, skipping gateway');
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const { apiUrl, apiKey, botIdentityId, pollIntervalMs } = account;
|
|
41
|
-
if (!apiKey || !botIdentityId) {
|
|
42
|
-
console.error('[Quiubo] apiKey and botIdentityId are required in account config');
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const client = new QuiuboApiClient(apiUrl ?? 'https://api.quiubo.io', apiKey);
|
|
46
|
-
// Authenticate and get Pusher config
|
|
47
|
-
let pusherConfig;
|
|
48
|
-
try {
|
|
49
|
-
const auth = await client.authenticate();
|
|
50
|
-
pusherConfig = auth.pusher;
|
|
51
|
-
console.log(`[Quiubo] Authenticated as ${auth.appName} (${auth.appId})`);
|
|
52
|
-
if (pusherConfig) {
|
|
53
|
-
console.log(`[Quiubo] Pusher available (cluster: ${pusherConfig.cluster})`);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
console.log('[Quiubo] Pusher not configured on server — using polling');
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
console.error('[Quiubo] Authentication failed:', error);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
gateway = new RealtimeGateway({
|
|
64
|
-
client,
|
|
65
|
-
botIdentityId,
|
|
66
|
-
pusher: pusherConfig,
|
|
67
|
-
pollIntervalMs: pollIntervalMs ?? 5000,
|
|
68
|
-
onMessage: async (msg) => {
|
|
69
|
-
await api.ingest({
|
|
70
|
-
channel: 'quiubo',
|
|
71
|
-
accountId: accountId ?? 'default',
|
|
72
|
-
chatType: 'group',
|
|
73
|
-
groupId: msg.groupId,
|
|
74
|
-
senderId: msg.senderIdentityId,
|
|
75
|
-
senderName: msg.senderUsername ?? msg.senderIdentityId,
|
|
76
|
-
text: msg.plaintext,
|
|
77
|
-
messageId: msg.messageId,
|
|
78
|
-
timestamp: msg.createdAt ? new Date(msg.createdAt).getTime() : Date.now(),
|
|
79
|
-
});
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
await gateway.start();
|
|
83
|
-
},
|
|
84
|
-
/**
|
|
85
|
-
* Called when the gateway stops.
|
|
86
|
-
*/
|
|
87
|
-
stop: async () => {
|
|
88
|
-
if (gateway) {
|
|
89
|
-
gateway.stop();
|
|
90
|
-
gateway = null;
|
|
91
|
-
}
|
|
92
|
-
},
|
|
14
|
+
const plugin = {
|
|
15
|
+
id: 'openclaw-quiubo',
|
|
16
|
+
name: 'Quiubo',
|
|
17
|
+
description: 'Chat with AI assistants through Quiubo',
|
|
18
|
+
register(api) {
|
|
19
|
+
setQuiuboRuntime(api.runtime);
|
|
20
|
+
api.registerChannel({ plugin: quiuboPlugin });
|
|
93
21
|
},
|
|
94
22
|
};
|
|
95
|
-
|
|
96
|
-
* OpenClaw plugin entry point.
|
|
97
|
-
*/
|
|
98
|
-
export default function register(api) {
|
|
99
|
-
api.registerChannel({ plugin: pluginWithGateway });
|
|
100
|
-
}
|
|
23
|
+
export default plugin;
|
|
101
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAoB1D,MAAM,MAAM,GAAG;IACb,EAAE,EAAE,iBAAiB;IACrB,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,wCAAwC;IACrD,QAAQ,CAAC,GAAsB;QAC7B,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9B,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAChD,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/src/channel.d.ts
CHANGED
|
@@ -2,47 +2,11 @@
|
|
|
2
2
|
* Quiubo Channel Plugin
|
|
3
3
|
*
|
|
4
4
|
* Flat plugin object matching OpenClaw's ChannelPlugin interface.
|
|
5
|
+
* Gateway lifecycle uses startAccount(ctx) per account (not start/stop).
|
|
6
|
+
* Inbound routing uses runtime.channel.reply pipeline (same as openclaw-mqtt).
|
|
5
7
|
*
|
|
6
8
|
* Shape:
|
|
7
|
-
* id, meta, capabilities, config, outbound
|
|
9
|
+
* id, meta, capabilities, config, outbound, gateway
|
|
8
10
|
*/
|
|
9
|
-
|
|
10
|
-
import type { QuiuboAccountConfig } from './types.js';
|
|
11
|
-
/**
|
|
12
|
-
* The plugin object passed to api.registerChannel({ plugin }).
|
|
13
|
-
*
|
|
14
|
-
* OpenClaw discovers accounts via config.listAccountIds / resolveAccount,
|
|
15
|
-
* then calls outbound.sendText when the agent needs to respond.
|
|
16
|
-
*/
|
|
17
|
-
export declare const quiuboPlugin: {
|
|
18
|
-
id: "quiubo";
|
|
19
|
-
meta: {
|
|
20
|
-
id: string;
|
|
21
|
-
label: string;
|
|
22
|
-
selectionLabel: string;
|
|
23
|
-
blurb: string;
|
|
24
|
-
aliases: string[];
|
|
25
|
-
};
|
|
26
|
-
capabilities: {
|
|
27
|
-
chatTypes: readonly ["group"];
|
|
28
|
-
};
|
|
29
|
-
config: {
|
|
30
|
-
listAccountIds(cfg: Record<string, unknown>): string[];
|
|
31
|
-
resolveAccount(cfg: Record<string, unknown>, accountId?: string): QuiuboAccountConfig;
|
|
32
|
-
};
|
|
33
|
-
outbound: {
|
|
34
|
-
deliveryMode: "direct";
|
|
35
|
-
sendText({ text, target }: {
|
|
36
|
-
text: string;
|
|
37
|
-
target?: Record<string, any>;
|
|
38
|
-
}): Promise<{
|
|
39
|
-
ok: boolean;
|
|
40
|
-
}>;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* Get the current API client (for webhook handler and other plumbing).
|
|
45
|
-
* Returns null if no account has been resolved yet.
|
|
46
|
-
*/
|
|
47
|
-
export declare function getQuiuboClient(): QuiuboApiClient | null;
|
|
11
|
+
export declare const quiuboPlugin: any;
|
|
48
12
|
//# sourceMappingURL=channel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH,eAAO,MAAM,YAAY,EAAE,GA6M1B,CAAC"}
|
package/dist/src/channel.js
CHANGED
|
@@ -2,26 +2,22 @@
|
|
|
2
2
|
* Quiubo Channel Plugin
|
|
3
3
|
*
|
|
4
4
|
* Flat plugin object matching OpenClaw's ChannelPlugin interface.
|
|
5
|
+
* Gateway lifecycle uses startAccount(ctx) per account (not start/stop).
|
|
6
|
+
* Inbound routing uses runtime.channel.reply pipeline (same as openclaw-mqtt).
|
|
5
7
|
*
|
|
6
8
|
* Shape:
|
|
7
|
-
* id, meta, capabilities, config, outbound
|
|
9
|
+
* id, meta, capabilities, config, outbound, gateway
|
|
8
10
|
*/
|
|
9
11
|
import { QuiuboApiClient } from './api.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* The plugin object passed to api.registerChannel({ plugin }).
|
|
21
|
-
*
|
|
22
|
-
* OpenClaw discovers accounts via config.listAccountIds / resolveAccount,
|
|
23
|
-
* then calls outbound.sendText when the agent needs to respond.
|
|
24
|
-
*/
|
|
12
|
+
import { RealtimeGateway } from './realtime-gateway.js';
|
|
13
|
+
import { getQuiuboRuntime } from './runtime.js';
|
|
14
|
+
/** Per-account gateway instances, keyed by accountId */
|
|
15
|
+
const gateways = new Map();
|
|
16
|
+
/** Per-account API clients, keyed by accountId */
|
|
17
|
+
const clients = new Map();
|
|
18
|
+
/** Per-account configs, keyed by accountId */
|
|
19
|
+
const accounts = new Map();
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
21
|
export const quiuboPlugin = {
|
|
26
22
|
id: 'quiubo',
|
|
27
23
|
meta: {
|
|
@@ -31,46 +27,70 @@ export const quiuboPlugin = {
|
|
|
31
27
|
blurb: 'Send and receive messages through Quiubo.',
|
|
32
28
|
aliases: ['qb'],
|
|
33
29
|
},
|
|
34
|
-
capabilities: {
|
|
30
|
+
capabilities: {
|
|
31
|
+
chatTypes: ['group'],
|
|
32
|
+
supportsMedia: false,
|
|
33
|
+
supportsReactions: false,
|
|
34
|
+
supportsThreads: false,
|
|
35
|
+
},
|
|
35
36
|
// ── config adapter ──────────────────────────────────────────────
|
|
36
37
|
config: {
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
39
|
listAccountIds(cfg) {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return Object.keys(accounts
|
|
40
|
+
const quiubo = cfg.channels?.quiubo;
|
|
41
|
+
if (!quiubo?.accounts)
|
|
42
|
+
return [];
|
|
43
|
+
return Object.keys(quiubo.accounts);
|
|
42
44
|
},
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
46
|
resolveAccount(cfg, accountId) {
|
|
44
|
-
const channels = cfg.channels;
|
|
45
|
-
const quiubo = channels?.quiubo;
|
|
46
|
-
const accounts = quiubo?.accounts;
|
|
47
47
|
const id = accountId ?? 'default';
|
|
48
|
-
const account = accounts?.[id];
|
|
48
|
+
const account = cfg.channels?.quiubo?.accounts?.[id];
|
|
49
49
|
if (!account) {
|
|
50
50
|
return { accountId: id };
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
const resolved = { ...account, accountId: id };
|
|
53
|
+
// Cache client + config for outbound use
|
|
53
54
|
const apiUrl = account.apiUrl ?? 'https://api.quiubo.io';
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return
|
|
55
|
+
clients.set(id, new QuiuboApiClient(apiUrl, account.apiKey));
|
|
56
|
+
accounts.set(id, resolved);
|
|
57
|
+
return resolved;
|
|
57
58
|
},
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
+
isEnabled: (account) => Boolean(account.apiKey),
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
62
|
+
isConfigured: (account) => Boolean(account.apiKey && account.botIdentityId),
|
|
58
63
|
},
|
|
59
64
|
// ── outbound adapter ────────────────────────────────────────────
|
|
60
65
|
outbound: {
|
|
61
66
|
deliveryMode: 'direct',
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
async sendText(ctx) {
|
|
69
|
+
const { text, cfg } = ctx;
|
|
70
|
+
// Resolve account + client
|
|
71
|
+
const accountId = ctx.accountId ?? 'default';
|
|
72
|
+
let client = clients.get(accountId);
|
|
73
|
+
let account = accounts.get(accountId);
|
|
74
|
+
if (!client || !account) {
|
|
75
|
+
// Try resolving from cfg
|
|
76
|
+
const quiubo = cfg?.channels?.quiubo?.accounts?.[accountId];
|
|
77
|
+
if (!quiubo?.apiKey) {
|
|
78
|
+
return { ok: false, error: 'No account config found' };
|
|
79
|
+
}
|
|
80
|
+
const apiUrl = quiubo.apiUrl ?? 'https://api.quiubo.io';
|
|
81
|
+
client = new QuiuboApiClient(apiUrl, quiubo.apiKey);
|
|
82
|
+
account = { ...quiubo, accountId };
|
|
83
|
+
clients.set(accountId, client);
|
|
84
|
+
accounts.set(accountId, account);
|
|
85
|
+
}
|
|
86
|
+
// Get groupId from context — OpenClaw sets this from inbound routing
|
|
87
|
+
const groupId = ctx.to ?? ctx.target?.groupId ?? ctx.target?.raw?.groupId;
|
|
66
88
|
if (!groupId) {
|
|
67
|
-
|
|
68
|
-
return { ok: false };
|
|
89
|
+
return { ok: false, error: 'No groupId in outbound context' };
|
|
69
90
|
}
|
|
70
|
-
const senderId =
|
|
91
|
+
const senderId = account.botIdentityId;
|
|
71
92
|
if (!senderId) {
|
|
72
|
-
|
|
73
|
-
return { ok: false };
|
|
93
|
+
return { ok: false, error: 'No botIdentityId configured' };
|
|
74
94
|
}
|
|
75
95
|
try {
|
|
76
96
|
await client.sendMessage(groupId, {
|
|
@@ -80,17 +100,173 @@ export const quiuboPlugin = {
|
|
|
80
100
|
return { ok: true };
|
|
81
101
|
}
|
|
82
102
|
catch (error) {
|
|
83
|
-
|
|
84
|
-
return { ok: false };
|
|
103
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
104
|
+
return { ok: false, error: msg };
|
|
85
105
|
}
|
|
86
106
|
},
|
|
87
107
|
},
|
|
108
|
+
// ── gateway adapter ─────────────────────────────────────────────
|
|
109
|
+
gateway: {
|
|
110
|
+
/**
|
|
111
|
+
* Called by OpenClaw per account when the gateway starts.
|
|
112
|
+
*
|
|
113
|
+
* ctx provides: { cfg, accountId, account, abortSignal, log }
|
|
114
|
+
* - cfg: full OpenClaw config
|
|
115
|
+
* - accountId: which account to start
|
|
116
|
+
* - account: resolved account config (from resolveAccount)
|
|
117
|
+
* - abortSignal: signal to stop this account's gateway
|
|
118
|
+
* - log: structured logger
|
|
119
|
+
*/
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
121
|
+
startAccount: async (ctx) => {
|
|
122
|
+
const { cfg, accountId, abortSignal, log } = ctx;
|
|
123
|
+
const quiuboConfig = cfg.channels?.quiubo?.accounts?.[accountId];
|
|
124
|
+
if (!quiuboConfig?.apiKey || !quiuboConfig?.botIdentityId) {
|
|
125
|
+
log?.warn?.(`[${accountId}] Quiubo: missing apiKey or botIdentityId, skipping`);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const apiUrl = quiuboConfig.apiUrl ?? 'https://api.quiubo.io';
|
|
129
|
+
const { apiKey, botIdentityId, pollIntervalMs } = quiuboConfig;
|
|
130
|
+
const runtime = getQuiuboRuntime();
|
|
131
|
+
// Discovery: log runtime shape on first startup to verify method paths
|
|
132
|
+
log?.info?.(`[${accountId}] Quiubo: runtime keys: ${Object.keys(runtime).join(', ')}`);
|
|
133
|
+
if (runtime.channel) {
|
|
134
|
+
log?.info?.(`[${accountId}] Quiubo: runtime.channel keys: ${Object.keys(runtime.channel).join(', ')}`);
|
|
135
|
+
if (runtime.channel.reply) {
|
|
136
|
+
log?.info?.(`[${accountId}] Quiubo: runtime.channel.reply keys: ${Object.keys(runtime.channel.reply).join(', ')}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const client = new QuiuboApiClient(apiUrl, apiKey);
|
|
140
|
+
// Cache for outbound
|
|
141
|
+
clients.set(accountId, client);
|
|
142
|
+
accounts.set(accountId, { ...quiuboConfig, accountId });
|
|
143
|
+
// Authenticate and get Pusher config
|
|
144
|
+
let pusherConfig;
|
|
145
|
+
try {
|
|
146
|
+
const auth = await client.authenticate();
|
|
147
|
+
pusherConfig = auth.pusher;
|
|
148
|
+
log?.info?.(`[${accountId}] Quiubo: authenticated as ${auth.appName} (${auth.appId})`);
|
|
149
|
+
if (pusherConfig) {
|
|
150
|
+
log?.info?.(`[${accountId}] Quiubo: Pusher available (cluster: ${pusherConfig.cluster})`);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
log?.info?.(`[${accountId}] Quiubo: Pusher not configured — using polling`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
log?.error?.(`[${accountId}] Quiubo: authentication failed: ${error}`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// Create gateway with inbound routing callback
|
|
161
|
+
const gateway = new RealtimeGateway({
|
|
162
|
+
client,
|
|
163
|
+
botIdentityId,
|
|
164
|
+
pusher: pusherConfig,
|
|
165
|
+
pollIntervalMs: pollIntervalMs ?? 5000,
|
|
166
|
+
onMessage: async (msg) => {
|
|
167
|
+
try {
|
|
168
|
+
await routeInboundMessage({
|
|
169
|
+
runtime,
|
|
170
|
+
cfg,
|
|
171
|
+
accountId,
|
|
172
|
+
botIdentityId,
|
|
173
|
+
client,
|
|
174
|
+
msg,
|
|
175
|
+
log,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
log?.error?.(`[${accountId}] Quiubo: inbound routing failed: ${error}`);
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
gateways.set(accountId, gateway);
|
|
184
|
+
await gateway.start();
|
|
185
|
+
log?.info?.(`[${accountId}] Quiubo: gateway started`);
|
|
186
|
+
// Return a promise that resolves when aborted (keeps the gateway alive)
|
|
187
|
+
return new Promise((resolve) => {
|
|
188
|
+
const cleanup = () => {
|
|
189
|
+
log?.info?.(`[${accountId}] Quiubo: gateway stopping`);
|
|
190
|
+
gateway.stop();
|
|
191
|
+
gateways.delete(accountId);
|
|
192
|
+
clients.delete(accountId);
|
|
193
|
+
accounts.delete(accountId);
|
|
194
|
+
resolve();
|
|
195
|
+
};
|
|
196
|
+
if (abortSignal) {
|
|
197
|
+
abortSignal.addEventListener('abort', cleanup, { once: true });
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
},
|
|
88
202
|
};
|
|
89
203
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
204
|
+
* Route an inbound message through OpenClaw's agent pipeline.
|
|
205
|
+
*
|
|
206
|
+
* Uses runtime.channel.reply.finalizeInboundContext() then
|
|
207
|
+
* runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher()
|
|
208
|
+
* — same pattern as openclaw-mqtt.
|
|
92
209
|
*/
|
|
93
|
-
|
|
94
|
-
|
|
210
|
+
async function routeInboundMessage(opts) {
|
|
211
|
+
const { runtime, cfg, accountId, botIdentityId, client, msg, log } = opts;
|
|
212
|
+
const senderId = msg.senderIdentityId;
|
|
213
|
+
const groupId = msg.groupId;
|
|
214
|
+
const text = msg.plaintext;
|
|
215
|
+
log?.info?.(`[${accountId}] Quiubo: inbound from ${senderId} in group ${groupId}: ${text?.slice(0, 100)}`);
|
|
216
|
+
// Step 1: Build standardized inbound context
|
|
217
|
+
const ctxPayload = runtime.channel.reply.finalizeInboundContext({
|
|
218
|
+
Body: text,
|
|
219
|
+
RawBody: text,
|
|
220
|
+
CommandBody: text,
|
|
221
|
+
CommandAuthorized: true,
|
|
222
|
+
From: `quiubo:${senderId}`,
|
|
223
|
+
To: `quiubo:${botIdentityId}`,
|
|
224
|
+
SessionKey: `agent:main:quiubo:${groupId}`,
|
|
225
|
+
AccountId: accountId,
|
|
226
|
+
ChatType: 'group',
|
|
227
|
+
ConversationLabel: `quiubo:${groupId}`,
|
|
228
|
+
SenderName: msg.senderUsername ?? senderId,
|
|
229
|
+
SenderId: senderId,
|
|
230
|
+
Provider: 'quiubo',
|
|
231
|
+
Surface: 'quiubo',
|
|
232
|
+
MessageSid: `quiubo-${msg.messageId}`,
|
|
233
|
+
Timestamp: msg.createdAt ? new Date(msg.createdAt).getTime() : Date.now(),
|
|
234
|
+
});
|
|
235
|
+
// Step 2: Dispatch through OpenClaw's reply system
|
|
236
|
+
await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
237
|
+
ctx: ctxPayload,
|
|
238
|
+
cfg,
|
|
239
|
+
dispatcherOptions: {
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
241
|
+
deliver: async (payload, info) => {
|
|
242
|
+
if (!payload.text) {
|
|
243
|
+
log?.debug?.(`[${accountId}] Quiubo: skipping empty ${info.kind} reply`);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
log?.info?.(`[${accountId}] Quiubo: delivering ${info.kind} reply [${payload.text.length} chars]`);
|
|
247
|
+
try {
|
|
248
|
+
await client.sendMessage(groupId, {
|
|
249
|
+
senderIdentityId: botIdentityId,
|
|
250
|
+
plaintext: payload.text,
|
|
251
|
+
});
|
|
252
|
+
log?.info?.(`[${accountId}] Quiubo: reply sent to group ${groupId}`);
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
log?.error?.(`[${accountId}] Quiubo: failed to send reply: ${error}`);
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
259
|
+
onSkip: (_payload, info) => {
|
|
260
|
+
log?.debug?.(`[${accountId}] Quiubo: skipped reply (${info.reason})`);
|
|
261
|
+
},
|
|
262
|
+
onError: (err, info) => {
|
|
263
|
+
log?.error?.(`[${accountId}] Quiubo: ${info.kind} reply error: ${err}`);
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
replyOptions: {
|
|
267
|
+
disableBlockStreaming: true,
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
log?.info?.(`[${accountId}] Quiubo: message processed from ${senderId}`);
|
|
95
271
|
}
|
|
96
272
|
//# sourceMappingURL=channel.js.map
|
package/dist/src/channel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quiubo PluginRuntime Singleton
|
|
3
|
+
*
|
|
4
|
+
* Stores the PluginRuntime reference provided by OpenClaw during register().
|
|
5
|
+
* Used by the channel plugin to route inbound messages through the agent pipeline.
|
|
6
|
+
*
|
|
7
|
+
* Pattern: identical to openclaw-mqtt/src/runtime.ts
|
|
8
|
+
*/
|
|
9
|
+
export declare function setQuiuboRuntime(r: any): void;
|
|
10
|
+
export declare function getQuiuboRuntime(): any;
|
|
11
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAE7C;AAGD,wBAAgB,gBAAgB,IAAI,GAAG,CAKtC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quiubo PluginRuntime Singleton
|
|
3
|
+
*
|
|
4
|
+
* Stores the PluginRuntime reference provided by OpenClaw during register().
|
|
5
|
+
* Used by the channel plugin to route inbound messages through the agent pipeline.
|
|
6
|
+
*
|
|
7
|
+
* Pattern: identical to openclaw-mqtt/src/runtime.ts
|
|
8
|
+
*/
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
+
let runtime;
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
export function setQuiuboRuntime(r) {
|
|
13
|
+
runtime = r;
|
|
14
|
+
}
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
export function getQuiuboRuntime() {
|
|
17
|
+
if (!runtime) {
|
|
18
|
+
throw new Error('Quiubo runtime not initialized — register() not called yet');
|
|
19
|
+
}
|
|
20
|
+
return runtime;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,8DAA8D;AAC9D,IAAI,OAAwB,CAAC;AAE7B,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAAC,CAAM;IACrC,OAAO,GAAG,CAAC,CAAC;AACd,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/openclaw.plugin.json
CHANGED