openclaw-msg9 0.1.0 → 0.2.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/dist/src/client.js +2 -17
- package/dist/src/gateway.d.ts +5 -3
- package/dist/src/gateway.js +14 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
package/dist/src/client.js
CHANGED
|
@@ -1,29 +1,14 @@
|
|
|
1
1
|
import { Agent } from "msg9-io";
|
|
2
|
-
const DEFAULT_BASE_URL = "https://api.msg9.io";
|
|
3
2
|
export function createMsg9Agent(account) {
|
|
4
3
|
const agent = new Agent({
|
|
5
4
|
address: account.address,
|
|
6
5
|
apiKey: account.apiKey,
|
|
7
6
|
...(account.baseUrl ? { baseUrl: account.baseUrl } : {}),
|
|
8
7
|
});
|
|
9
|
-
const baseUrl = (account.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
10
|
-
async function postInboxState(suffix) {
|
|
11
|
-
const response = await fetch(`${baseUrl}/api/v1/inbox/messages/${encodeURIComponent(suffix)}`, {
|
|
12
|
-
method: "POST",
|
|
13
|
-
headers: { Authorization: `Bearer ${account.apiKey}` },
|
|
14
|
-
});
|
|
15
|
-
if (!response.ok) {
|
|
16
|
-
throw new Error(`msg9 inbox state update failed: ${response.status} ${response.statusText}`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
8
|
return {
|
|
20
9
|
unread: () => agent.unread(),
|
|
21
10
|
send: (options) => agent.send(options),
|
|
22
|
-
markRead:
|
|
23
|
-
|
|
24
|
-
: (id) => postInboxState(`${id}/read`),
|
|
25
|
-
markProcessed: typeof agent.markProcessed === "function"
|
|
26
|
-
? (id) => agent.markProcessed(id, "agent")
|
|
27
|
-
: (id) => postInboxState(`${id}/processed`),
|
|
11
|
+
markRead: (id) => agent.markRead(id, "agent"),
|
|
12
|
+
markProcessed: (id) => agent.markProcessed(id, "agent"),
|
|
28
13
|
};
|
|
29
14
|
}
|
package/dist/src/gateway.d.ts
CHANGED
|
@@ -23,8 +23,10 @@ export declare function resolveInboundCommandAuthorization(params: {
|
|
|
23
23
|
* Poll the msg9 inbox until the abort signal fires.
|
|
24
24
|
*
|
|
25
25
|
* Each sweep drains `agent.unread()` fully. Every message is deduped by
|
|
26
|
-
* message_id,
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* message_id, self-echo-filtered (mail from this account's own address is a
|
|
27
|
+
* reply that landed back in the same inbox — marked processed and skipped so
|
|
28
|
+
* the agent never talks to itself), allowFrom-filtered (non-listed senders
|
|
29
|
+
* are marked read and skipped), then marked processed BEFORE dispatch so the
|
|
30
|
+
* agent is driven at-most-once even if dispatch or delivery fails.
|
|
29
31
|
*/
|
|
30
32
|
export declare function startGateway(ctx: GatewayContext): Promise<void>;
|
package/dist/src/gateway.js
CHANGED
|
@@ -62,9 +62,11 @@ function formatInboundEnvelope(pluginRuntime, params) {
|
|
|
62
62
|
* Poll the msg9 inbox until the abort signal fires.
|
|
63
63
|
*
|
|
64
64
|
* Each sweep drains `agent.unread()` fully. Every message is deduped by
|
|
65
|
-
* message_id,
|
|
66
|
-
*
|
|
67
|
-
*
|
|
65
|
+
* message_id, self-echo-filtered (mail from this account's own address is a
|
|
66
|
+
* reply that landed back in the same inbox — marked processed and skipped so
|
|
67
|
+
* the agent never talks to itself), allowFrom-filtered (non-listed senders
|
|
68
|
+
* are marked read and skipped), then marked processed BEFORE dispatch so the
|
|
69
|
+
* agent is driven at-most-once even if dispatch or delivery fails.
|
|
68
70
|
*/
|
|
69
71
|
export async function startGateway(ctx) {
|
|
70
72
|
const { account, abortSignal, cfg, onReady, onError, log } = ctx;
|
|
@@ -92,6 +94,15 @@ export async function startGateway(ctx) {
|
|
|
92
94
|
}
|
|
93
95
|
seenMessageIds.add(messageId);
|
|
94
96
|
const from = message.from_address;
|
|
97
|
+
// Self-echo filter: a reply this account sent to its own address lands
|
|
98
|
+
// back in the same inbox and would otherwise be dispatched as new
|
|
99
|
+
// inbound mail, re-triggering the agent in an infinite loop. Consume
|
|
100
|
+
// (markProcessed) and never dispatch.
|
|
101
|
+
if (from === account.address) {
|
|
102
|
+
log?.info(`[msg9:${account.accountId}] Ignoring self-addressed echo msg=${messageId}`);
|
|
103
|
+
await agent.markProcessed(messageId);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
95
106
|
// allowFrom check — blocked senders stay visible in the owner's
|
|
96
107
|
// unprocessed folder but never reach the agent.
|
|
97
108
|
if (account.allowFrom && account.allowFrom.length > 0 && !account.allowFrom.includes(from)) {
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-msg9",
|
|
3
3
|
"displayName": "OpenClaw msg9",
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"description": "OpenClaw msg9.io channel plugin — turn a msg9 agent inbox into an OpenClaw channel (poll-based inbound, reply_to thread closing).",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"pack:dry-run": "npm pack --dry-run"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"msg9-io": "^0.
|
|
35
|
+
"msg9-io": "^0.11.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^20.0.0",
|