
























@@ -13,6 +13,7 @@ const canaryTimeoutMs = Number(
1313const warmSampleCount = Number(process.env.OPENCLAW_NPM_TELEGRAM_WARM_SAMPLES ?? "20");
1414const sampleTimeoutMs = Number(process.env.OPENCLAW_NPM_TELEGRAM_SAMPLE_TIMEOUT_MS ?? "30000");
1515const maxWarmFailures = Number(process.env.OPENCLAW_NPM_TELEGRAM_MAX_FAILURES ?? "3");
16+const successMarker = process.env.OPENCLAW_NPM_TELEGRAM_SUCCESS_MARKER ?? "OPENCLAW_E2E_OK";
1617const scenarioIds = (
1718process.env.OPENCLAW_NPM_TELEGRAM_SCENARIOS ?? "telegram-mentioned-message-reply"
1819)
@@ -82,15 +83,18 @@ function messageText(message) {
8283}
83848485async function flushUpdates(bot) {
85-let updates = await bot.getUpdates({ timeout: 0, allowed_updates: ["message"] });
86+let updates = await bot.getUpdates({
87+timeout: 0,
88+allowed_updates: ["message", "edited_message"],
89+});
8690let nextOffset;
8791while (updates.length > 0) {
8892const lastUpdateId = updates.at(-1).update_id;
8993nextOffset = lastUpdateId + 1;
9094updates = await bot.getUpdates({
9195offset: nextOffset,
9296timeout: 0,
93-allowed_updates: ["message"],
97+allowed_updates: ["message", "edited_message"],
9498});
9599}
96100return nextOffset;
@@ -102,15 +106,16 @@ async function waitForSutReply(params) {
102106const updates = await driver.getUpdates({
103107offset: driverUpdateOffset,
104108timeout: 5,
105-allowed_updates: ["message"],
109+allowed_updates: ["message", "edited_message"],
106110});
107111for (const update of updates) {
108112driverUpdateOffset = Math.max(driverUpdateOffset, update.update_id + 1);
109-const message = update.message;
113+const message = update.message ?? update.edited_message;
110114if (!message || String(message.chat?.id) !== String(groupId)) {
111115continue;
112116}
113117observedMessages.push({
118+updateType: update.edited_message ? "edited_message" : "message",
114119updateId: update.update_id,
115120messageId: message.message_id,
116121fromId: message.from?.id,
@@ -128,10 +133,12 @@ async function waitForSutReply(params) {
128133continue;
129134}
130135const text = messageText(message);
136+if (params.matchText && !text.includes(params.matchText)) {
137+continue;
138+}
131139const replyMatches = message.reply_to_message?.message_id === params.requestMessageId;
132-const markerMatches = params.matchText ? text.includes(params.matchText) : false;
133140const anySutReplyMatches = params.allowAnySutReply;
134-if (replyMatches || markerMatches || anySutReplyMatches) {
141+if (replyMatches || anySutReplyMatches || params.matchText) {
135142return message;
136143}
137144}
@@ -143,11 +150,15 @@ async function waitForSutReply(params) {
143150async function runScenario(params) {
144151const startedAt = new Date();
145152const startedUnixSeconds = Math.floor(startedAt.getTime() / 1000);
146-const request = await driver.sendMessage({
153+const sendParams = {
147154chat_id: groupId,
148155text: params.input,
149156disable_notification: true,
150-});
157+};
158+if (params.replyToMessageId) {
159+sendParams.reply_parameters = { message_id: params.replyToMessageId };
160+}
161+const request = await driver.sendMessage(sendParams);
151162152163try {
153164const reply = await waitForSutReply({
@@ -167,6 +178,7 @@ async function runScenario(params) {
167178title: params.title,
168179status: "pass",
169180details: `observed SUT message ${reply.message_id}`,
181+messageId: reply.message_id,
170182 rttMs,
171183};
172184} catch (error) {
@@ -207,10 +219,13 @@ async function runWarmScenario(params) {
207219let failures = 0;
208220let passed = 0;
209221for (let index = 0; passed < params.sampleCount; index += 1) {
222+const sampleMarker = `${successMarker}_${index + 1}`;
210223const sample = await runScenario({
211-allowAnySutReply: true,
224+allowAnySutReply: false,
212225id: params.id,
213-input: `/status@${params.sutUsername}`,
226+input: `@${params.sutUsername} RTT sample ${index + 1}. Reply with exactly ${sampleMarker}.`,
227+matchText: sampleMarker,
228+replyToMessageId: params.replyToMessageId,
214229sampleIndex: index + 1,
215230sutId: params.sutId,
216231timeoutMs: params.sampleTimeoutMs,
@@ -282,27 +297,27 @@ async function main() {
282297driverUpdateOffset = (await flushUpdates(driver)) ?? driverUpdateOffset;
283298284299const scenarios = [];
285-scenarios.push(
286-await runScenario({
287-allowAnySutReply: true,
288-id: "telegram-canary",
289-input: `/status@${sutMe.username}`,
290-sutId: sutMe.id,
291-timeoutMs: canaryTimeoutMs,
292-title: "Telegram canary",
293-}),
294-);
300+const canary = await runScenario({
301+allowAnySutReply: true,
302+id: "telegram-canary",
303+input: `/status@${sutMe.username}`,
304+sutId: sutMe.id,
305+timeoutMs: canaryTimeoutMs,
306+title: "Telegram canary",
307+});
308+scenarios.push(canary);
295309296310if (scenarioIds.includes("telegram-mentioned-message-reply")) {
297311scenarios.push(
298312await runWarmScenario({
299313id: "telegram-mentioned-message-reply",
300314maxFailures: maxWarmFailures,
315+replyToMessageId: canary.messageId,
301316sampleCount: warmSampleCount,
302317 sampleTimeoutMs,
303318sutId: sutMe.id,
304319sutUsername: sutMe.username,
305-title: "Telegram status command reply",
320+title: "Telegram normal reply",
306321}),
307322);
308323}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。