Skip to main content

Telegram Send

@magistr/telegram-sendv2026.08.19.1· 3d agoMODELS
01README

Send messages, photos, and documents to Telegram chats and channels via the Telegram Bot API.

Methods:

  • getMe — verify the bot token and fetch bot identity (smoke test)
  • sendMessage — text with optional MarkdownV2 / HTML formatting
  • sendPhoto — image by URL, Telegram file_id, or local file path
  • sendDocument — arbitrary file (PDF, ZIP, …) up to 50 MB

The botToken is stored as a sensitive globalArgument and routed to a vault automatically. Set defaultChatId on the model instance to avoid repeating the chat target on every call.

A natural complement to @magistr/telegram-import, which goes the other direction — importing Telegram channel exports into Obsidian.

02Models1
@magistr/telegram/sendv2026.08.19.1extensions/models/telegram_send.ts
fn getMe()
Call getMe to verify the bot token and fetch bot identity. Use as a smoke-test.
fn sendMessage(text: string, disableWebPagePreview?: boolean, disableNotification?: boolean, replyToMessageId?: number)
Send a text message to a chat or channel.
ArgumentTypeDescription
textstringMessage text (1-4096 characters)
disableWebPagePreview?boolean
disableNotification?boolean
replyToMessageId?number
fn sendPhoto(chatId?: string, caption?: string, disableNotification?: boolean)
Send a photo. `photo` may be an https URL, a Telegram file_id, or a local file path.
ArgumentTypeDescription
chatId?string
caption?string
disableNotification?boolean
fn sendDocument(chatId?: string, caption?: string, disableNotification?: boolean)
Send a document/file. `document` may be an https URL, a Telegram file_id, or a local file path.
ArgumentTypeDescription
chatId?string
caption?string
disableNotification?boolean

Resources

botInfo(infinite)— Bot identity returned by getMe
sentMessage(infinite)— Result of a send* call
03Previous Versions3
2026.08.01.1

2026.08.01.1

Security hardening: closes the HIGH bot-token credential-leak tracked below as a "Known gap" in the Unreleased entry (filed and planned as the issue-lifecycle model telegram-send-hardening-richmessage-port).

  • Added a module-private redactToken(message, token) pure helper to telegram_send.ts. It replaces the live /bot<token>/ URL segment with /bot<redacted>/, then applies a generic /bot[^/]+/ regex backstop so any /bot.../ path segment is scrubbed even if the token reaches the message reformatted (re-cased, percent-encoded, or otherwise transformed) rather than byte-for-byte. message is accepted as unknown and safely coerced to a string — a fetch rejection is not guaranteed to be an Error with a string .message (it may be a DOMException, a thrown string, or an arbitrary non-Error value) — so no unsanitized shape can pass through unredacted.
  • telegramJson and telegramMultipart now wrap their fetch() call in try/catch: a network-layer rejection (DNS failure, TLS error, connection reset) is caught and rethrown with its message redacted via redactToken, preserving the original rejection as cause for downstream diagnostics. Only the fetch() call itself is wrapped — the ok:false API-error throw (never carries the token, pinned GREEN and covered by property test c) is untouched.
  • Behavior-preserving otherwise: legitimate sends and the ok:false API-error path are unchanged.
  • Tests: flipped the two adversarial suite's former "HONEST GAP pin" tests (telegram_send_adversarial_test.ts, telegramJson/getMe and telegramMultipart/sendPhoto) to assert the fetch-rejection message is now redacted (contains /bot<redacted>/, excludes the raw token, preserves .cause) instead of asserting verbatim propagation. Added direct redactToken unit tests: exact-token redaction, token-free passthrough, the generic backstop for a reformatted token, and non-Error/DOMException/ thrown-string/plain-object coercion (including a case where a non-Error value's own string form embeds the token). All 72 suite tests green; property suite green at FC_NUM_RUNS=5000.
  • README.md: updated the Security note — the token-in-URL fetch-rejection gap is now redacted rather than an open gap.
  • quality.yaml: the byte-frozen-source justification no longer applies (source is modified); ratchet re-measured live.
  • Deferred, tracked separately: porting sendRichMessage from the homelab dev copy is OUT OF SCOPE for this security fix (its homelab source-of-truth is not in this read-only snapshot, so folding it in would be a blind, unverifiable port). It remains tracked by the issue-lifecycle model telegram-send-hardening-richmessage-port as a follow-up.
2026.07.16.2

Release 2026.07.16.2 — align model versions with manifests

Maintenance release across the @magistr extensions. For most packages this carries no functional change: the only edit is the model's version: field, brought back in line with its manifest version so the published model type version and the package version no longer drift.

Functional changes in this release are limited to:

  • anime-cron: normalizeTitle now strips a ": subtitle" suffix and a trailing parenthesized year before comparison, fixing dedup false-misses where the torrent title carries a subtitle or year that the AniList romaji does not.

  • arckit: first publish. Standalone ArcKit port — a 12-phase architecture governance state machine with 65 bundled templates, driven by a bundled skill.

Also tracks three extensions (kaiten, observability-agent, music-library) that previously existed only as untracked working-tree directories, recovered from stashes.

2026.05.13.1
04Stats
A
100 / 100
Downloads
4
Archive size
9.1 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
05Platforms
06Labels