feat: Telegram Bot API integration

- New client: src/clients/telegram.ts
- Tools: telegram_get_me, telegram_send_message, telegram_send_photo, telegram_get_updates, telegram_get_chat
- REST endpoints: GET /api/telegram/me, POST /api/telegram/message, POST /api/telegram/photo, GET /api/telegram/updates, GET /api/telegram/chat
- Multi-account env var pattern: TELEGRAM_{ACCOUNT}_BOT_TOKEN
- Uses Telegram Bot API (https://api.telegram.org)

Total tools: 24 (email 6, obsidian 5, whatsapp 3, linkedin 4, telegram 5)
This commit is contained in:
Garfield
2026-05-05 16:54:07 -04:00
parent 73f83c0d86
commit 385f91de4d
5 changed files with 439 additions and 0 deletions

View File

@@ -623,6 +623,62 @@ app.post('/api/linkedin/message', requireAuth, async (req, res) => {
}
});
// ── Telegram REST endpoints ─────────────────────────────────────
app.get('/api/telegram/me', requireAuth, async (req, res) => {
const account = req.query.account as string | undefined;
try {
const result = await handleToolCall('telegram_get_me', { account });
res.json(parseToolResult(result));
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
});
app.post('/api/telegram/message', requireAuth, async (req, res) => {
const { chat_id, text, parse_mode, account } = req.body as Record<string, unknown>;
if (!chat_id || !text) { res.status(400).json({ error: 'chat_id and text are required' }); return; }
try {
const result = await handleToolCall('telegram_send_message', { chat_id, text, parse_mode, account });
res.json(parseToolResult(result));
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
});
app.post('/api/telegram/photo', requireAuth, async (req, res) => {
const { chat_id, photo, caption, account } = req.body as Record<string, unknown>;
if (!chat_id || !photo) { res.status(400).json({ error: 'chat_id and photo are required' }); return; }
try {
const result = await handleToolCall('telegram_send_photo', { chat_id, photo, caption, account });
res.json(parseToolResult(result));
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
});
app.get('/api/telegram/updates', requireAuth, async (req, res) => {
const limit = req.query.limit ? parseInt(req.query.limit as string, 10) : undefined;
const account = req.query.account as string | undefined;
try {
const result = await handleToolCall('telegram_get_updates', { limit, account });
res.json(parseToolResult(result));
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
});
app.get('/api/telegram/chat', requireAuth, async (req, res) => {
const chat_id = req.query.chat_id as string | undefined;
const account = req.query.account as string | undefined;
if (!chat_id) { res.status(400).json({ error: 'chat_id is required' }); return; }
try {
const result = await handleToolCall('telegram_get_chat', { chat_id, account });
res.json(parseToolResult(result));
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
});
app.post('/api/pilot-request', async (req, res) => {
const origin = req.get('origin');
if (origin && !SQUAREMCP_ALLOWED_ORIGINS.has(origin)) {