Simplify install with one-click scripts; honor HTTP(S)_PROXY for Telegram.
Add install.ps1/install.sh, shrink README to script-first flow, register bot commands, and route API calls through undici EnvHttpProxyAgent when a proxy is set (v0.2.2). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -51,9 +51,21 @@ export class TelegramBridge {
|
||||
this.ctx.logger.error(this.redact(err));
|
||||
});
|
||||
});
|
||||
void this.client.setMyCommands([
|
||||
{ command: 'start', description: '欢迎与用法' },
|
||||
{ command: 'sessions', description: '列出并附着本机 live 会话' },
|
||||
{ command: 'status', description: '查看当前绑定' },
|
||||
{ command: 'unbind', description: '断开手机绑定(不关闭本机会话)' },
|
||||
{ command: 'help', description: '显示帮助' },
|
||||
]).then(() => {
|
||||
this.ctx.logger.info('dsh-telegram-channel: bot commands registered');
|
||||
}).catch((err) => {
|
||||
this.ctx.logger.warn(`dsh-telegram-channel: setMyCommands failed: ${this.redact(err)}`);
|
||||
});
|
||||
if (!this.polling) {
|
||||
this.polling = true;
|
||||
this.pollAbort = new AbortController();
|
||||
this.ctx.logger.info('dsh-telegram-channel: long-polling started');
|
||||
this.pollPromise = this.pollLoop();
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+6
@@ -35,6 +35,10 @@ export interface InlineKeyboardButton {
|
||||
export interface InlineKeyboardMarkup {
|
||||
inline_keyboard: InlineKeyboardButton[][];
|
||||
}
|
||||
export interface TelegramBotCommand {
|
||||
command: string;
|
||||
description: string;
|
||||
}
|
||||
export interface TelegramClientOptions {
|
||||
fetch?: typeof fetch;
|
||||
baseUrl?: string;
|
||||
@@ -46,6 +50,7 @@ export interface TelegramClientLike {
|
||||
sendMessage(chatId: number, text: string, parseMode?: string, replyMarkup?: InlineKeyboardMarkup): Promise<TelegramMessage>;
|
||||
sendChatAction(chatId: number, action: string): Promise<boolean>;
|
||||
answerCallbackQuery(callbackQueryId: string, text?: string): Promise<boolean>;
|
||||
setMyCommands(commands: TelegramBotCommand[]): Promise<boolean>;
|
||||
}
|
||||
export declare class TelegramClient implements TelegramClientLike {
|
||||
private readonly token;
|
||||
@@ -60,4 +65,5 @@ export declare class TelegramClient implements TelegramClientLike {
|
||||
sendMessage(chatId: number, text: string, parseMode?: string, replyMarkup?: InlineKeyboardMarkup): Promise<TelegramMessage>;
|
||||
sendChatAction(chatId: number, action: string): Promise<boolean>;
|
||||
answerCallbackQuery(callbackQueryId: string, text?: string): Promise<boolean>;
|
||||
setMyCommands(commands: TelegramBotCommand[]): Promise<boolean>;
|
||||
}
|
||||
|
||||
+26
-1
@@ -1,3 +1,25 @@
|
||||
import { EnvHttpProxyAgent, fetch as undiciFetch } from 'undici';
|
||||
function resolveProxyUrl() {
|
||||
return (process.env.HTTPS_PROXY
|
||||
|| process.env.HTTP_PROXY
|
||||
|| process.env.https_proxy
|
||||
|| process.env.http_proxy
|
||||
|| undefined);
|
||||
}
|
||||
/**
|
||||
* Node's global `fetch` ignores HTTP(S)_PROXY unless `NODE_USE_ENV_PROXY=1`.
|
||||
* Undici's EnvHttpProxyAgent honors the env vars (and NO_PROXY).
|
||||
*/
|
||||
function createDefaultFetch() {
|
||||
if (!resolveProxyUrl())
|
||||
return globalThis.fetch;
|
||||
const agent = new EnvHttpProxyAgent();
|
||||
const proxied = ((input, init) => undiciFetch(input, {
|
||||
...init,
|
||||
dispatcher: agent,
|
||||
}));
|
||||
return proxied;
|
||||
}
|
||||
export class TelegramClient {
|
||||
token;
|
||||
fetchImpl;
|
||||
@@ -8,7 +30,7 @@ export class TelegramClient {
|
||||
throw new Error('bot token is required');
|
||||
}
|
||||
this.token = token;
|
||||
this.fetchImpl = options.fetch ?? fetch;
|
||||
this.fetchImpl = options.fetch ?? createDefaultFetch();
|
||||
this.baseUrl = options.baseUrl ?? 'https://api.telegram.org';
|
||||
this.pollingTimeoutSec = options.pollingTimeoutSec ?? 30;
|
||||
}
|
||||
@@ -69,4 +91,7 @@ export class TelegramClient {
|
||||
body.text = text;
|
||||
return this.call('answerCallbackQuery', body);
|
||||
}
|
||||
async setMyCommands(commands) {
|
||||
return this.call('setMyCommands', { commands });
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -9,6 +9,18 @@ export const Config = Schema.object({
|
||||
maxMessageLength: Schema.number().default(4096),
|
||||
pollingTimeoutSec: Schema.number().default(30),
|
||||
});
|
||||
function resolveAllowedUserIds(config) {
|
||||
if (config.allowedUserIds && config.allowedUserIds.length > 0) {
|
||||
return config.allowedUserIds;
|
||||
}
|
||||
const raw = process.env.DSH_TELEGRAM_ALLOWED_USER_IDS ?? '';
|
||||
return raw
|
||||
.split(/[,;\s]+/)
|
||||
.map((part) => part.trim())
|
||||
.filter(Boolean)
|
||||
.map((part) => Number(part))
|
||||
.filter((n) => Number.isFinite(n) && n > 0);
|
||||
}
|
||||
export function apply(ctx, config) {
|
||||
const token = (config.token && config.token.length > 0)
|
||||
? config.token
|
||||
@@ -19,7 +31,7 @@ export function apply(ctx, config) {
|
||||
}
|
||||
const bridge = new TelegramBridge(ctx, {
|
||||
token,
|
||||
allowedUserIds: config.allowedUserIds ?? [],
|
||||
allowedUserIds: resolveAllowedUserIds(config),
|
||||
allowAllUsers: config.allowAllUsers ?? false,
|
||||
maxMessageLength: config.maxMessageLength ?? 4096,
|
||||
pollingTimeoutSec: config.pollingTimeoutSec ?? 30,
|
||||
|
||||
Reference in New Issue
Block a user