SuperAPI AI Directory

enrich-api-page

Coding & development

View repository

Updated 10-15 21:55

About this skill

Enrich API Reference Page

You are enriching the user-maintained sections of one or more Telegram Bot API reference pages in GramIO docs.

Arguments

The user provides one or more method/type names, space-separated:

sendPhoto
sendMessage sendPhoto getUpdates
Message InlineKeyboardMarkup

Process each name sequentially. After finishing all pages, give a summary of what was done.

What You Must NEVER Touch

  • Anything between <!-- GENERATED:START --> and <!-- GENERATED:END --> markers in the page body

The frontmatter IS yours to update — SEO optimization is a primary goal of enrichment.


Steps (repeat for each name)

1. Read the existing page

Find the file:

  • Methods: docs/telegram/methods/{name}.md
  • Types: docs/telegram/types/{name}.md

Note which sections are empty/placeholder vs. already have content. Don't overwrite sections that already have good content — only improve or fill missing ones.

2. Fetch the official Telegram docs

https://core.telegram.org/bots/api#{lowercasename}

Extract:

  • Full description nuances and caveats
  • All constraints mentioned (limits, timing, chat-type restrictions)
  • Which methods/types are cross-referenced

3. Update SEO frontmatter

SEO is critical — people searching Google for sendMessage telegram, telegram bot api sendMessage etc. should find GramIO docs.

Update the frontmatter fields:

title — exact search-match format:

sendMessage — Telegram Bot API | GramIO
Message Object — Telegram Bot API | GramIO

description (meta) — action-oriented, 140–160 chars, mentions GramIO and TypeScript:

Send text messages using GramIO with TypeScript. Complete sendMessage parameter reference,
entity formatting examples, reply_markup, and common error handling.

Good description anatomy: [Action verb] [what it does] using GramIO. [Key features]: [param1], [param2], [use case].

keywords (meta) — include all of:

  • The method/type name itself (highest priority)
  • telegram bot api, telegram bot
  • gramio {name}, {name} typescript, {name} example
  • All required parameter names
  • Common search phrases: how to {action} telegram bot, telegram {name} method
  • Return type name if notable

Example for sendMessage:

sendMessage, telegram bot api, send message telegram bot, gramio sendMessage,
telegram send text message, sendMessage typescript, chat_id, parse_mode, reply_markup,
telegram bot send message example, how to send message telegram bot

4. Research errors

For methods only (skip for types).

Use this error knowledge base, then add method-specific ones from official docs:

Universal (any method):

  • 400 Bad Request: chat not found — invalid/inaccessible chat_id
  • 400 Bad Request: message not found — referenced message doesn't exist
  • 403 Forbidden: bot was blocked by the user — user blocked the bot
  • 403 Forbidden: bot is not a member of the channel chat — bot not in channel
  • 403 Forbidden: not enough rights — bot lacks required permissions
  • 429 Too Many Requests: retry after N — flood control, check retry_after

sendMessage:

  • 400 TEXT_TOO_LONG — text > 4096 chars
  • 400 can't parse entities — malformed entities or wrong parse_mode markup

sendPhoto / sendDocument / sendVideo / sendAudio:

  • 400 PHOTO_INVALID_DIMENSIONS — image dimensions too large
  • 400 wrong file identifier/HTTP URL specified — bad file_id or inaccessible URL

answerCallbackQuery:

  • 400 query is too old and response timeout expired — must answer within 10 seconds

answerInlineQuery:

  • 400 QUERY_ID_INVALID — query expired (>10s) or already answered

editMessage*:

  • 400 message is not modified — new content identical to current
  • 400 message can't be edited — message too old, or sent by a different bot

5. Verify types via local .d.ts (primary) or JSR (fallback)

CRITICAL: Never invent types or properties. Before writing any code example, verify the actual type signatures.

Context naming convention — camelCase only:

  • GramIO contexts use camelCase for all properties and methods: ctx.text, ctx.from, ctx.chat, ctx.replyMessage, ctx.senderChat, etc.
  • NEVER use snake_case on context objects — ctx.reply_to_message is WRONG, ctx.update.message?.text is WRONG
  • Snake_case exists only in the raw Telegram payload: ctx.payload.reply_to_message — but always prefer the typed camelCase accessors
  • NEVER pass object to ctx.send() — ctx.send({ sticker: id }) is WRONG; each media type has its own method

Primary: Grep the local .d.ts

The most reliable and fastest way. The .d.ts for @gramio/contexts is available locally:

node_modules/@gramio/contexts/dist/index.d.ts

Use Grep to find exact method signatures before using them:

# Find a specific method on a context:
Grep "sendSticker" node_modules/@gramio/contexts/dist/index.d.ts
Grep "replyWithSticker" node_modules/@gramio/contexts/dist/index.d.ts

# Find all properties on a context class:
Grep "get text\|get from\|get chat\|get caption" node_modules/@gramio/contexts/dist/index.d.ts

Built-in cheat sheet — MessageContext

These methods are confirmed from @gramio/contexts/dist/index.d.ts. Use this before grepping.

Send methods — chat_id is injected automatically, first arg is the media/content:

