mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 04:00:21 +00:00
fix(ci): align telegram runtime and test drift
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import type { ReactionTypeEmoji } from "@grammyjs/types";
|
||||
import { resolveAckReaction } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import {
|
||||
createStatusReactionController,
|
||||
@@ -42,6 +43,40 @@ export type {
|
||||
TelegramMediaRef,
|
||||
} from "./bot-message-context.types.js";
|
||||
|
||||
type TelegramMessageContextPayload = Awaited<ReturnType<typeof buildTelegramInboundContextPayload>>;
|
||||
type TelegramReactionApi = (
|
||||
chatId: number | string,
|
||||
messageId: number,
|
||||
reactions: Array<{ type: "emoji"; emoji: ReactionTypeEmoji["emoji"] }>,
|
||||
) => Promise<unknown>;
|
||||
|
||||
export type TelegramMessageContext = {
|
||||
ctxPayload: TelegramMessageContextPayload["ctxPayload"];
|
||||
primaryCtx: BuildTelegramMessageContextParams["primaryCtx"];
|
||||
msg: BuildTelegramMessageContextParams["primaryCtx"]["message"];
|
||||
chatId: number | string;
|
||||
isGroup: boolean;
|
||||
groupConfig?: ReturnType<
|
||||
BuildTelegramMessageContextParams["resolveTelegramGroupConfig"]
|
||||
>["groupConfig"];
|
||||
resolvedThreadId?: number;
|
||||
threadSpec: ReturnType<typeof resolveTelegramThreadSpec>;
|
||||
replyThreadId?: number;
|
||||
isForum: boolean;
|
||||
historyKey?: string;
|
||||
historyLimit: BuildTelegramMessageContextParams["historyLimit"];
|
||||
groupHistories: BuildTelegramMessageContextParams["groupHistories"];
|
||||
route: ReturnType<typeof resolveTelegramConversationRoute>["route"];
|
||||
skillFilter: TelegramMessageContextPayload["skillFilter"];
|
||||
sendTyping: () => Promise<void>;
|
||||
sendRecordVoice: () => Promise<void>;
|
||||
ackReactionPromise: Promise<boolean> | null;
|
||||
reactionApi: TelegramReactionApi | null;
|
||||
removeAckAfterReply: boolean;
|
||||
statusReactionController: StatusReactionController | null;
|
||||
accountId: string;
|
||||
};
|
||||
|
||||
export const buildTelegramMessageContext = async ({
|
||||
primaryCtx,
|
||||
allMedia,
|
||||
@@ -64,7 +99,7 @@ export const buildTelegramMessageContext = async ({
|
||||
loadFreshConfig,
|
||||
upsertPairingRequest,
|
||||
sendChatActionHandler,
|
||||
}: BuildTelegramMessageContextParams) => {
|
||||
}: BuildTelegramMessageContextParams): Promise<TelegramMessageContext | null> => {
|
||||
const msg = primaryCtx.message;
|
||||
const chatId = msg.chat.id;
|
||||
const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup";
|
||||
@@ -378,7 +413,7 @@ export const buildTelegramMessageContext = async ({
|
||||
return;
|
||||
}
|
||||
await reactionApi(chatId, msg.message_id, [
|
||||
{ type: "emoji", emoji: resolvedEmoji },
|
||||
{ type: "emoji", emoji: resolvedEmoji as ReactionTypeEmoji["emoji"] },
|
||||
]);
|
||||
}
|
||||
},
|
||||
@@ -404,7 +439,10 @@ export const buildTelegramMessageContext = async ({
|
||||
: shouldAckReaction() && msg.message_id && reactionApi
|
||||
? withTelegramApiErrorLogging({
|
||||
operation: "setMessageReaction",
|
||||
fn: () => reactionApi(chatId, msg.message_id, [{ type: "emoji", emoji: ackReaction }]),
|
||||
fn: () =>
|
||||
reactionApi(chatId, msg.message_id, [
|
||||
{ type: "emoji", emoji: ackReaction as ReactionTypeEmoji["emoji"] },
|
||||
]),
|
||||
}).then(
|
||||
() => true,
|
||||
(err) => {
|
||||
@@ -469,7 +507,3 @@ export const buildTelegramMessageContext = async ({
|
||||
accountId: account.accountId,
|
||||
};
|
||||
};
|
||||
|
||||
export type TelegramMessageContext = NonNullable<
|
||||
Awaited<ReturnType<typeof buildTelegramMessageContext>>
|
||||
>;
|
||||
|
||||
@@ -943,7 +943,9 @@ export const dispatchTelegramMessage = async ({
|
||||
removeAfterReply: removeAckAfterReply,
|
||||
ackReactionPromise,
|
||||
ackReactionValue: ackReactionPromise ? "ack" : null,
|
||||
remove: () => reactionApi?.(chatId, msg.message_id ?? 0, []) ?? Promise.resolve(),
|
||||
remove: async () => {
|
||||
await (reactionApi?.(chatId, msg.message_id ?? 0, []) ?? Promise.resolve());
|
||||
},
|
||||
onError: (err) => {
|
||||
if (!msg.message_id) {
|
||||
return;
|
||||
|
||||
@@ -5,7 +5,7 @@ export type TelegramStreamMode = "off" | "partial" | "block";
|
||||
|
||||
export type TelegramGetFile = () => Promise<{ file_path?: string }>;
|
||||
export type TelegramChatDetails = {
|
||||
available_reactions?: ChatFullInfo["available_reactions"];
|
||||
available_reactions?: ChatFullInfo["available_reactions"] | null;
|
||||
is_forum?: boolean;
|
||||
};
|
||||
export type TelegramGetChat = (chatId: number | string) => Promise<TelegramChatDetails>;
|
||||
|
||||
@@ -12,7 +12,7 @@ const DRAFT_METHOD_UNAVAILABLE_RE =
|
||||
const DRAFT_CHAT_UNSUPPORTED_RE = /(can't be used|can be used only)/i;
|
||||
|
||||
type TelegramSendMessageDraft = (
|
||||
chatId: number,
|
||||
chatId: Parameters<Bot["api"]["sendMessage"]>[0],
|
||||
draftId: number,
|
||||
text: string,
|
||||
params?: {
|
||||
@@ -105,7 +105,7 @@ type SupersededTelegramPreview = {
|
||||
|
||||
export function createTelegramDraftStream(params: {
|
||||
api: Bot["api"];
|
||||
chatId: number;
|
||||
chatId: Parameters<Bot["api"]["sendMessage"]>[0];
|
||||
maxChars?: number;
|
||||
thread?: TelegramThreadSpec | null;
|
||||
previewTransport?: "auto" | "message" | "draft";
|
||||
@@ -180,8 +180,8 @@ export function createTelegramDraftStream(params: {
|
||||
}
|
||||
: replyParams;
|
||||
const usedThreadParams =
|
||||
"message_thread_id" in (sendParams ?? {}) &&
|
||||
typeof sendParams?.message_thread_id === "number";
|
||||
typeof (sendParams as { message_thread_id?: unknown } | undefined)?.message_thread_id ===
|
||||
"number";
|
||||
try {
|
||||
return {
|
||||
sent: await params.api.sendMessage(chatId, sendArgs.renderedText, sendParams),
|
||||
|
||||
@@ -18,5 +18,6 @@ export function isTelegramForumServiceMessage(msg: unknown): boolean {
|
||||
if (!msg || typeof msg !== "object") {
|
||||
return false;
|
||||
}
|
||||
return TELEGRAM_FORUM_SERVICE_FIELDS.some((field) => field in msg && msg[field] != null);
|
||||
const record = msg as Record<string, unknown>;
|
||||
return TELEGRAM_FORUM_SERVICE_FIELDS.some((field) => field in record && record[field] != null);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ReactionTypeEmoji } from "@grammyjs/types";
|
||||
import type { ChannelAccountSnapshot } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { DEFAULT_EMOJIS } from "../../../src/channels/status-reactions.js";
|
||||
@@ -138,7 +139,7 @@ describe("isTelegramSupportedReactionEmoji", () => {
|
||||
|
||||
describe("extractTelegramAllowedEmojiReactions", () => {
|
||||
it("returns undefined when chat does not include available_reactions", () => {
|
||||
const result = extractTelegramAllowedEmojiReactions({ id: 1 });
|
||||
const result = extractTelegramAllowedEmojiReactions({});
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -170,11 +171,11 @@ describe("extractTelegramAllowedEmojiReactions", () => {
|
||||
describe("resolveTelegramAllowedEmojiReactions", () => {
|
||||
it("uses getChat lookup when message chat does not include available_reactions", async () => {
|
||||
const getChat = async () => ({
|
||||
available_reactions: [{ type: "emoji", emoji: "👍" }],
|
||||
available_reactions: [{ type: "emoji", emoji: "👍" as ReactionTypeEmoji["emoji"] } as const],
|
||||
});
|
||||
|
||||
const result = await resolveTelegramAllowedEmojiReactions({
|
||||
chat: { id: 1 },
|
||||
chat: {},
|
||||
chatId: 1,
|
||||
getChat,
|
||||
});
|
||||
@@ -188,7 +189,7 @@ describe("resolveTelegramAllowedEmojiReactions", () => {
|
||||
};
|
||||
|
||||
const result = await resolveTelegramAllowedEmojiReactions({
|
||||
chat: { id: 1 },
|
||||
chat: {},
|
||||
chatId: 1,
|
||||
getChat,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user