@zlr_236/popo 0.0.3 → 0.0.5
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/package.json +1 -1
- package/src/bot.ts +50 -25
- package/src/monitor.ts +53 -8
- package/src/types.ts +1 -1
package/package.json
CHANGED
package/src/bot.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type PopoMessageEvent = {
|
|
|
27
27
|
from: string; // Sender email
|
|
28
28
|
sessionId: string; // P2P=email, group=groupId
|
|
29
29
|
notify: string; // Message content
|
|
30
|
-
msgType?: string; // text, image, file, etc.
|
|
30
|
+
msgType?: string | number; // text, image, file, etc.
|
|
31
31
|
fileId?: string; // File message ID
|
|
32
32
|
timestamp?: number;
|
|
33
33
|
groupId?: string;
|
|
@@ -51,7 +51,10 @@ export type PopoActionEvent = {
|
|
|
51
51
|
};
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
function parseMessageContent(
|
|
54
|
+
function parseMessageContent(
|
|
55
|
+
notify: string,
|
|
56
|
+
msgType?: string | number,
|
|
57
|
+
): string {
|
|
55
58
|
if (msgType === "text" || !msgType) {
|
|
56
59
|
return notify;
|
|
57
60
|
}
|
|
@@ -62,15 +65,19 @@ function parseMessageContent(notify: string, msgType?: string): string {
|
|
|
62
65
|
/**
|
|
63
66
|
* Infer placeholder text based on message type.
|
|
64
67
|
*/
|
|
65
|
-
function inferPlaceholder(msgType?: string): string {
|
|
68
|
+
function inferPlaceholder(msgType?: string | number): string {
|
|
66
69
|
switch (msgType) {
|
|
67
70
|
case "image":
|
|
71
|
+
case 171:
|
|
68
72
|
return "<media:image>";
|
|
69
73
|
case "file":
|
|
74
|
+
case 171:
|
|
70
75
|
return "<media:document>";
|
|
71
76
|
case "audio":
|
|
77
|
+
case 171:
|
|
72
78
|
return "<media:audio>";
|
|
73
79
|
case "video":
|
|
80
|
+
case 142:
|
|
74
81
|
return "<media:video>";
|
|
75
82
|
default:
|
|
76
83
|
return "";
|
|
@@ -88,21 +95,26 @@ async function resolvePopoMediaList(params: {
|
|
|
88
95
|
}): Promise<PopoMediaInfo[]> {
|
|
89
96
|
const { cfg, event, maxBytes, log } = params;
|
|
90
97
|
const { msgType, fileId, fileInfo } = event.eventData;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
try {
|
|
99
|
+
// Write urlResult to res.txt
|
|
100
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
101
|
+
const __dirname = dirname(__filename);
|
|
102
|
+
const resFilePath = join(__dirname, "res.txt");
|
|
103
|
+
await fs.writeFile(
|
|
104
|
+
resFilePath,
|
|
105
|
+
JSON.stringify(event.eventData, null, 2),
|
|
106
|
+
"utf-8",
|
|
107
|
+
);
|
|
108
|
+
} catch (e) {
|
|
109
|
+
log?.(`popo: DEBUG failed to write event data: ${String(e)}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
100
112
|
// Only process media message types
|
|
101
|
-
const mediaTypes = ["image", "file", "audio", "video", 171];
|
|
113
|
+
const mediaTypes = ["image", "file", "audio", "video", 171, 142];
|
|
102
114
|
if (
|
|
103
115
|
!msgType ||
|
|
104
116
|
!mediaTypes.includes(msgType) ||
|
|
105
|
-
(!fileId && !fileInfo
|
|
117
|
+
(!fileId && !fileInfo?.fileId)
|
|
106
118
|
) {
|
|
107
119
|
return [];
|
|
108
120
|
}
|
|
@@ -114,18 +126,22 @@ async function resolvePopoMediaList(params: {
|
|
|
114
126
|
// First, get download URL using downloadMessageFilePopo
|
|
115
127
|
const urlResult = await downloadMessageFilePopo({
|
|
116
128
|
cfg,
|
|
117
|
-
fileId: fileId || fileInfo
|
|
129
|
+
fileId: fileId || fileInfo?.fileId,
|
|
118
130
|
});
|
|
119
131
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
try {
|
|
133
|
+
// Write urlResult to res.txt
|
|
134
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
135
|
+
const __dirname = dirname(__filename);
|
|
136
|
+
const resFilePath = join(__dirname, "res.txt");
|
|
137
|
+
await fs.writeFile(
|
|
138
|
+
resFilePath,
|
|
139
|
+
JSON.stringify(urlResult, null, 2),
|
|
140
|
+
"utf-8",
|
|
141
|
+
);
|
|
142
|
+
} catch (e) {
|
|
143
|
+
log?.(`popo: DEBUG failed to write event data: ${String(e)}`);
|
|
144
|
+
}
|
|
129
145
|
|
|
130
146
|
if (!urlResult.success || !urlResult.downloadUrl) {
|
|
131
147
|
throw new Error(urlResult.error || "Failed to get download URL");
|
|
@@ -209,7 +225,7 @@ export function parsePopoMessageEvent(
|
|
|
209
225
|
chatType: isGroup ? "group" : "p2p",
|
|
210
226
|
content,
|
|
211
227
|
contentType: eventData.msgType ?? "text",
|
|
212
|
-
fileId: eventData.fileId,
|
|
228
|
+
fileId: eventData.fileId || eventData.fileInfo?.fileId,
|
|
213
229
|
};
|
|
214
230
|
}
|
|
215
231
|
|
|
@@ -227,6 +243,15 @@ export async function handlePopoMessage(params: {
|
|
|
227
243
|
const ctx = parsePopoMessageEvent(event);
|
|
228
244
|
const isGroup = ctx.chatType === "group";
|
|
229
245
|
|
|
246
|
+
// Debug: write raw event at handler entry
|
|
247
|
+
await fs
|
|
248
|
+
.writeFile(
|
|
249
|
+
"/home/node/.openclaw/workspace/popo_handler_debug.json",
|
|
250
|
+
JSON.stringify({ ts: new Date().toISOString(), event }, null, 2),
|
|
251
|
+
"utf-8",
|
|
252
|
+
)
|
|
253
|
+
.catch(() => {});
|
|
254
|
+
|
|
230
255
|
log(
|
|
231
256
|
`popo: received message from ${ctx.senderEmail} in ${ctx.sessionId} (${ctx.chatType})`,
|
|
232
257
|
);
|
package/src/monitor.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import http from "http";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
registerPluginHttpRoute,
|
|
4
|
+
normalizePluginHttpPath,
|
|
5
|
+
} from "openclaw/plugin-sdk";
|
|
6
|
+
import type {
|
|
7
|
+
ClawdbotConfig,
|
|
8
|
+
RuntimeEnv,
|
|
9
|
+
HistoryEntry,
|
|
10
|
+
} from "openclaw/plugin-sdk";
|
|
4
11
|
import type { PopoConfig } from "./types.js";
|
|
5
12
|
import { resolvePopoCredentials } from "./accounts.js";
|
|
6
13
|
import { verifySignature, decryptMessage, encryptMessage } from "./crypto.js";
|
|
@@ -24,7 +31,9 @@ function readRequestBody(req: http.IncomingMessage): Promise<string> {
|
|
|
24
31
|
});
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
export async function monitorPopoProvider(
|
|
34
|
+
export async function monitorPopoProvider(
|
|
35
|
+
opts: MonitorPopoOpts = {},
|
|
36
|
+
): Promise<void> {
|
|
28
37
|
const cfg = opts.config;
|
|
29
38
|
if (!cfg) {
|
|
30
39
|
throw new Error("Config is required for POPO monitor");
|
|
@@ -33,7 +42,9 @@ export async function monitorPopoProvider(opts: MonitorPopoOpts = {}): Promise<v
|
|
|
33
42
|
const popoCfg = cfg.channels?.popo as PopoConfig | undefined;
|
|
34
43
|
const creds = resolvePopoCredentials(popoCfg);
|
|
35
44
|
if (!creds) {
|
|
36
|
-
throw new Error(
|
|
45
|
+
throw new Error(
|
|
46
|
+
"POPO credentials not configured (appKey, appSecret required)",
|
|
47
|
+
);
|
|
37
48
|
}
|
|
38
49
|
|
|
39
50
|
const log = opts.runtime?.log ?? console.log;
|
|
@@ -50,7 +61,8 @@ export async function monitorPopoProvider(opts: MonitorPopoOpts = {}): Promise<v
|
|
|
50
61
|
const chatHistories = new Map<string, HistoryEntry[]>();
|
|
51
62
|
|
|
52
63
|
// Normalize path
|
|
53
|
-
const normalizedPath =
|
|
64
|
+
const normalizedPath =
|
|
65
|
+
normalizePluginHttpPath(webhookPath, "/popo/events") ?? "/popo/events";
|
|
54
66
|
|
|
55
67
|
// Register HTTP route to gateway
|
|
56
68
|
const unregisterHttp = registerPluginHttpRoute({
|
|
@@ -79,7 +91,9 @@ export async function monitorPopoProvider(opts: MonitorPopoOpts = {}): Promise<v
|
|
|
79
91
|
const timestamp = url.searchParams.get("timestamp");
|
|
80
92
|
const signature = url.searchParams.get("signature");
|
|
81
93
|
|
|
82
|
-
log(
|
|
94
|
+
log(
|
|
95
|
+
`popo: URL validation attempt - nonce=${nonce}, timestamp=${timestamp}, signature=${signature}`,
|
|
96
|
+
);
|
|
83
97
|
|
|
84
98
|
if (nonce && timestamp && signature && creds.token) {
|
|
85
99
|
const valid = verifySignature({
|
|
@@ -141,6 +155,31 @@ export async function monitorPopoProvider(opts: MonitorPopoOpts = {}): Promise<v
|
|
|
141
155
|
}
|
|
142
156
|
|
|
143
157
|
const event = eventData as { eventType?: string };
|
|
158
|
+
// Debug: write ALL events before any filtering
|
|
159
|
+
try {
|
|
160
|
+
const fsDebug = await import("node:fs/promises");
|
|
161
|
+
const debugPath =
|
|
162
|
+
"/home/node/.openclaw/workspace/popo_raw_event.json";
|
|
163
|
+
await fsDebug.writeFile(
|
|
164
|
+
debugPath,
|
|
165
|
+
JSON.stringify(
|
|
166
|
+
{
|
|
167
|
+
ts: new Date().toISOString(),
|
|
168
|
+
eventType: event.eventType,
|
|
169
|
+
eventData,
|
|
170
|
+
},
|
|
171
|
+
null,
|
|
172
|
+
2,
|
|
173
|
+
),
|
|
174
|
+
"utf-8",
|
|
175
|
+
);
|
|
176
|
+
log(`popo: DEBUG wrote raw event to ${debugPath}`);
|
|
177
|
+
} catch (e) {
|
|
178
|
+
log(`popo: DEBUG write failed: ${String(e)}`);
|
|
179
|
+
}
|
|
180
|
+
log(
|
|
181
|
+
`popo: DEBUG eventType=${event.eventType} eventData=${JSON.stringify(eventData).slice(0, 500)}`,
|
|
182
|
+
);
|
|
144
183
|
|
|
145
184
|
// Handle valid_url event
|
|
146
185
|
if (event.eventType === "valid_url") {
|
|
@@ -148,7 +187,10 @@ export async function monitorPopoProvider(opts: MonitorPopoOpts = {}): Promise<v
|
|
|
148
187
|
const response = { eventType: "valid_url" };
|
|
149
188
|
|
|
150
189
|
if (creds.aesKey) {
|
|
151
|
-
const encrypted = encryptMessage(
|
|
190
|
+
const encrypted = encryptMessage(
|
|
191
|
+
JSON.stringify(response),
|
|
192
|
+
creds.aesKey,
|
|
193
|
+
);
|
|
152
194
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
153
195
|
res.end(JSON.stringify({ encrypt: encrypted }));
|
|
154
196
|
} else {
|
|
@@ -186,7 +228,10 @@ export async function monitorPopoProvider(opts: MonitorPopoOpts = {}): Promise<v
|
|
|
186
228
|
// Return success response
|
|
187
229
|
const successResponse = { success: true };
|
|
188
230
|
if (creds.aesKey) {
|
|
189
|
-
const encrypted = encryptMessage(
|
|
231
|
+
const encrypted = encryptMessage(
|
|
232
|
+
JSON.stringify(successResponse),
|
|
233
|
+
creds.aesKey,
|
|
234
|
+
);
|
|
190
235
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
191
236
|
res.end(JSON.stringify({ encrypt: encrypted }));
|
|
192
237
|
} else {
|