Skip to content

テレグラムGuide · Telegram

/anime, answered with a picture.

Send /anime a knight cat drinking tea and the bot replies with the image. One file in Python or Node. You need an AnimeAPI key with balance and a Telegram account.
  1. Create the bot with BotFather

    Open @BotFather, send /newbot, pick a name and a username ending in bot. It replies with a token like 123456789:AA…. Optionally send /setcommands with anime - Draw an anime image so the command shows up in the menu.

  2. Python: python-telegram-bot

    terminal
    python3 -m venv .venv && source .venv/bin/activate
    pip install "python-telegram-bot>=21" httpx
    bot.py
    # bot.py · run: TELEGRAM_TOKEN=... ANIMEAPI_KEY=... python bot.py
    import os
    
    import httpx
    from telegram import Update
    from telegram.constants import ChatAction
    from telegram.ext import Application, CommandHandler, ContextTypes
    
    API_URL = "https://animeapi.ai/api/generate"
    HEADERS = {"Authorization": f"Bearer {os.environ['ANIMEAPI_KEY']}"}
    
    
    async def anime(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
        prompt = " ".join(context.args).strip()
        if not prompt:
            await update.message.reply_text("Usage: /anime a girl with a red umbrella at a rainy bus stop")
            return
    
        await update.message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
    
        # Async HTTP so one slow image doesn't block every other chat.
        async with httpx.AsyncClient(timeout=180) as client:
            res = await client.post(
                API_URL,
                headers=HEADERS,
                json={"prompt": prompt, "model": "anime", "allowNSFW": False},
            )
            data = res.json()
            if res.status_code != 200:
                await update.message.reply_text(f"Couldn't draw that ({res.status_code}): {data.get('error')}")
                return
            image = await client.get(data["image_url"])
    
        # Upload the bytes. Telegram converts WebP to a regular photo.
        await update.message.reply_photo(photo=image.content, caption=prompt[:1024])
    
    
    def main() -> None:
        app = Application.builder().token(os.environ["TELEGRAM_TOKEN"]).build()
        app.add_handler(CommandHandler("anime", anime))
        app.run_polling()
    
    
    if __name__ == "__main__":
        main()
    terminal
    TELEGRAM_TOKEN="123456789:AA..." ANIMEAPI_KEY="ank_..." python bot.py
  3. Or Node: Telegraf

    terminal
    mkdir anime-telegram && cd anime-telegram
    npm init -y && npm pkg set type=module
    npm install telegraf@4
    bot.mjs
    // bot.mjs · run: node --env-file=.env bot.mjs
    import { Telegraf } from "telegraf";
    
    const bot = new Telegraf(process.env.TELEGRAM_TOKEN);
    
    bot.command("anime", async (ctx) => {
      const prompt = ctx.payload.trim();
      if (!prompt) return ctx.reply("Usage: /anime a girl with a red umbrella at a rainy bus stop");
    
      await ctx.sendChatAction("upload_photo");
    
      const res = await fetch("https://animeapi.ai/api/generate", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.ANIMEAPI_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ prompt, model: "anime", allowNSFW: false }),
      });
      const data = await res.json();
      if (!res.ok) return ctx.reply(`Couldn't draw that (${res.status}): ${data.error}`);
    
      const image = Buffer.from(await (await fetch(data.image_url)).arrayBuffer());
      await ctx.replyWithPhoto({ source: image }, { caption: prompt.slice(0, 1024) });
    });
    
    bot.launch();
    process.once("SIGINT", () => bot.stop("SIGINT"));
    process.once("SIGTERM", () => bot.stop("SIGTERM"));
    .env
    TELEGRAM_TOKEN=123456789:AA...
    ANIMEAPI_KEY=ank_...
    terminal
    node --env-file=.env bot.mjs

→Notes

  • Async HTTP. The Python version uses httpx.AsyncClient. A blocking requests.post inside an async handler would freeze every other chat while one image renders.
  • Upload, don’t link. Both versions download the image and upload the bytes. Anime images are WebP, and Telegram converts an uploaded WebP into a normal photo.
  • SFW by default. Both send allowNSFW: false. The API default is true.
  • Want the ultra tiers? Change "model". Expect roughly 10–13 seconds on the ultra tiers; the chat action keeps the “sending photo…” indicator visible for a few seconds, so re-send it if you want it shown the whole time.