Method First arg Notes
ctx.send(text, params?) string sendMessage shorthand
ctx.sendPhoto(photo, params?) file —
ctx.sendDocument(document, params?) file —
ctx.sendAudio(audio, params?) file —
ctx.sendVideo(video, params?) file —
ctx.sendAnimation(animation, params?) file —
ctx.sendVoice(voice, params?) file —
ctx.sendVideoNote(videoNote, params?) file —
ctx.sendSticker(sticker, params?) file —
ctx.sendLocation(lat, lon, params?) numbers —
ctx.sendDice(emoji, params?) string —
ctx.sendPoll(params) — full params
ctx.sendContact(params) — full params
ctx.sendVenue(params) — full params
ctx.sendInvoice(params) — full params
ctx.sendMediaGroup(media, params?) array returns MessageContext[]
ctx.sendPaidMedia(media, starCount, params?) array, number —
ctx.sendChatAction(action, params?) string returns true

Reply methods — same as send* but also set reply_parameters pointing to the current message:

Method Notes
ctx.reply(text, params?) reply to current message with text
ctx.replyWithPhoto(photo, params?) —
ctx.replyWithDocument(document, params?) —
ctx.replyWithAudio(audio, params?) —
ctx.replyWithVideo(video, params?) —
ctx.replyWithAnimation(animation, params?) —
ctx.replyWithVoice(voice, params?) —
ctx.replyWithVideoNote(videoNote, params?) —
ctx.replyWithSticker(sticker, params?) —
ctx.replyWithLocation(lat, lon, params?) —
ctx.replyWithMediaGroup(media, params?) returns MessageContext[]
ctx.replyWithDice(emoji, params?) —
ctx.replyWithPoll(params) —
ctx.replyWithContact(params) —
ctx.replyWithVenue(params) —
ctx.replyWithInvoice(params) —

Edit/delete methods:

Method Notes
ctx.editText(text, params?) alias: editMessageText
ctx.editCaption(caption, params?) alias: editMessageCaption
ctx.editMedia(media, params?) alias: editMessageMedia
ctx.editReplyMarkup(markup, params?) alias: editMessageReplyMarkup
ctx.editChecklist(checklist, params?) —
ctx.delete(params?) delete current message
ctx.deleteMessages(ids) delete multiple
ctx.copy(params?) copyMessage shorthand
ctx.forward(params?) forwardMessage shorthand

Common properties (all camelCase):

Property Type Notes
ctx.text string | undefined message text
ctx.caption string | undefined media caption
ctx.from User | undefined sender (undefined in channel posts)
ctx.chat Chat current chat
ctx.attachment varies message media (photo, sticker, etc.)
ctx.replyMessage MessageContext | undefined replied-to message
ctx.payload raw TelegramMessage raw snake_case data

Fallback: JSR (for uncommon context classes)

For context classes not covered by the cheat sheet above (e.g. CallbackQueryContext, InlineQueryContext, ChatJoinRequestContext), use Grep on the local .d.ts first. JSR is a last resort only when the .d.ts is not available:

Package JSR URL
@gramio/contexts https://jsr.io/@gramio/contexts/doc
@gramio/types https://jsr.io/@gramio/types/doc

If a method/property is not found via Grep — don't use it.

6. Write the enriched sections

## GramIO Usage

Write 3–6 TypeScript examples:

  • Context shorthand first (ctx.send, ctx.reply, ctx.answerCallbackQuery)
  • Direct bot.api.methodName({...}) call second
  • One example per key use case
  • Imports when needed

Code format — use ts twoslash:

All code blocks MUST use ```ts twoslash instead of ```typescript. This enables build-time type checking — if you use a type that doesn't exist, the VitePress build will fail.

Pattern for examples:

```ts twoslash
import { Bot } from "gramio";

const bot = new Bot("");
// ---cut---
// The visible example starts after ---cut---
bot.command("start", (ctx) => ctx.send("Hello!"));
```
  • // ---cut--- hides the setup code (imports, Bot creation) from the rendered page but keeps it for type checking
  • // ^? shows an inline type hover annotation — use sparingly for key types
  • If the example needs extra imports (format, keyboards, etc.), put them before // ---cut---
  • If the example is a standalone snippet (not inside a handler), you may omit // ---cut---

Code rules:

  • format tagged template builds entities, never add parse_mode alongside it
  • ctx.send() → shorthand for sendMessage to current chat
  • ctx.reply() → additionally sets reply_parameters
  • For files: await MediaUpload.path("./file.jpg") or await MediaUpload.url("https://...") — both are async, always use await
  • MediaUpload.buffer(buf, "name.ext") and MediaUpload.text("content", "name.txt") are synchronous (no await needed)
  • MediaInput builds complete TelegramInputMedia* objects — use it for methods that accept InputMedia arrays/objects (sendMediaGroup, editMessageMedia):
    • MediaInput.photo(media, options?) → TelegramInputMediaPhoto ({ type: "photo", media, ...options })
    • MediaInput.video(media, options?) → TelegramInputMediaVideo
    • MediaInput.audio(media, options?) → TelegramInputMediaAudio
    • MediaInput.document(media, options?) → TelegramInputMediaDocument
    • MediaInput.animation(media, options?) → TelegramInputMediaAnimation
    • The media argument is a file_id string or a MediaUpload result; options can include caption, parse_mode, etc.
    • Do NOT use MediaInput for InputStoryContent — story content uses { type, photo/video } (different field name), not { type, media }. Use plain MediaUpload + manual object construction for stories.
  • Always link to /files/media-upload in See Also when the method involves file uploads
  • Always link to /formatting in See Also when the method accepts text, caption, or message_text (formatting is applicable)
  • Always link to /keyboards/overview in See Also when the method involves reply_markup, inline keyboards, or callback queries

