@gonzih/cc-tg 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bot.d.ts CHANGED
@@ -18,6 +18,7 @@ export declare class CcTgBot {
18
18
  private handleTelegram;
19
19
  private handleVoice;
20
20
  private handlePhoto;
21
+ private handleDocument;
21
22
  private getOrCreateSession;
22
23
  private handleClaudeMessage;
23
24
  private startTyping;
package/dist/bot.js CHANGED
@@ -3,8 +3,8 @@
3
3
  * One ClaudeProcess per chat_id — sessions are isolated per user.
4
4
  */
5
5
  import TelegramBot from "node-telegram-bot-api";
6
- import { existsSync } from "fs";
7
- import { resolve, basename } from "path";
6
+ import { existsSync, createWriteStream, mkdirSync } from "fs";
7
+ import { resolve, basename, join } from "path";
8
8
  import https from "https";
9
9
  import http from "http";
10
10
  import { ClaudeProcess, extractText } from "./claude.js";
@@ -60,6 +60,11 @@ export class CcTgBot {
60
60
  await this.handlePhoto(chatId, msg);
61
61
  return;
62
62
  }
63
+ // Document — download to CWD/.cc-tg/uploads/, tell Claude the path
64
+ if (msg.document) {
65
+ await this.handleDocument(chatId, msg);
66
+ return;
67
+ }
63
68
  const text = msg.text?.trim();
64
69
  if (!text)
65
70
  return;
@@ -147,6 +152,31 @@ export class CcTgBot {
147
152
  await this.bot.sendMessage(chatId, `Failed to process image: ${err.message}`);
148
153
  }
149
154
  }
155
+ async handleDocument(chatId, msg) {
156
+ const doc = msg.document;
157
+ const caption = msg.caption?.trim();
158
+ const fileName = doc.file_name ?? `file_${doc.file_id}`;
159
+ console.log(`[doc:${chatId}] received document file_name=${fileName} mime=${doc.mime_type}`);
160
+ this.bot.sendChatAction(chatId, "typing").catch(() => { });
161
+ try {
162
+ const uploadsDir = join(this.opts.cwd ?? process.cwd(), ".cc-tg", "uploads");
163
+ mkdirSync(uploadsDir, { recursive: true });
164
+ const destPath = join(uploadsDir, fileName);
165
+ const fileLink = await this.bot.getFileLink(doc.file_id);
166
+ await downloadToFile(fileLink, destPath);
167
+ console.log(`[doc:${chatId}] saved to ${destPath}`);
168
+ const prompt = caption
169
+ ? `${caption}\n\nATTACHMENTS: [${fileName}](${destPath})`
170
+ : `ATTACHMENTS: [${fileName}](${destPath})`;
171
+ const session = this.getOrCreateSession(chatId);
172
+ session.claude.sendPrompt(prompt);
173
+ this.startTyping(chatId, session);
174
+ }
175
+ catch (err) {
176
+ console.error(`[doc:${chatId}] error:`, err.message);
177
+ await this.bot.sendMessage(chatId, `Failed to receive document: ${err.message}`);
178
+ }
179
+ }
150
180
  getOrCreateSession(chatId) {
151
181
  const existing = this.sessions.get(chatId);
152
182
  if (existing && !existing.claude.exited)
@@ -395,6 +425,18 @@ function fetchAsBase64(url) {
395
425
  }).on("error", reject);
396
426
  });
397
427
  }
428
+ /** Download a URL to a local file path */
429
+ function downloadToFile(url, destPath) {
430
+ return new Promise((resolve, reject) => {
431
+ const client = url.startsWith("https") ? https : http;
432
+ const file = createWriteStream(destPath);
433
+ client.get(url, (res) => {
434
+ res.pipe(file);
435
+ file.on("finish", () => file.close(() => resolve()));
436
+ file.on("error", reject);
437
+ }).on("error", reject);
438
+ });
439
+ }
398
440
  function splitMessage(text, maxLen = 4096) {
399
441
  if (text.length <= maxLen)
400
442
  return [text];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gonzih/cc-tg",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Claude Code Telegram bot — chat with Claude Code via Telegram",
5
5
  "type": "module",
6
6
  "bin": {