Skip to main content

Postak

Turn a Telegram channel into a personal AI chat list.

Start a chat with /new. Each post becomes a conversation title; its comment thread is the chat. Postak replies as you type and names the post after the first reply.

Postak channel with active conversations

Features

  • Channel as chat list — each /new post becomes an auto-titled conversation.
  • Rich streaming replies — rich Telegram messages: tables, checklists, ...
  • Per-thread memory — each conversation keeps its own context.
  • multi-channel support · Custom prompts · Commenter mentions · Scoped access · Thread tools · Pluggable models and storage

How it works

  1. Send /new in your channel — or in its discussion group — to start a conversation.
  2. Telegram forwards the post into its discussion group as a comment thread.
  3. Reply in the thread — Postak answers, streaming as it types.
  4. The first reply auto-titles the post, so your feed reads like a chat list.

Requirements

  • Python 3.10+
  • A Telegram bot (@BotFather) and a channel with a linked discussion group
  • An OpenAI-compatible LLM endpoint

Start in five minutes

  1. In Telegram, create a channel and enable comments by linking a discussion group. Add your bot as an admin of both.
  1. Configure and run:
uv sync
cp .env.example .env    # fill in BOT_TOKEN, TARGET_CHANNEL_ID, LLM_MODEL, …
uv run postak

# or, from PyPI:
#   pip install postak
#   postak    # reads .env from the current directory
  1. Send /new in your channel or discussion group, then reply in the new thread.

Configuration

Postak reads settings from the environment (via a .env file):

Variable Required Default Description
BOT_TOKEN ✔ — Telegram bot token from @BotFather
TARGET_CHANNEL_ID — Channel id(s) to serve, comma-separated (e.g. -1001234567890,-1009876543210). Leave empty and a Postak admin can add channels later — see Admin commands
LLM_MODEL ✔ — Model name, e.g. gpt-4o-mini
LLM_ENDPOINT OpenAI API Base URL of an OpenAI-compatible endpoint
LLM_API_KEY not-needed API key for the LLM endpoint
POSTAK_ADMINS — Comma-separated Telegram user ids who may manage Postak. Required if TARGET_CHANNEL_ID is empty, since that's the only way to add a channel
DATABASE_URL sqlite+aiosqlite:///postak.db Store URL: a SQLite path, or :memory:
HISTORY_WINDOW 20 Max recent messages kept as context (the system prompt is always kept)

Library usage

from aiogram import Bot, Dispatcher

from postak import OpenAIGenerator, Postak

postak = Postak(
    generator=OpenAIGenerator(model="gpt-4o-mini", api_key="..."),
    store="sqlite+aiosqlite:///postak.db",
    channels=[-1001234567890],
    admins=[123456789],
)

bot = Bot("telegram-token")
dp = Dispatcher()

postak.attach(dp)
dp.run_polling(bot)

Admin commands

Postak admins manage everything with /postak (/postak help lists it all):

Access

  • admin list — show admins · admin add|remove <user_id> — grant or revoke rights
  • access list — show all access rules
  • access allow|revoke <user_id> global|group|thread — per-user access
  • access public on|off global|group|thread — open or close a scope to everyone; a public/allowed group (or global scope) also lets non-admins run /new in an already-linked group, not just comment

Channels

  • add [chat_id] — link a channel, discovering its discussion group via Telegram; defaults to the chat you're in, or pass either side's id
  • remove [chat_id] — unlink it and drop that group's access rules

A Postak admin can skip add entirely: sending /new in a group Postak doesn't know yet links its channel and starts the conversation in one step.

In a thread

  • digest — summarize the conversation
  • compress — replace history with a compact summary
  • title — regenerate the post title · settitle <text> — set it yourself
  • regenerate — redo the last answer
  • delete — delete the message you replied to

Model

  • model get — show the current model · model set <model> — switch it

System prompt — targets the surrounding thread when run inside one, else the global default

  • sysprompt — show it · sysprompt <text> — set it · sysprompt delete — reset it
  • The global prompt applies to conversations opened after the change and is admin-only; a thread's prompt takes effect on its next reply and can also be managed by anyone allowed to chat in that thread

Development

uv sync
uv run python -m unittest discover -s tests
uv run ruff check .
uv run mypy postak

License

MIT

Metadata

Release files for postak 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for postak 0.1.0
File Size Uploaded Provenance Actions
postak-0.1.0.tar.gz 36.7 kB Without provenance Details for postak-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for postak 0.1.0
File Interpreter ABI Platform Actions
postak-0.1.0-py3-none-any.whl Python 3 none any Details for postak-0.1.0-py3-none-any.whl

Total release size: 69.7 kB

Release files / postak-0.1.0.tar.gz

Download URL postak-0.1.0.tar.gz
Size 36.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ec93cf804770c9c3b9fbd64b4b27da2c4d106c5912f4fe3be3b0530dd983dd3b
BLAKE2b-256 checksum
How to use checksums
c97d36f72d45a3d4eed08f104f0028fae4f0c4ad3fb000f5bce8a70b15225cd8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release files / postak-0.1.0-py3-none-any.whl

Download URL postak-0.1.0-py3-none-any.whl
Size 33.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fa0db1c08c585dea079bc3522a4d6c63d253313f7e1c37b05b762f171dc146b8
BLAKE2b-256 checksum
How to use checksums
0849afddde31717e1e233e05611dc883c8c2492f66fc7a6005aa266eed1f477b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Security for postak 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page