Import convention — prefer importing from "gramio" directly:

  • Keyboard, InlineKeyboard, ForceReply, RemoveKeyboard are re-exported from "gramio" — import them from "gramio", not "@gramio/keyboards"
  • MediaUpload and MediaInput are re-exported from "gramio" — import them from "gramio", not "@gramio/files"
  • format, bold, italic, code, link, etc. are re-exported from "gramio" — import them from "gramio", not "@gramio/format"
  • Only use the individual package imports (@gramio/keyboards, @gramio/files, @gramio/format) when explicitly working outside of the main gramio package

Good:

import {
    Bot,
    InlineKeyboard,
    MediaUpload,
    MediaInput,
    format,
    bold,
} from "gramio";

Avoid:

import { InlineKeyboard } from "@gramio/keyboards";
import { MediaUpload } from "@gramio/files";
import { MediaInput } from "@gramio/files";

## Errors

Write a markdown table with context annotations in the Cause column:

| Code | Error                                    | Cause                                                                                       |
| ---- | ---------------------------------------- | ------------------------------------------------------------------------------------------- |
| 400  | `Bad Request: TEXT_TOO_LONG`             | `text` exceeds 4096 chars — use [Split plugin](/plugins/official/split)                     |
| 403  | `Forbidden: bot was blocked by the user` | User blocked the bot — catch and mark user as inactive                                      |
| 429  | `Too Many Requests: retry after N`       | Rate limit hit — check `retry_after`, use [auto-retry plugin](/plugins/official/auto-retry) |

The Cause column is user-maintained non-generated data — make it maximally useful:

  • Don't just repeat what the error says — explain why it happens
  • Add a short action hint: what should the developer do? (catch, retry, validate, etc.)
  • Link to relevant plugins or docs pages when applicable
  • For rate limits, always mention retry_after and the auto-retry plugin

Add a tip block if auto-retry is relevant:

::: tip
Use GramIO's [auto-retry plugin](/plugins/official/auto-retry) to handle `429` errors automatically.
:::

## Tips & Gotchas

Write 3–6 bullet points. These are also user-maintained — make them actionable annotations, not just paraphrased docs:

Good pattern: **Key point.** Explanation of why it matters + what to do.

- **Text limit is 4096 characters.** For longer content, use the [Split plugin](/plugins/official/split) — it handles entity preservation automatically.
- **`parse_mode` and `entities` are mutually exclusive.** GramIO's `format` helper always produces `entities`, so never pass `parse_mode` alongside it.
- **`chat_id` accepts `@username` strings** for public groups/channels. Private chats always require the numeric ID.

Focus on:

  • Constraints with consequences (limits, timing, rate limits)
  • Mutually exclusive parameters
  • Chat-type behavioral differences (private / group / supergroup / channel)
  • Common pitfalls that cause silent bugs or unexpected behavior
  • GramIO-specific patterns that simplify the task

## See Also

4–8 links. Always verify with Glob that the target page exists before linking.

# Check if page exists:
ls docs/telegram/methods/sendPhoto.md
ls docs/telegram/types/Message.md
ls docs/plugins/official/auto-retry.md

Include:

  • Related methods (same category)
  • Return type and key parameter types (link to their /telegram/types/ pages)
  • Relevant GramIO guides that exist: /formatting, /keyboards/overview, /files
  • Plugins that apply

7. Report progress

After each page, briefly list:

  • ✅ Sections added/updated
  • ⚠️ Anything uncertain or that needs human review
  • → Suggested next: related pages worth enriching

After all pages are done, print a summary table:

| Page | SEO | Usage | Errors | Tips | See Also |
|------|-----|-------|--------|------|----------|
| sendMessage | ✅ | ✅ | ✅ | ✅ | ✅ |
| sendPhoto   | ✅ | ✅ | ✅ | ✅ | ✅ |

Quality Bar

  • SEO: title matches the exact search query people use; keywords include all major variants
  • Types: every property access, method call, and type annotation must exist in the real GramIO/Telegram types — verified via Grep on local .d.ts or the cheat sheet above. Zero invented types. ctx.send({ sticker }) is WRONG — use ctx.sendSticker(id).
  • Examples: ts twoslash code blocks, correct imports, realistic values, idiomatic GramIO. Build MUST pass — if twoslash fails, the type is wrong
  • Errors: accurate (mark uncertain ones with *); Cause column is a useful annotation, not just error text
  • Tips: actionable, non-obvious, each one saves a developer real time
  • Links: only link pages that exist