Skip to content

Repository files navigation

makeitMD

Send Markdown. Get native Telegram rich text.
A deliberately small Go bot built directly on Telegram Bot API 10.1.

latest version stable version Go version Apache-2.0 license Telegram bot

Quick Start · Usage · How It Works · Operations · Configuration


The Idea

Telegram Bot API 10.1 can render structured Rich Markdown natively. makeitMD keeps the product boundary as small as possible: send source text in a private chat and receive Telegram's native rendering immediately.

Principle makeitMD approach
Exact input Passes the submitted string unchanged as rich_message.markdown
Native rendering Uses Telegram sendRichMessage, not a custom parser
Minimal interaction /start only, one panel: two tabs and the language, no settings
Private operations Statistics and source audit stay operator-only
Direct integration Calls the Bot API over HTTP without a Telegram library

Result: one text in, one native rich message out.

Status

Channel Version Meaning
Stable v0.1.0 First public release
Production v0.1.0 Runs as makeitmd-bot with healthy DB and Telegram polling

Quick Start

You need Go 1.26.5+, Docker, a Telegram token from BotFather, and access to the Asterfield shared core-postgres database.

cp .env.example .env
$EDITOR .env
docker compose up --build

Before the first start, apply core/migrations/003_makeitmd.sql, provision the makeitmd_core password, and ensure the external Docker network core_net exists.

Using makeitMD

  1. Open @makeitMD_bot.
  2. Send /start.
  3. Send Markdown source text.
  4. Receive the native Telegram Rich Markdown message.

The greeting is intentionally short:

Send me Markdown. I’ll render it.

/start also opens the panel: How it works, About — the running version, the rendering the bot uses, the repository, the licence and the admin — and Language. Back returns to the greeting, and every screen edits the same message rather than adding another one. There is nothing else to configure, so there is no settings screen.

The panel speaks the sixteen languages the Asterfield bots share. It follows the language your Telegram client reports until you pick one, and the language you pick is stored once for the whole family: the other bots answer in it too. Follow Telegram on that screen hands the decision back to your client.

Everything else the bot says is a rendered message. In a group makeitMD renders nothing: /start there is registered as an ephemeral command, so the answer — a link back to the private chat — is visible only to the person who sent it.

Rich Markdown supports headings, nested styles, lists, task lists, tables, quotes, code blocks, details, links, formulas, and other structured content. Telegram currently limits one rich message to 32,768 UTF-8 characters.

How It Works

Telegram getUpdates
        |
        v
core.touch identity/presence
        |
        v
store exact source as received
        |
        v
sendRichMessage(markdown: exact source)
        |
        +--> sent   -> lifetime statistics
        +--> failed -> short syntax error

The durable Telegram offset advances only after handling an update. Replayed updates do not resend conversions already marked sent.

Shared Core Database

Global Telegram identity and presence live in core.person and core.presence. Private makeitMD data lives in the isolated makeitmd schema:

  • makeitmd.conversions — exact decoded source, raw input message and entities, every outbound Markdown/result attempt, final Telegram result, delivery state, character count, and byte count.
  • makeitmd.user_stats — lifetime per-user conversion totals independent of raw-text retention.
  • makeitmd.runtime_state — durable Telegram update offset.
  • makeitmd.schema_migrations — applied domain migration ledger.

Raw sent and failed conversions expire after 90 days by default. Unresolved received rows remain available for recovery. No statistics are shown to users.

Operations

  • GET /healthz checks PostgreSQL and Telegram polling freshness and returns version, commit, build date, and pending/failed conversion counts.
  • GET /metrics exposes private-data-free Prometheus counters.
  • Docker marks the container unhealthy when /healthz fails.
  • Telegram GET requests retry transport, 429, and 5xx failures with jitter.
  • POST requests retry only when Telegram explicitly returns retry_after, avoiding unsafe duplicate sends after an ambiguous transport failure.
  • Transport errors are sanitized before logging so the bot token cannot appear through an embedded Bot API URL.

Configuration

Variable Required Default Purpose
TELEGRAM_BOT_TOKEN yes Telegram Bot API token
DATABASE_URL yes makeitmd_core connection to shared core-postgres
AUTO_MIGRATE no true Apply makeitMD migrations on startup
MIGRATIONS_DIR no ./migrations SQL migration directory
HTTP_ADDR no :8080 Internal health and metrics listener
CONVERSION_RETENTION no 2160h Retention for terminal raw conversion rows
LOG_LEVEL no info Reserved log level
BUILD_VERSION no dev Version stamped into health and logs
BUILD_COMMIT no none Source revision
BUILD_DATE no unknown UTC build timestamp

Production

deploy/ws04/compose.yaml is the production stack. It pulls the image the release workflow published to GHCR and never builds one:

# in the stack directory, alongside .env
MAKEITMD_IMAGE=ghcr.io/freshlabdev/makeitmd@sha256:<digest> docker compose up -d

Pin MAKEITMD_IMAGE by digest rather than tag. A digest names one exact build, so a rollback is a one-line change with nothing to rebuild, and docker inspect on the running container answers which commit it came from. BUILD_VERSION / BUILD_COMMIT / BUILD_DATE are baked in by the release workflow; they only need setting for a local build.

Development

go mod verify
go test -race ./...
go vet ./...
govulncheck ./...
docker compose config
docker build -t makeitmd:local .

CI repeats module verification, build, race tests, vet, vulnerability scanning, Docker build, and Compose validation. See versioning, release process, and the full changelog.

License

Apache License 2.0. See LICENSE and NOTICE.

About

Minimal Telegram bot that renders Rich Markdown natively with Telegram Bot API 10.1. Built in Go with PostgreSQL-backed audit and statistics.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages