mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:30:43 +00:00
fix(telegram): skip polling webhook probe
This commit is contained in:
@@ -15,6 +15,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Channels/Telegram: skip the optional webhook-info API call during polling-mode status checks and startup bot-label probes so long-polling setups avoid an unnecessary Telegram round trip. Carries forward #72990. Thanks @danielgruneberg.
|
||||
- Sessions: ignore future-dated session activity timestamps during reset freshness checks and cap future `updatedAt` values at the merge boundary so clock-skewed messages cannot keep stale sessions alive forever. Fixes #72989. Thanks @martingarramon.
|
||||
- Plugins/CLI: allow managed plugin installs when the active extensions root is a symlink to a real state directory, while keeping nested target symlinks blocked and suppressing misleading hook-pack fallback errors for install-boundary failures. Fixes #72946. Thanks @mayank6136.
|
||||
- Gateway/startup: keep hot Gateway boot paths on leaf config imports and add max-RSS reporting to the gateway startup bench so low-memory startup regressions are visible before release. Thanks @vincentkoc.
|
||||
|
||||
@@ -769,6 +769,7 @@ export const telegramPlugin = createChatChannelPlugin({
|
||||
proxyUrl: account.config.proxy,
|
||||
network: account.config.network,
|
||||
apiRoot: account.config.apiRoot,
|
||||
includeWebhookInfo: Boolean(account.config.webhookUrl),
|
||||
}),
|
||||
formatCapabilitiesProbe: ({ probe }) => {
|
||||
const lines = [];
|
||||
@@ -885,6 +886,7 @@ export const telegramPlugin = createChatChannelPlugin({
|
||||
proxyUrl: account.config.proxy,
|
||||
network: account.config.network,
|
||||
apiRoot: account.config.apiRoot,
|
||||
includeWebhookInfo: false,
|
||||
});
|
||||
const username = probe.ok ? probe.bot?.username?.trim() : null;
|
||||
if (username) {
|
||||
|
||||
@@ -173,6 +173,18 @@ describe("probeTelegram retry logic", () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1); // Should not retry
|
||||
});
|
||||
|
||||
it("can skip webhook info when caller only needs bot identity", async () => {
|
||||
const fetchMock = installFetchMock();
|
||||
mockGetMeSuccess(fetchMock);
|
||||
|
||||
const result = await probeTelegram(token, timeoutMs, { includeWebhookInfo: false });
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.webhook).toBeUndefined();
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock.mock.calls[0]?.[0]).toBe("https://api.telegram.org/bottest-token/getMe");
|
||||
});
|
||||
|
||||
it("uses resolver-scoped Telegram fetch with probe network options", async () => {
|
||||
const fetchMock = installFetchMock();
|
||||
mockGetMeSuccess(fetchMock);
|
||||
@@ -192,7 +204,6 @@ describe("probeTelegram retry logic", () => {
|
||||
autoSelectFamily: false,
|
||||
dnsResultOrder: "ipv4first",
|
||||
},
|
||||
apiRoot: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ export type TelegramProbeOptions = {
|
||||
network?: TelegramNetworkConfig;
|
||||
accountId?: string;
|
||||
apiRoot?: string;
|
||||
includeWebhookInfo?: boolean;
|
||||
};
|
||||
|
||||
const probeFetcherCache = new Map<string, typeof fetch>();
|
||||
@@ -102,6 +103,7 @@ export async function probeTelegram(
|
||||
const timeoutBudgetMs = Math.max(1, Math.floor(timeoutMs));
|
||||
const deadlineMs = started + timeoutBudgetMs;
|
||||
const options = resolveProbeOptions(proxyOrOptions);
|
||||
const includeWebhookInfo = options?.includeWebhookInfo !== false;
|
||||
const fetcher = resolveProbeFetcher(token, options);
|
||||
const apiBase = resolveTelegramApiBase(options?.apiRoot);
|
||||
const base = `${apiBase}/bot${token}`;
|
||||
@@ -184,29 +186,31 @@ export async function probeTelegram(
|
||||
: null,
|
||||
};
|
||||
|
||||
// Try to fetch webhook info, but don't fail health if it errors.
|
||||
try {
|
||||
const webhookRemainingBudgetMs = resolveRemainingBudgetMs();
|
||||
if (webhookRemainingBudgetMs > 0) {
|
||||
const webhookRes = await fetchWithTimeout(
|
||||
`${base}/getWebhookInfo`,
|
||||
{},
|
||||
Math.max(1, Math.min(timeoutBudgetMs, webhookRemainingBudgetMs)),
|
||||
fetcher,
|
||||
);
|
||||
const webhookJson = (await webhookRes.json()) as {
|
||||
ok?: boolean;
|
||||
result?: { url?: string; has_custom_certificate?: boolean };
|
||||
};
|
||||
if (webhookRes.ok && webhookJson?.ok) {
|
||||
result.webhook = {
|
||||
url: webhookJson.result?.url ?? null,
|
||||
hasCustomCert: webhookJson.result?.has_custom_certificate ?? null,
|
||||
if (includeWebhookInfo) {
|
||||
// Try to fetch webhook info, but don't fail health if it errors.
|
||||
try {
|
||||
const webhookRemainingBudgetMs = resolveRemainingBudgetMs();
|
||||
if (webhookRemainingBudgetMs > 0) {
|
||||
const webhookRes = await fetchWithTimeout(
|
||||
`${base}/getWebhookInfo`,
|
||||
{},
|
||||
Math.max(1, Math.min(timeoutBudgetMs, webhookRemainingBudgetMs)),
|
||||
fetcher,
|
||||
);
|
||||
const webhookJson = (await webhookRes.json()) as {
|
||||
ok?: boolean;
|
||||
result?: { url?: string; has_custom_certificate?: boolean };
|
||||
};
|
||||
if (webhookRes.ok && webhookJson?.ok) {
|
||||
result.webhook = {
|
||||
url: webhookJson.result?.url ?? null,
|
||||
hasCustomCert: webhookJson.result?.has_custom_certificate ?? null,
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore webhook errors for probe
|
||||
}
|
||||
} catch {
|
||||
// ignore webhook errors for probe
|
||||
}
|
||||
|
||||
result.ok = true;
|
||||
|
||||
Reference in New Issue
Block a user