Skip to content
Back to skills

Telegram Inline Button Promote

ASecurity

Wire up a Telegram inline keyboard button in a polling bot — add button to outbound notification, subscribe to callback_query updates, answer the callback, and collapse a multi-step confirm flow into a single button press.

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 1, 2026
ai-agentspythonshellapi

Works with

  • api

Security analysis

A100/100

Scanned October 1, 2026

npx -y skills add williamblair333/Uncle-J-s-Refinery --skill telegram-inline-button-promote --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Telegram Inline Button Promote?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Telegram Inline Button Promote
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/williamblair333-telegram-inline-button-promote/badge)](https://www.skillsdirectory.com/skills/williamblair333-telegram-inline-button-promote)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: telegram-inline-button-promote
description: Wire up a Telegram inline keyboard button in a polling bot — add button to outbound notification, subscribe to callback_query updates, answer the callback, and collapse a multi-step confirm flow into a single button press.
---

## When to use

Use this skill when you want to replace a multi-step Telegram text command (e.g. `promote <id>` → `promote <id> global`) with a single inline button press baked into the outbound notification itself.

Applies to projects that:
- Send Telegram notifications via a shell/Python notify lib
- Run a polling bot that reads `getUpdates` in a loop
- Currently use a two-step confirm flow for a privileged action

## Prerequisites

- The notify lib must expose a function that accepts a `reply_markup` / inline keyboard argument (e.g. `notify_send_pitch` vs the simpler `notify_send_text`).
- The polling bot must be editable Python or shell.

## Key steps

### 1. Check memory and notify lib first
.venv-memweave/bin/python scripts/memweave/mw_search.py "<feature area> promote flow" --k 5
# Then read lib/notify.sh (or equivalent) to find the pitch/button function

### 2. Add the inline button to the outbound notification

Replace the plain-text send call with the one that accepts `reply_markup`:
# Before
notify_send_text(chat_id, text)

# After — inline_keyboard is a list-of-rows, each row a list of buttons
reply_markup = {
    "inline_keyboard": [[
        {"text": "✅ Promote Global", "callback_data": f"promote_global:{item_id}"}
    ]]
}
notify_send_pitch(chat_id, text, reply_markup=reply_markup)

### 3. Subscribe the polling bot to callback_query updates

In `getUpdates`, add `callback_query` to `allowed_updates`:
params = {
    "offset": offset,
    "timeout": 30,
    "allowed_updates": ["message", "callback_query"],   # <-- add this
}

### 4. Add answer_callback_query helper (above the loop)

Place this before the update loop so it's in scope:
def answer_callback(callback_id, text=""):
    requests.post(f"{API}/answerCallbackQuery", json={
        "callback_query_id": callback_id,
        "text": text,
    })

Always call this to dismiss the loading spinner on the button.

### 5. Handle callback_query at the top of the update loop

for update in updates:
    # Callback queries come in before messages — handle first
    if "callback_query" in update:
        cq = update["callback_query"]
        data = cq.get("data", "")
        answer_callback(cq["id"])

        if data.startswith("promote_global:"):
            item_id = data.split(":", 1)[1]
            do_promote_global(item_id)          # direct action, no confirm step
        continue

    msg = update.get("message", {})
    # ... rest of message handler

### 6. Remove the old multi-step text-command confirm block

Delete (or simplify) the code that was waiting for a second `promote <id> global` message. The inline button encodes the full intent in `callback_data`, so no confirm round-trip is needed.

### 7. Move shared helpers above the loop

Any helper functions referenced by both the callback handler and the message handler (e.g. `find_draft`, `install_skill`) must be defined above the update loop, not inside a branch of it.

## Sanity checks after editing

python3 -c "import ast, sys; ast.parse(open('scripts/your-bot.py').read()); print('OK')"
# Verify no stale references to removed variables
grep -n "old_var_name" scripts/your-bot.py

## Common pitfalls

- Forgetting to call `answer_callback_query` — the button stays in "loading" state forever.
- Defining helpers inside the loop — they shadow or error on the second iteration.
- Not adding `callback_query` to `allowed_updates` — Telegram silently drops them.
- Reusing a variable name from the old two-step flow in the new single-step handler.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.