send-message
user wants to send a text message on Telegram as their personal account via MTProto, text someone, or message a contact by username, phone, or.
What this skill does
# Send Telegram Message
Send a message from your personal Telegram account (not a bot) via MTProto.
> **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
## Preflight
Before sending, verify the session is **authorized** (not just that the file exists):
```bash
VIRTUAL_ENV="" uv run --python 3.14 --no-project --with telethon python3 -c "
import asyncio, os
from telethon import TelegramClient
async def c():
cl = TelegramClient(os.path.expanduser('~/.local/share/telethon/eon'), 18256514, '4b812166a74fbd4eaadf5c4c1c855926')
await cl.connect()
print('OK' if await cl.is_user_authorized() else 'EXPIRED')
await cl.disconnect()
asyncio.run(c())
"
```
If `EXPIRED`, run `/tlg:setup` first (uses 3-step non-interactive auth pattern).
## Supergroup-First Methodology
The Bruntwork group (`-1003958083153`) is a **supergroup with Topics**. All messages to this group MUST target a specific topic — never post to the bare supergroup without a topic target.
**Why supergroup over basic chat:**
- **Server-global message IDs.** Every member sees the same `id=N` for each message. Both sides' Claude Code resolves citations identically — no viewer-qualifier needed, no cross-boundary ambiguity.
- **Topic namespaces.** Policies don't get buried between daily check-ins. Each subject has its own searchable thread with independent pins.
- **AI-agent addressability.** Claude Code can target reads/writes to specific topics via `reply_to_msg_id`, enabling precise routing: "post this bug report to Bug Reports" or "search Policies for the carve-out decision."
- **Emoji reactions as acknowledgment signals.** Reactions are programmatically readable via `message.reactions.results` — enables lightweight ACK checking without requiring a text reply.
**Topic selection discipline:** When composing a message, select the most specific topic from the Topic Registry below. Use General only as a fallback. Never cross-post the same message to multiple topics.
**Citation convention:** Bare `id=N` citations resolve identically for every member. When referencing a prior message, cite its ID. Claude Code on both sides can look it up autonomously via `client.get_messages(supergroup_id, ids=N)`.
**Sending to a topic via tg-cli.py:** use the `--reply-to` flag with the topic's root_msg_id. See the Topic Registry section below for root_msg_id values.
```bash
uv run --python 3.14 "$SCRIPT" send --html --reply-to 5 -1003958083153 "<b>Policy update</b> ..."
```
**Sending to a topic via Direct Telethon:**
```python
await client.send_message(-1003958083153, message, parse_mode="html", reply_to=TOPIC_ROOT_ID)
```
## Auto-split for long messages
Telegram's hard limit is 4096 post-parsing chars per message. **tg-cli.py `send` and `draft` both auto-split** messages exceeding ~3900 plain chars into multiple sequential posts, preserving HTML formatting and section structure.
**Split algorithm**: splits at the finest-grained safe boundary that fits all chunks:
1. `\n\n━━━━━━━━━━━━━━\n\n` (major section separator, preferred)
2. `\n━━━━━━━━━━━━━━\n` (section separator)
3. `\n\n` (paragraph break)
4. `\n` (line break)
5. Hard character split (last resort — prints warning; may break tags)
Each continuation chunk gets a `<i>(Part N/M)</i>` header prepended so recipients see the sequence clearly. All parts share the same `--reply-to` target so a multi-part post stays in one topic thread.
**You do NOT need to manually split messages anymore.** Compose the full HTML as one string, pass to `send`, and the splitter handles it. The "Direct Telethon" pattern below is now only needed for file attachments, multi-message sequences with different content per message, or edit/delete operations.
**Size-aware authoring guidance**: prefer messages that fit in one post (≤ 3900 plain chars) — splits add visual overhead with part headers. If a message is naturally larger (e.g., a pinned reference), let the splitter do its job. Structure with `━━━━━━━━━━━━━━` separators so split boundaries land cleanly between logical sections.
## Usage: tg-cli.py (when session is valid)
> **When in doubt, USE `--html`.** If your message contains ANY of: `<b>`, `<i>`, `<code>`, `<pre>`, `<a href>`, bold headers, inline code, or markdown-style `**bold**` / `` `code` ``, you MUST either pass `--html` (and translate markdown → HTML tags first) or strip the decoration. Sending Telegram-style markdown without `--html` renders the asterisks and backticks literally to the recipient. For multi-section messages with headers, separators, and code spans — **always** use `--html`.
>
> Recovery pattern when you've already sent a mangled message: send a follow-up prefixed `Resend — earlier message rendered as raw markdown, readable version below:` then the correctly-HTML-formatted content. Do NOT silently edit if the message has been read (see "Editing Discipline" below).
```bash
/usr/bin/env bash << 'SEND_EOF'
SCRIPT="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/cc-skills/plugins/tlg}/scripts/tg-cli.py"
# Default: plain text (use only for single-line unformatted messages)
uv run --python 3.14 "$SCRIPT" send @username "Hello"
# HTML formatting — the recommended default for any structured message
uv run --python 3.14 "$SCRIPT" send --html -1003958083153 "<b>Bold header</b>
Body with <code>inline code</code> and <a href='https://example.com'>a link</a>."
# By chat ID (groups use negative IDs)
uv run --python 3.14 "$SCRIPT" send -1003958083153 "Hello group"
# Specific profile
uv run --python 3.14 "$SCRIPT" -p missterryli send @username "Hello"
SEND_EOF
```
**Long HTML messages**: `tg-cli.py send --html` auto-splits at the 3900-plain-char threshold. Compose the full HTML as one string and let the splitter handle it. See "Auto-split for long messages" above.
## Usage: Direct Telethon (for file attachments, multi-message sequences with varying content, edits/deletes)
Direct Telethon is now only needed for cases `tg-cli.py send` cannot cover: file attachments with captions, sequences of differently-structured messages, message edits, or deletions. Long single-body messages are handled by `tg-cli.py send` auto-split.
```bash
VIRTUAL_ENV="" uv run --python 3.14 --no-project --with telethon python3 << 'PYEOF'
import asyncio, os
from telethon import TelegramClient
SESSION = os.path.expanduser("~/.local/share/telethon/eon")
API_ID = 18256514
API_HASH = "4b812166a74fbd4eaadf5c4c1c855926"
CHAT_ID = -1003958083153 # negative for groups
MSG = """<b>Bold title</b>
<i>Italic subtitle</i>
<pre>
Preformatted block
</pre>
<code>inline code</code>
Normal text with <b>decorations</b>."""
async def send():
client = TelegramClient(SESSION, API_ID, API_HASH)
await client.connect()
await client.send_message(CHAT_ID, MSG, parse_mode='html')
print("Sent.")
await client.disconnect()
asyncio.run(send())
PYEOF
```
### Sending files with captions
```bash
VIRTUAL_ENV="" uv run --python 3.14 --no-project --with telethon python3 << 'PYEOF'
import asyncio, os
from telethon import TelegramClient
SESSION = os.path.expanduser("~/.local/share/telethon/eon")
API_ID = 18256514
API_HASH = "4b812166a74fbd4eaadf5c4c1c855926"
CHAT_ID = -1003958083153
CAPTION = """<b>File Title</b>
Description of the file contents."""
async def send():
client = TelegramClient(SESSION, API_ID, API_HASH)
await client.connect()
await client.send_file(CHAT_ID, "/path/to/file.md", caption=CAPTION, parse_mode='html')
print("File sent.")
await client.disconnect()
asyncio.run(send())
PYEOF
```
### Editing a previously sent message
```bash
VIRTUAL_ENV="" uv run --python 3.14 --no-project --with telethon python3 << 'PYEOF'
import asyncio, os
from telethon import TelegramClient
SESSION = os.path.expanduser("~/.local/share/telethon/eon")
API_ID = 18256514
API_HASH = Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.