The problem with Grafana's native Telegram integration
Grafana has a built-in Telegram contact point. But to use it you need to:
- Create a Telegram bot via @BotFather and generate a token
- Find your Telegram chat ID (send a message and hit the API to retrieve it)
- Paste both into Grafana
- Repeat for every team member who wants alerts
It works, but it's four steps of friction before you see a single notification. And if you want to fan out to Slack or Discord as well, you're setting up separate integrations for each platform.
PingHook reduces this to one step. You get a webhook URL from the bot. Paste it into Grafana. Done.
Prerequisites
- Grafana with unified alerting (version 8.x or later)
- A Telegram account
- About 30 seconds
Step 1 โ Get your PingHook URL
Open Telegram and message @PingHookBot. Send /start. The bot replies with your unique webhook URL instantly โ no email, no password, no signup.
Step 2 โ Add a Webhook contact point in Grafana
- Go to Alerting โ Contact points โ New contact point
- Set the type to Webhook
- Paste your URL with a label and a filter:
The ?if=status:eq:firing filter is the critical part. Grafana sends a webhook for both firing and resolved events โ without this, you get notified every time an alert recovers too. The filter keeps only what's actionable.
- Click Test โ Grafana sends a sample payload and you'll see a message in Telegram within seconds
- Save the contact point and assign it to a notification policy
What the notification looks like
Grafana sends a structured JSON payload. PingHook auto-formats it as a readable code block in Telegram:
Advanced: filtering and routing
Only prod alerts
Chain multiple ?if= params โ all must pass (AND logic):
Suppress alert storms
Add ?dedup=10 to suppress the same alert for 10 minutes โ so a flapping service doesn't flood your chat:
Route critical alerts to Telegram, others to Slack
Create two contact points in Grafana โ each pointing to a different PingHook URL with a ?channel= param:
Both URLs share the same API key. The ?channel= param handles the routing โ your other channels stay connected and unaffected.
Fan out to Slack and Discord at once
Connect additional channels in the Telegram bot โ then every Grafana alert lands everywhere simultaneously:
Troubleshooting
Test ping works, real alerts don't appear. Check your notification policy โ the contact point needs to be in the routing tree. Run /history in the bot to see if pings are arriving but being suppressed.
Still getting "resolved" notifications. Confirm ?if=status:eq:firing is in the URL. Without it, PingHook delivers both firing and resolved events.
Alert storm flooding your chat. Add ?dedup=N (minutes). The first alert comes through; subsequent ones with the same label are suppressed until the window expires.
Want to inspect what Grafana is actually sending. Use ?silent=1 temporarily โ pings are logged but not delivered. Then check /history in the bot to see the raw payload.
Summary
Four steps from zero to notified:
- Get your URL from @PingHookBot via
/start - Add a Webhook contact point in Grafana with
?if=status:eq:firingappended - Assign it to a notification policy
- Fire a test alert โ message lands in Telegram within a second
Try it in 30 seconds
Open the bot, send /start, get your URL. No account, no email, no config.
Open @PingHookBot in Telegram โ