Callog

Alerts that know whoyou are.

Callog is a git-first routing layer for engineering notifications. Your CI already knows the build is red and who broke it. Slack has no idea, because that person commits from a personal email and the webhook only knows a channel name. Callog connects the two: the alert reaches the right place and actually tags the right human, in Slack or Telegram.

.github/workflows/e2e.yml
fe-alerts
callogapp14:02

e2e failed on main

3 tests failed. Author: @alice. Team @frontend.

Git-first

Routes, templates and teams are YAML in one config repo. Reviewed in PRs, validated in CI, applied on push. A broken config never goes live.

Identity, not channels

A GitHub login on a personal email, a Slack user and a Telegram account are one person. Mention the commit author and they get pinged where they actually read.

No secrets in repos

GitHub Actions authenticate with OIDC. Services use scoped API keys. Not a single webhook URL in any repository.

Before and after

The same failing test, before and after

frontend
bo
Bob14:21

did e2e pass on main? the deploy is waiting

da
Dana14:33

no idea, let me open the Actions tab… still running I think

bo
Bob14:40

it's red. @here anyone know whose commit that was?

da
Dana15:07

we really need to set up test notifications at some point

fe-alerts
callogapp14:02

e2e failed on main

3 tests failed. Author: @alice. Team @frontend.

al
Alice14:04

on it, fix is up in 10 min

callogapp14:19

e2e passed on main

Fixed by @alice in 2 commits.(edited)

How it works

Three parts. One pull request to change any of them.

  1. Producer

    CI sends one event

    Add the Action to the workflow, name a route, pass the data. No webhook URL, no secrets: GitHub OIDC proves which repository is calling.

  2. Config repo

    The config repo says where it goes

    Each route is a YAML file: destinations, who is allowed to send, a schema for the payload and a template. Teams are channels plus members from a GitHub team or Slack user group.

  3. Delivery

    The right people get tagged

    Recipients are matched to real Slack and Telegram accounts, the message is rendered for each app, replies land in the same thread and failed sends are retried.

routes/e2e-failed.yaml
id: e2e-failed
allowed_sources:
  github_repos: [acme/fe-e2e]
destinations:
  - slack: "#fe-alerts"
  - telegram: fe-alerts
  - team: frontend
mentions: recipients
template:
  - header: "e2e failed on {{ data.branch }}"
  - text: "{{ data.failed }} tests failed. Author: {{ recipients | mention }}"
  - buttons:
      - { text: "Open run", url: "{{ data.run_url }}" }
teams.yaml
teams:
  frontend:
    slack_channel: "#fe-team"
    members_from:
      github_team: frontend
      slack_usergroup: frontend

Features

Everything a real pipeline needed

Each of these exists because a failing build at a 100-engineer company needed it.

  • Mentions that reach peopleGitHub author β†’ Slack or Telegram
  • Zero secrets in reposGitHub OIDC instead of webhook URLs
  • One PR to change anythingroutes, channels, templates in git
  • Preview in the pull requestsee the message before merge
  • CI validationbroken config never ships
  • Threads by keysame key, same thread
  • Edit in placeno channel spam on retries
  • Teams from existing groupsGitHub teams, Slack user groups
  • Delivery logstatus, retries, payload
  • Unmapped reportsee who still needs linking
  • Mute a routeper person, no admin needed
  • Pick your DM channelSlack or Telegram, your call
  • Slack and Telegramchannels, groups and DMs
  • Idempotent by defaultretries never duplicate
  • Liquid templatespayload data always escaped
  • Scoped API keysfor services outside CI
  • Last-known-good configa bad push changes nothing
  • One container + Postgresself-host in five minutes

The hard part

Three accounts. One person.

A GitHub login on a personal email, a Slack user and a Telegram account are linked into one person automatically. Only verified or high-confidence links are used for mentions and DMs.

alice-codesGitHub Β· personal emailalice@acme.devSlack Β· work email@alice_tgTelegramAlice Novakone person, mentioned everywhere
SourceProviderConfidence
Slack workspace syncslack, emailverified
GitHub org verified-domain emailsgithubverified
Commit heuristic, 3+ commits from a work emailgithubhigh
OAuth through the botgithubverified
Deep link from a Slack DMtelegramverified
Weak signal or conflictanysuggested

Alternatives

Where it sits

Knock / NovuPagerDutyslack-github-actionCallog
FocusProduct notifications to end usersOn-call and incidentsPost to a channelInternal engineering alerts
GitHub ↔ Slack ↔ Telegram identityβ€”Partialβ€”Core of the product
Address a team or a personβ€”Yesβ€”Yes
Git-first configβ€”β€”Per repositoryCentralized, reviewed in PRs
Cost for a 20-person teamHighHighFree, primitiveFree, self-hosted

Pricing

Free where it matters

The code is the same in both editions. Self-host it today, or let us run it when the hosted version opens.

Cloud
Soonfree up to 8 people

Install the GitHub App, add to Slack, send your first alert. Then pay per active person.

  • EU hosting, managed Postgres
  • Shared GitHub and Slack Apps, no setup
  • Onboarding wizard
  • Billing per active person above 8

Delete your last webhook URL

Clone the repo, create a GitHub App, run docker compose. Your first alert with a real mention lands in about five minutes.

git clone https://github.com/callog-dev/callog && cd callog
cp .env.example .env
docker compose --profile db --profile app up -d --build
curl http://localhost:3000/readyz