fix(telegram): move network fallback to resolver-scoped dispatchers (#40740)

Merged via squash.

Prepared head SHA: a4456d48b4
Co-authored-by: sircrumpet <4436535+sircrumpet@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
This commit is contained in:
Eugene
2026-03-10 15:58:51 +10:00
committed by GitHub
parent d1a59557b5
commit 45b74fb56c
23 changed files with 1641 additions and 390 deletions

View File

@@ -57,18 +57,38 @@ function installGatewayRuntime(params?: { probeOk?: boolean; botUsername?: strin
const probeTelegram = vi.fn(async () =>
params?.probeOk ? { ok: true, bot: { username: params.botUsername ?? "bot" } } : { ok: false },
);
const collectUnmentionedGroupIds = vi.fn(() => ({
groupIds: [] as string[],
unresolvedGroups: 0,
hasWildcardUnmentionedGroups: false,
}));
const auditGroupMembership = vi.fn(async () => ({
ok: true,
checkedGroups: 0,
unresolvedGroups: 0,
hasWildcardUnmentionedGroups: false,
groups: [],
elapsedMs: 0,
}));
setTelegramRuntime({
channel: {
telegram: {
monitorTelegramProvider,
probeTelegram,
collectUnmentionedGroupIds,
auditGroupMembership,
},
},
logging: {
shouldLogVerbose: () => false,
},
} as unknown as PluginRuntime);
return { monitorTelegramProvider, probeTelegram };
return {
monitorTelegramProvider,
probeTelegram,
collectUnmentionedGroupIds,
auditGroupMembership,
};
}
describe("telegramPlugin duplicate token guard", () => {
@@ -149,6 +169,85 @@ describe("telegramPlugin duplicate token guard", () => {
);
});
it("passes account proxy and network settings into Telegram probes", async () => {
const { probeTelegram } = installGatewayRuntime({
probeOk: true,
botUsername: "opsbot",
});
const cfg = createCfg();
cfg.channels!.telegram!.accounts!.ops = {
...cfg.channels!.telegram!.accounts!.ops,
proxy: "http://127.0.0.1:8888",
network: {
autoSelectFamily: false,
dnsResultOrder: "ipv4first",
},
};
const account = telegramPlugin.config.resolveAccount(cfg, "ops");
await telegramPlugin.status!.probeAccount!({
account,
timeoutMs: 5000,
cfg,
});
expect(probeTelegram).toHaveBeenCalledWith("token-ops", 5000, {
accountId: "ops",
proxyUrl: "http://127.0.0.1:8888",
network: {
autoSelectFamily: false,
dnsResultOrder: "ipv4first",
},
});
});
it("passes account proxy and network settings into Telegram membership audits", async () => {
const { collectUnmentionedGroupIds, auditGroupMembership } = installGatewayRuntime({
probeOk: true,
botUsername: "opsbot",
});
collectUnmentionedGroupIds.mockReturnValue({
groupIds: ["-100123"],
unresolvedGroups: 0,
hasWildcardUnmentionedGroups: false,
});
const cfg = createCfg();
cfg.channels!.telegram!.accounts!.ops = {
...cfg.channels!.telegram!.accounts!.ops,
proxy: "http://127.0.0.1:8888",
network: {
autoSelectFamily: false,
dnsResultOrder: "ipv4first",
},
groups: {
"-100123": { requireMention: false },
},
};
const account = telegramPlugin.config.resolveAccount(cfg, "ops");
await telegramPlugin.status!.auditAccount!({
account,
timeoutMs: 5000,
probe: { ok: true, bot: { id: 123 }, elapsedMs: 1 },
cfg,
});
expect(auditGroupMembership).toHaveBeenCalledWith({
token: "token-ops",
botId: 123,
groupIds: ["-100123"],
proxyUrl: "http://127.0.0.1:8888",
network: {
autoSelectFamily: false,
dnsResultOrder: "ipv4first",
},
timeoutMs: 5000,
});
});
it("forwards mediaLocalRoots to sendMessageTelegram for outbound media sends", async () => {
const sendMessageTelegram = vi.fn(async () => ({ messageId: "tg-1" }));
setTelegramRuntime({

View File

@@ -438,11 +438,11 @@ export const telegramPlugin: ChannelPlugin<ResolvedTelegramAccount, TelegramProb
collectStatusIssues: collectTelegramStatusIssues,
buildChannelSummary: ({ snapshot }) => buildTokenChannelStatusSummary(snapshot),
probeAccount: async ({ account, timeoutMs }) =>
getTelegramRuntime().channel.telegram.probeTelegram(
account.token,
timeoutMs,
account.config.proxy,
),
getTelegramRuntime().channel.telegram.probeTelegram(account.token, timeoutMs, {
accountId: account.accountId,
proxyUrl: account.config.proxy,
network: account.config.network,
}),
auditAccount: async ({ account, timeoutMs, probe, cfg }) => {
const groups =
cfg.channels?.telegram?.accounts?.[account.accountId]?.groups ??
@@ -468,6 +468,7 @@ export const telegramPlugin: ChannelPlugin<ResolvedTelegramAccount, TelegramProb
botId,
groupIds,
proxyUrl: account.config.proxy,
network: account.config.network,
timeoutMs,
});
return { ...audit, unresolvedGroups, hasWildcardUnmentionedGroups };
@@ -531,11 +532,11 @@ export const telegramPlugin: ChannelPlugin<ResolvedTelegramAccount, TelegramProb
const token = (account.token ?? "").trim();
let telegramBotLabel = "";
try {
const probe = await getTelegramRuntime().channel.telegram.probeTelegram(
token,
2500,
account.config.proxy,
);
const probe = await getTelegramRuntime().channel.telegram.probeTelegram(token, 2500, {
accountId: account.accountId,
proxyUrl: account.config.proxy,
network: account.config.network,
});
const username = probe.ok ? probe.bot?.username?.trim() : null;
if (username) {
telegramBotLabel = ` (@${username})`;