That's when I moved my alerts to Telegram. Telegram messages bypass most "do not disturb" settings, the notification sound is customizable, and I can forward signals to a private group where my trading journal bot also logs entries.
Setting this up took me about 20 minutes. Here's exactly how to do it.
What You Need Before Starting
- A TradingView account on Essential plan or higher (webhooks are not available on the free plan)
- A Telegram account
- About 20 minutes
Step 1: Create Your Telegram Bot With BotFather
Every Telegram bot starts with BotFather — Telegram's official bot that creates other bots.
1. Open Telegram and search for @BotFather
2. Send the command/newbot
3. BotFather asks for a display name — I named mine TV Alerts
4. BotFather asks for a username — it must end in bot (e.g., my_tv_alerts_bot)
5. BotFather gives you an HTTP API token — copy it and store it somewhere safe
The token looks like this: 7123456789:AAHk3gJdKfZ8x9bWcDeFgHiJkLmNoPqRsT
Step 2: Get Your Telegram Chat ID
Your bot needs to know *where* to send messages. That means getting the numeric chat ID for your personal chat, group, or channel.
For Personal Messages
1. Start a conversation with your new bot — search for its username and press Start
2. Send any message to the bot (like "hello") 3. Open this URL in your browser, replacingYOUR_BOT_TOKEN with your actual token:
https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates
4. Look for "chat":{"id":123456789} — that number is your chat ID
For a Group Chat
1. Add your bot to the group
2. Send a message in the group that mentions the bot 3. Hit the samegetUpdates URL — the chat ID for groups is negative (e.g., -1001234567890)
For a Channel
1. Add the bot as an administrator to your channel
2. Post something in the channel 3. CheckgetUpdates — the channel chat ID is also negative
I use a private group with two members: me and the bot. This way I have a searchable log of every alert, and I can add my spouse or trading partner later without reconfiguring anything.
Step 3: Choose Your Relay Method
Here's the thing TradingView's webhook documentation doesn't make obvious: TradingView webhooks send HTTP POST requests to a URL you specify, but you can't just paste the Telegram API URL directly because TradingView sends the alert message as raw text in the request body, not as a properly formatted Telegram API call.
You need a lightweight relay — something that receives the webhook from TradingView and forwards it to Telegram's sendMessage endpoint.
Here are three options, ranked by simplicity:
Option A: TradingFinder's Free Relay (Easiest — No Code)
TradingFinder built a free relay service specifically for this use case. The TradingView community has a popular indicator called "TradingView Telegram Webhook Alert" by TFlab that generates the webhook URL for you.
1. Go to TradingView → Indicators → search "TradingView Telegram Webhook Alert TFlab"
2. Add it to your chart 3. In the indicator settings, paste your bot token and chat ID 4. The indicator generates a webhook URL — copy itThe downside: you're routing your alerts through a third-party server. For price alerts and signal notifications, this is fine. For sending actual trade execution commands, I'd self-host.
Option B: Cloudflare Workers (Free, 5 Minutes, Your Own Relay)
This is what I use. Cloudflare Workers gives you 100,000 free requests per day — more than enough for trading alerts.
Create a file called worker.js:
export default {
async fetch(request, env) {
if (request.method !== "POST") {
return new Response("Send a POST request", { status: 405 });
}
const body = await request.text();
// Parse the incoming message
// TradingView sends the alert message as plain text in the body
const message = body.trim();
if (!message) {
return new Response("Empty message", { status: 400 });
}
// Forward to Telegram
const telegramUrl = `https://api.telegram.org/bot${env.BOT_TOKEN}/sendMessage`;
const response = await fetch(telegramUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
chat_id: env.CHAT_ID,
text: message,
parse_mode: "HTML"
})
});
if (response.ok) {
return new Response("Sent", { status: 200 });
} else {
const error = await response.text();
return new Response(`Telegram error: ${error}`, { status: 502 });
}
}
};
Deploy it:
npx wrangler init tv-telegram-relay
# Replace the generated worker.js with the code above
npx wrangler secret put BOT_TOKEN
# Paste your bot token when prompted
npx wrangler secret put CHAT_ID
# Paste your chat ID when prompted
npx wrangler deploy
Your relay URL will be something like https://tv-telegram-relay.your-subdomain.workers.dev — use this as the webhook URL in TradingView.
Option C: Google Apps Script (Free, No Terminal Needed)
If you don't have a Cloudflare account and want something browser-only:
1. Go to script.google.com
2. Create a new project 3. Paste this code:
function doPost(e) {
const BOT_TOKEN = "YOUR_BOT_TOKEN";
const CHAT_ID = "YOUR_CHAT_ID";
const message = e.postData.contents;
const url = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json",
payload: JSON.stringify({
chat_id: CHAT_ID,
text: message,
parse_mode: "HTML"
})
});
return ContentService.createTextOutput("OK");
}
4. Deploy → New Deployment → Web app → Execute as "Me" → Access "Anyone"
5. Copy the deployment URL Downsides: Google Apps Script has cold-start latency (1-3 seconds), and the free tier has daily quota limits. For a handful of alerts per day, it works. For high-frequency signals, use Cloudflare Workers.Step 4: Configure the TradingView Alert
Now the fun part — connecting TradingView to your relay.
1. Open your chart on TradingView
2. Right-click on an indicator or price level → Add Alert (or pressAlt+A)
3. Set your condition (price crossing a level, indicator signal, Pine Script alertcondition, etc.)
4. Under Notifications, check Webhook URL
5. Paste your relay URL
6. In the Message field, type your alert message
Basic Alert Message
🔔 USDJPY Alert
Price crossed above 150.000
Time: {{timenow}}
Advanced Alert With Dynamic Placeholders
TradingView supports built-in placeholders that get replaced when the alert fires:
Like what you're reading? Try it yourself — this link supports ChartedTrader at no cost to you.
Try TradingView — Get Up to $30 Off Your First Plan →
📊 <b>{{ticker}}</b> Alert
Action: {{strategy.order.action}}
Price: {{close}}
Time: {{timenow}}
Exchange: {{exchange}}
Interval: {{interval}}
Here's my actual alert message template for USDJPY momentum signals:
🚀 <b>Signal: {{ticker}}</b>
Direction: {{strategy.order.action}}
Entry Price: {{close}}
Timeframe: {{interval}}
Time: {{timenow}}
Strategy: Momentum Crossover
The tags work because our relay sends messages with parse_mode: "HTML" — Telegram renders them as bold text.
Available TradingView Placeholders
| Placeholder | What It Returns | Example |
|---|---|---|
{{ticker}} | Symbol name | USDJPY |
{{exchange}} | Exchange name | OANDA |
{{close}} | Current close price | 149.523 |
{{open}} | Current open price | 149.410 |
{{high}} | Current high | 149.680 |
{{low}} | Current low | 149.320 |
{{volume}} | Current volume | 58234 |
{{time}} | Bar time (UTC) | 2026-03-21T14:00:00Z |
{{timenow}} | Alert trigger time | 2026-03-21T14:32:15Z |
{{interval}} | Chart timeframe | 60 (for 1H) |
{{strategy.order.action}} | Buy or sell | buy |
{{strategy.order.price}} | Order fill price | 149.523 |
{{strategy.position_size}} | Position size | 1000 |
{{strategy.market_position}} | Long/short/flat | long |
{{strategy.prev_market_position}} | Previous position | flat |
Step 5: Test the Complete Pipeline
Before trusting this with real trading signals:
1. Create a test alert on any chart — set the condition to trigger immediately (like "price crossing" a level that's already passed)
2. Wait for TradingView to fire the webhook 3. Check your Telegram — the message should appear within 1-5 secondsIf it doesn't arrive:
- Check the webhook URL — make sure there's no trailing space or newline
- Verify the bot token — try calling
https://api.telegram.org/botYOUR_TOKEN/getMein your browser. You should see your bot's info - Confirm the chat ID — send a message to the bot again and re-check
getUpdates - Check relay logs — in Cloudflare Workers, go to Workers → your worker → Logs → Real-time. You'll see every incoming request and any errors
Real-World Setup: Multi-Alert Trading Dashboard
Once the basic pipeline works, you can get creative. Here's my setup:
Separate Channels for Different Signal Types
I run three Telegram groups, each with its own bot relay:
- 📈 Entry Signals — only fires when my momentum strategy generates a buy/sell signal
- ⚠️ Risk Alerts — fires on unusual volatility, drawdown thresholds, or position size warnings
- 📋 Daily Summary — fires once per day with a strategy performance snapshot
Formatted Trade Card
Here's the template I use for entry signals — it creates a clean, scannable card in Telegram:
🟢 <b>LONG Signal</b>
Pair: <b>{{ticker}}</b>
Entry: {{close}}
Timeframe: {{interval}} min
📊 Momentum Score: see chart
⏰ {{timenow}}
<i>Auto-generated by TradingView Webhook</i>
Adding Emoji for Quick Visual Scanning
I use {{strategy.order.action}} to control the emoji prefix in my Cloudflare Worker:
// In your worker.js, before sending to Telegram:
let formattedMessage = message;
if (message.toLowerCase().includes("buy")) {
formattedMessage = "🟢 " + formattedMessage;
} else if (message.toLowerCase().includes("sell")) {
formattedMessage = "🔴 " + formattedMessage;
}
This makes it obvious at a glance whether you're looking at a long or short signal when you check your phone.
Webhook Alerts With Pine Script
If you write your own indicators, you can trigger alerts from Pine Script using alertcondition() or the newer alert() function:
//@version=6
indicator("Momentum Alert Example", overlay=true)
// Simple momentum crossover
fastMA = ta.sma(close, 10)
slowMA = ta.sma(close, 50)
bullishCross = ta.crossover(fastMA, slowMA)
bearishCross = ta.crossunder(fastMA, slowMA)
// Method 1: alertcondition (older, works with manual alert setup)
alertcondition(bullishCross, "Bullish Crossover", "🟢 BUY Signal on {{ticker}} at {{close}}")
alertcondition(bearishCross, "Bearish Crossover", "🔴 SELL Signal on {{ticker}} at {{close}}")
// Method 2: alert() function (newer, fires automatically from strategy)
if bullishCross
alert("🟢 BUY Signal on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if bearishCross
alert("🔴 SELL Signal on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
Key difference: alertcondition() requires you to manually create an alert on the chart and select the condition. alert() fires automatically when the script runs — just set up one alert with "Any alert() function call" as the condition and your webhook URL. The alert() approach is cleaner for strategies with multiple signal types.
Troubleshooting Common Issues
Alert Fires But Telegram Message Never Arrives
1. Check your relay's logs. If TradingView successfully sent the webhook but Telegram rejected it, you'll see the error
2. Most common cause: bot token expired or was regenerated. Go back to BotFather →/mytoken to check
3. Second most common: chat ID changed because you recreated the group. Re-fetch it from getUpdates
Messages Arrive With Delay (30+ Seconds)
- If using Google Apps Script, cold starts cause 2-5 second delays. Switch to Cloudflare Workers for consistent sub-second delivery
- If using Cloudflare Workers and still seeing delays, the issue is likely on TradingView's side — webhook delivery isn't instant, especially during high-volume market events. Typical latency is 1-10 seconds
Telegram Shows "Bad Request: can't parse entities"
Your HTML formatting has an error. Common mistakes:
- Unclosed
tags — everyneeds a - Using
for line breaks — Telegram HTML doesn't support. Just use actual newlines in your message - Using unsupported tags — Telegram only supports:
,,,,,,
parse_mode from "HTML" to "Markdown" or remove formatting entirely to debug.
Alert Fires Multiple Times
Check your alert settings in TradingView:
- Once Per Bar Close — fires once when the bar closes. Best for strategies
- Once Per Bar — fires once when the condition first becomes true within a bar. Can re-fire if the condition flips
- Every Time Condition Is Met — fires on every tick where the condition is true. This will spam your Telegram
Cost Breakdown
| Component | Cost | Notes |
|---|---|---|
| TradingView Essential | $12.95/mo | Minimum plan for webhooks (get a discount here) |
| Telegram Bot | Free | No limits on messages |
| Cloudflare Workers | Free | 100K requests/day on free tier |
| Total | $12.95/mo | Or less with annual billing |
What Comes Next: From Alerts to Automation
Getting alerts on Telegram is step one. The natural next step is acting on those alerts automatically:
- Manual but fast: See the Telegram alert → open your exchange → execute the trade. This is what most traders do, and it works if you're not running a high-frequency strategy
- Semi-automated: Use TradingView's built-in broker integration to connect directly to OKX or Interactive Brokers for one-click execution from the chart
- Fully automated: Route TradingView webhooks to your exchange's API instead of (or in addition to) Telegram. We covered this in our OKX Signal Bot setup guide
FAQ
Can I use webhooks on the TradingView free plan?
No. Webhooks require the Essential plan or higher. The free plan supports email, push notifications, and pop-up alerts — but not webhooks. Check current TradingView pricing here.
Is there a limit on how many webhook alerts I can have?
Yes, but it's generous. Essential allows 20 active alerts, Plus allows 100, Premium allows 400, and Expert/Ultimate allow more. Each alert can have a webhook attached.
Can I send alerts to multiple Telegram groups?
Not directly from one TradingView alert — each alert has one webhook URL. But you can modify your relay to forward to multiple chat IDs:
const chatIds = [env.CHAT_ID_1, env.CHAT_ID_2, env.CHAT_ID_3];
await Promise.all(chatIds.map(chatId =>
fetch(telegramUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ chat_id: chatId, text: message, parse_mode: "HTML" })
})
));
Will this work for crypto, stocks, and forex?
Yes. TradingView webhooks fire for any instrument — crypto, forex, stocks, futures, indices. The alert is tied to the chart and condition, not the asset class.
How reliable is this? Will I miss signals?
In 6+ months of running this setup with Cloudflare Workers, I've had zero missed alerts. TradingView's webhook delivery is reliable, and Cloudflare Workers has 99.99% uptime. The only scenario where you'd miss a signal is if TradingView itself has an outage, which is rare.
That said, don't rely on *any* single notification method for critical trading decisions. I keep TradingView push notifications enabled as a backup alongside Telegram.
---
*Disclosure: This article contains affiliate links to TradingView. I use TradingView daily for chart analysis and alert management. If you sign up through my link, I may earn a commission at no extra cost to you.*