From telegram
Respond to and interact with users via Telegram. Use when handling inbound Telegram messages, sending replies, reacting to messages, editing bot messages, downloading attachments, or processing voice notes. Covers the full Telegram Bot API surface exposed by the telegram channel plugin.
npx claudepluginhub cameri/claude-skills --plugin telegramThis skill uses the workspace's default tool permissions.
<essential_principles>
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Analyzes BMad project state from catalog CSV, configs, artifacts, and query to recommend next skills or answer questions. Useful for help requests, 'what next', or starting BMad.
<essential_principles>
<channel source="plugin:telegram:telegram" chat_id="..." message_id="..." user="..." user_id="..." ts="...">. The user reads Telegram — your transcript is invisible to them. Everything you want them to see must go through reply.reply_to on a fresh response to the latest message — only use it to thread a reply to an earlier message.attachment_kind="voice") must be transcribed with ElevenLabs STT before responding. See Voice Notes./telegram:access in their terminal.
</essential_principles>Send a text message (and optional file attachments) to a chat.
reply(chat_id, text, reply_to?, format?, files?)
chat_id — from the inbound <channel> tagtext — plain text or MarkdownV2 (must escape special chars if using markdownv2 format)reply_to — set to a message_id only when threading to an earlier message; omit for normal responsesformat — "text" (default) or "markdownv2"files — array of absolute local file paths; images send as inline photos, others as documents (max 50 MB each)Add an emoji reaction to a message.
react(chat_id, message_id, emoji)
Telegram only accepts its fixed whitelist of reaction emojis. Common safe choices: 👍 👎 ❤️ 🔥 🎉 👏 🤔 😱 🙏 ✅ ❌ 👀
Edit the text of a previously sent bot message (in-place, no push notification).
edit_message(chat_id, message_id, text, format?)
Use for progress updates on long-running tasks. Send a new reply when done so the user's device pings them.
Download an attachment from a Telegram message to the local inbox.
download_attachment(file_id) → local file path
Use when the inbound <channel> tag has an attachment_file_id. Returns an absolute path ready to Read or pass to other tools. Telegram caps bot downloads at 20 MB.
</tools>
<inbound_message_anatomy>
<channel
source="plugin:telegram:telegram"
chat_id="123456789"
message_id="42"
user="Alice"
user_id="123456789"
ts="2026-01-01T00:00:00.000Z"
attachment_kind="voice" <!-- optional: photo | document | voice | audio | video | sticker -->
attachment_file_id="AgAD..." <!-- present when attachment exists -->
attachment_size="7724" <!-- bytes -->
attachment_mime="audio/ogg" <!-- MIME type -->
attachment_name="file.pdf" <!-- present for documents -->
image_path="/abs/path/to/photo.jpg" <!-- present for photos (already downloaded) -->
>
message text here
</channel>
Photos: image_path is already downloaded — Read it directly.
All other attachments: call download_attachment(attachment_file_id) first.
</inbound_message_anatomy>
<voice_notes>
When attachment_kind="voice" or attachment_kind="audio":
download_attachment(attachment_file_id) → local pathsource /workspace/.env
curl -s -X POST "https://api.elevenlabs.io/v1/speech-to-text" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-F "file=@/path/to/audio.oga" \
-F "model_id=scribe_v2"
API key lives in /workspace/.env as ELEVENLABS_API_KEY.
</voice_notes>
<text_to_speech>
To send an audio reply using ElevenLabs TTS:
source /workspace/.env
python3 - <<'EOF'
import urllib.request, json
api_key = open('/workspace/.env').read() # parse ELEVENLABS_API_KEY
# Or use the env var directly if sourced
data = json.dumps({
"text": "Your message here",
"model_id": "eleven_turbo_v2_5",
"voice_settings": {"stability": 0.5, "similarity_boost": 0.75}
}).encode()
req = urllib.request.Request(
"https://api.elevenlabs.io/v1/text-to-speech/<voice_id>",
data=data,
headers={"xi-api-key": "<key>", "Content-Type": "application/json"}
)
with urllib.request.urlopen(req) as r:
open("/tmp/reply.mp3", "wb").write(r.read())
EOF
Then reply(chat_id, "caption", files=["/tmp/reply.mp3"]).
Free-tier voice IDs (premade voices work on free accounts; library voices require paid):
See GET https://api.elevenlabs.io/v1/voices with your API key for the full list.
Common: EXAVITQu4vr4xnSDxMaL (Sarah), TX3LPaxmHKxFdv7VOQHJ (Liam), nPczCjzI2devNBz1zQrb (Brian)
</text_to_speech>
<sending_files>
Pass absolute paths to reply(files: [...]):
Plain text (default, format: "text"): safe, no escaping needed.
MarkdownV2 (format: "markdownv2"): supports bold, italic, code, links. You MUST escape these chars with \: . _ * [ ] ( ) ~ > # + - = | { } !
Example MarkdownV2:
*bold* _italic_ `code` [link](https://example.com)
Prefer plain text unless formatting is clearly useful. </formatting>
<long_tasks>
edit_message to update progress in-place (no push notification).reply when done — this pings the user's device.
</long_tasks><references_index>