Skip to content

Telegram Community

MOSAIC has a Telegram presence with two connected spaces:

Purpose
Channel @mosaic_searchRead-only announcements: releases, CI events, weekly digest
Support Group @mosaic_search_supportInteractive support, questions, discussion

The channel and group are linked — every channel post gets a comments thread in the group.


For users

Joining

Support bot

The group has an automated support bot. It responds instantly to commands and common questions.

Commands

CommandWhat it returns
/helpList of all commands
/installInstallation instructions (pipx, pip)
/versionLatest release version from PyPI
/docsLink to the documentation
/sourcesAll 21 supported sources, grouped by auth requirement
/changelogLast 3 release notes from GitHub
/bugHow to file a bug report (links to GitHub issue template)
/roadmapOpen milestones and planned enhancements from GitHub

Commands work in the group and in private chat with the bot.

FAQ auto-reply

The bot also recognises common questions in plain text and replies automatically. Topics covered:

  • Installation (pipx, pip install)
  • API keys — which sources need them and how to get free ones
  • Proxy / firewall / timeout issues
  • Zotero integration
  • Obsidian integration
  • PDF download (--pdf, open-access)
  • Configuration (mosaic config --show)
  • Finding similar papers (mosaic similar)
  • Batch download from .bib / .csv files

Welcome message

New members receive an automatic welcome with install instructions and links.


For maintainers

This section documents the Telegram infrastructure so it can be understood, updated, and reproduced without exposing any credentials.

Overview

┌─────────────────────────┐     ┌──────────────────────────┐
│   GitHub Actions (CI)   │     │  Cloudflare Worker       │
│                         │     │  mosaic-bot              │
│  telegram-release.yml   │────▶│                          │
│  telegram-push.yml      │     │  Receives webhook from   │
│  telegram-pr.yml        │     │  Telegram instantly,     │
│  telegram-issues.yml    │     │  handles commands, FAQ,  │
│  telegram-weekly.yml    │     │  and welcome events      │
└─────────────────────────┘     └──────────────────────────┘
          │                                  ▲
          │ sendMessage                      │ POST (webhook)
          ▼                                  │
   ┌─────────────┐                   ┌───────────────┐
   │  @mosaic    │◀── linked ───────▶│ @mosaic       │
   │  _channel   │                   │ _support      │
   └─────────────┘                   └───────────────┘

Channel notifications (CI-driven)

Five GitHub Actions workflows send messages to the channel automatically:

WorkflowTriggerWhat it sends
telegram-release.ymlGitHub Release publishedRelease announcement with version, changelog excerpt, PyPI and docs links
telegram-push.ymlPush to mainCommit list with authors and diff link
telegram-pr.ymlPR opened / closed / mergedPR title, status, and link
telegram-issues.ymlIssue opened / closed / reopenedIssue title, excerpt, and link
telegram-weekly.ymlEvery Monday 08:00 UTCWeekly digest: commits, merged PRs, issue stats

All five use only Python stdlib (urllib, json) — no external dependencies. The bot token and channel ID are read from GitHub secrets at runtime.

Support bot (webhook-driven)

The support bot lives in bot/worker.js and runs on Cloudflare Workers.

Architecture

User sends message in @mosaic_search_support


Telegram servers POST the update to the Worker URL


Worker verifies X-Telegram-Bot-Api-Secret-Token header
        │  (rejects with 401 if token doesn't match)

Worker returns 200 OK immediately

        ▼  (ctx.waitUntil — background)
Worker processes the update:
  • Command? → call the appropriate handler
  • Plain text in a group? → check FAQ keyword list
  • new_chat_members event? → send welcome message


Worker calls Telegram sendMessage API → reply appears instantly

Files

FilePurpose
bot/worker.jsCloudflare Worker — all bot logic (commands, FAQ, welcome)
bot/bot.pyEquivalent Python script — reference implementation and polling fallback
wrangler.tomlCloudflare Worker configuration (entry point, name, compatibility date)
.github/workflows/deploy-worker.ymlCI workflow — deploys the worker and re-registers the Telegram webhook

Deploy workflow

The deploy workflow (deploy-worker.yml) fires on:

  • Push to main when bot/worker.js, wrangler.toml, or the workflow file itself changes
  • Manual workflow_dispatch

Steps:

  1. Checkout the repo
  2. npm install -g wrangler
  3. wrangler deploy — uploads bot/worker.js to Cloudflare
  4. wrangler secret put — pushes TELEGRAM_BOT_TOKEN and WEBHOOK_SECRET into the Worker environment
  5. Python script calls setWebhook to register the Worker URL with Telegram

Required secrets and variables

Stored in GitHub → Settings → Secrets and variables → Actions. No credentials are stored in the repository.

Secrets:

NameDescription
TELEGRAM_BOT_TOKENBot token from @BotFather — shared by channel workflows and the Worker
TELEGRAM_CHANNEL_IDNumeric channel ID used by the five channel notification workflows
CF_API_TOKENCloudflare API token with Workers Scripts: Edit permission
CF_ACCOUNT_IDCloudflare account ID — prevents wrangler from calling /memberships
WEBHOOK_SECRETArbitrary random string; set on setWebhook and verified by the Worker

Variables:

NameDescription
CF_WORKER_URLDeployed Worker URL (e.g. https://mosaic-bot.<account>.workers.dev) — set after first deploy

Updating the bot

To add a command, change an FAQ reply, or modify the welcome message:

  1. Edit bot/worker.js
  2. Commit and push to main
  3. The deploy workflow fires automatically — the new version is live in under a minute

Re-registering the webhook

The webhook is re-registered automatically on every deploy. To force re-registration without changing bot logic, run the deploy workflow manually via Actions → Deploy Telegram Bot Worker → Run workflow.

Security notes

  • The Worker rejects all requests that do not carry the correct X-Telegram-Bot-Api-Secret-Token header — only Telegram servers can trigger it
  • WEBHOOK_SECRET and TELEGRAM_BOT_TOKEN are stored as Cloudflare Worker secrets (encrypted at rest, never exposed in logs)
  • No credentials appear in wrangler.toml or any tracked file
  • The CF_API_TOKEN has the minimum required scope (Workers Scripts: Edit); it cannot read DNS, billing, or other account data

Fallback: polling mode

bot/bot.py is a pure-Python (stdlib only) equivalent of the worker. It uses getUpdates polling instead of webhooks. To switch back to polling mode:

  1. Call deleteWebhook to deregister the current webhook
  2. Run bot/bot.py on any machine with TELEGRAM_BOT_TOKEN set
  3. Or restore the telegram-bot.yml workflow (see git history) for scheduled polling via GitHub Actions