claude-telegram-bot 0.3.33 → 0.3.34

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.
Files changed (2) hide show
  1. package/bot.mjs +44 -2
  2. package/package.json +1 -1
package/bot.mjs CHANGED
@@ -572,6 +572,27 @@ function classifyClaudeError(raw, code) {
572
572
  return `Execution error (exit ${code}):\n${raw}`;
573
573
  }
574
574
 
575
+ // ── 커스텀 명령어 스크립트 실행 ──────────────────────────────────────────
576
+ function runCustomCommand(run, args) {
577
+ return new Promise((resolve) => {
578
+ const cmd = args ? `${run} ${args}` : run;
579
+ const child = spawn(cmd, [], {
580
+ shell: true,
581
+ cwd: cfg.projectDir,
582
+ env: { ...process.env, ...(cfg.env || {}) },
583
+ });
584
+ let out = "", err = "";
585
+ child.stdout.on("data", (d) => (out += d));
586
+ child.stderr.on("data", (d) => (err += d));
587
+ child.on("close", (code) => {
588
+ const text = (out + (err ? `\n[stderr]\n${err}` : "")).trim() || "(no output)";
589
+ resolve({ ok: code === 0, text, code });
590
+ });
591
+ child.on("error", (e) => resolve({ ok: false, text: e.message, code: -1 }));
592
+ setTimeout(() => { try { child.kill(); } catch {} resolve({ ok: false, text: "timeout (60s)", code: -1 }); }, 60_000);
593
+ });
594
+ }
595
+
575
596
  // ── Claude 실행 ───────────────────────────────────────────────────────────
576
597
  function runClaude(prompt, sessionId, opts = {}) {
577
598
  return new Promise((resolve) => {
@@ -1126,6 +1147,22 @@ async function handle(msg) {
1126
1147
  return;
1127
1148
  }
1128
1149
 
1150
+ // 커스텀 명령어 (config.commands) — Claude와 독립 실행
1151
+ if (text.startsWith("/")) {
1152
+ const cmdName = text.slice(1).split(" ")[0];
1153
+ const def = (cfg.commands || {})[cmdName];
1154
+ if (def) {
1155
+ const run = typeof def === "object" ? def.run : null;
1156
+ if (run) {
1157
+ const args = text.length > cmdName.length + 1 ? text.slice(cmdName.length + 2) : "";
1158
+ const res = await runCustomCommand(run, args || undefined);
1159
+ const out = res.text.length > 4000 ? res.text.slice(0, 3990) + "\n…(truncated)" : res.text;
1160
+ await send(chatId, `${res.ok ? "" : "⚠️ "}${out}`);
1161
+ return;
1162
+ }
1163
+ }
1164
+ }
1165
+
1129
1166
  if (busy) {
1130
1167
  msgQueue.push({ msg, receivedAt: Date.now() });
1131
1168
  await send(chatId, t(l, "queued", msgQueue.length));
@@ -1284,9 +1321,14 @@ async function main() {
1284
1321
  }
1285
1322
  // 텔레그램 명령어 자동완성(/ 입력 시 뜨는 메뉴) 등록. 직접 파싱과 별개로 한 번 알려줘야 함.
1286
1323
  // 기본 목록(BOT_LANG) + 한국어 변형(language_code: ko) → ko 클라이언트는 한국어, 그 외 기본.
1287
- tg("setMyCommands", { commands: COMMANDS[BOT_LANG] || COMMANDS.en }).catch(() => {});
1324
+ // config.commands 정의된 커스텀 명령어도 목록에 추가.
1325
+ const customCmdEntries = Object.entries(cfg.commands || {}).map(([name, def]) => ({
1326
+ command: name,
1327
+ description: (typeof def === "object" ? (def.description || name) : name).slice(0, 256),
1328
+ }));
1329
+ tg("setMyCommands", { commands: [...(COMMANDS[BOT_LANG] || COMMANDS.en), ...customCmdEntries] }).catch(() => {});
1288
1330
  if (!FORCE_LANG) {
1289
- tg("setMyCommands", { commands: COMMANDS.ko, language_code: "ko" }).catch(() => {});
1331
+ tg("setMyCommands", { commands: [...COMMANDS.ko, ...customCmdEntries], language_code: "ko" }).catch(() => {});
1290
1332
  }
1291
1333
 
1292
1334
  // 시작 시 밀린 메시지 건너뛰기
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-telegram-bot",
3
- "version": "0.3.33",
3
+ "version": "0.3.34",
4
4
  "description": "Drive Claude Code from Telegram — messages run headless `claude -p` in a project dir and replies come back to the chat. Zero dependencies.",
5
5
  "type": "module",
6
6
  "bin": {