openclaw/extensions/telegram/src/network-config.ts

107 lines
3.6 KiB
TypeScript

import process from "node:process";
import type { TelegramNetworkConfig } from "../../../src/config/types.telegram.js";
import { isTruthyEnvValue } from "../../../src/infra/env.js";
import { isWSL2Sync } from "../../../src/infra/wsl.js";
export const TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV =
"OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY";
export const TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV = "OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY";
export const TELEGRAM_DNS_RESULT_ORDER_ENV = "OPENCLAW_TELEGRAM_DNS_RESULT_ORDER";
export type TelegramAutoSelectFamilyDecision = {
value: boolean | null;
source?: string;
};
let wsl2SyncCache: boolean | undefined;
function isWSL2SyncCached(): boolean {
if (typeof wsl2SyncCache === "boolean") {
return wsl2SyncCache;
}
wsl2SyncCache = isWSL2Sync();
return wsl2SyncCache;
}
export type TelegramDnsResultOrderDecision = {
value: string | null;
source?: string;
};
export function resolveTelegramAutoSelectFamilyDecision(params?: {
network?: TelegramNetworkConfig;
env?: NodeJS.ProcessEnv;
nodeMajor?: number;
}): TelegramAutoSelectFamilyDecision {
const env = params?.env ?? process.env;
const nodeMajor =
typeof params?.nodeMajor === "number"
? params.nodeMajor
: Number(process.versions.node.split(".")[0]);
if (isTruthyEnvValue(env[TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV])) {
return { value: true, source: `env:${TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV}` };
}
if (isTruthyEnvValue(env[TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV])) {
return { value: false, source: `env:${TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV}` };
}
if (typeof params?.network?.autoSelectFamily === "boolean") {
return { value: params.network.autoSelectFamily, source: "config" };
}
// WSL2 has unstable IPv6 connectivity; disable autoSelectFamily to use IPv4 directly
if (isWSL2SyncCached()) {
return { value: false, source: "default-wsl2" };
}
if (Number.isFinite(nodeMajor) && nodeMajor >= 22) {
return { value: true, source: "default-node22" };
}
return { value: null };
}
/**
* Resolve DNS result order setting for Telegram network requests.
* Some networks/ISPs have issues with IPv6 causing fetch failures.
* Setting "ipv4first" prioritizes IPv4 addresses in DNS resolution.
*
* Priority:
* 1. Environment variable OPENCLAW_TELEGRAM_DNS_RESULT_ORDER
* 2. Config: channels.telegram.network.dnsResultOrder
* 3. Default: "ipv4first" on Node 22+ (to work around common IPv6 issues)
*/
export function resolveTelegramDnsResultOrderDecision(params?: {
network?: TelegramNetworkConfig;
env?: NodeJS.ProcessEnv;
nodeMajor?: number;
}): TelegramDnsResultOrderDecision {
const env = params?.env ?? process.env;
const nodeMajor =
typeof params?.nodeMajor === "number"
? params.nodeMajor
: Number(process.versions.node.split(".")[0]);
// Check environment variable
const envValue = env[TELEGRAM_DNS_RESULT_ORDER_ENV]?.trim().toLowerCase();
if (envValue === "ipv4first" || envValue === "verbatim") {
return { value: envValue, source: `env:${TELEGRAM_DNS_RESULT_ORDER_ENV}` };
}
// Check config
const configValue = (params?.network as { dnsResultOrder?: string } | undefined)?.dnsResultOrder
?.trim()
.toLowerCase();
if (configValue === "ipv4first" || configValue === "verbatim") {
return { value: configValue, source: "config" };
}
// Default to ipv4first on Node 22+ to avoid IPv6 issues
if (Number.isFinite(nodeMajor) && nodeMajor >= 22) {
return { value: "ipv4first", source: "default-node22" };
}
return { value: null };
}
export function resetTelegramNetworkConfigStateForTests(): void {
wsl2SyncCache = undefined;
}