diff --git a/README.md b/README.md index 9bc2504..30b88ac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

+

Python version @@ -34,23 +34,29 @@ All alerts can be instantly sent to Telegram, Discord, Twitter and/or Email. - Twitter Support using the [tweepy](https://github.com/tweepy/tweepy) libary - Email Support using [smtplib](https://docs.python.org/3/library/smtplib.html) - Alert channels can be enabled or disabled in [`config.py`](https://github.com/vsnz/TradingView-Webhook-Bot/blob/master/config.py) -- Whitelisted words can be easily added in [`config.py`](https://github.com/vsnz/TradingView-Webhook-Bot/blob/master/config.py) +- Dynamically send alerts to different Telegram and/or Discord channels - TradingView `{{close}}`, `{{exchange}}` etc. variables support. Read more [here](https://www.tradingview.com/blog/en/introducing-variables-in-alerts-14880/) > 💡 Got a feature idea? Open an [issue](https://github.com/vsnz/TradingView-Webhook-Bot/issues/new) and I might implement it. ## Installation -> ⚠️ Best to run the bot on a VPS. I can recommend [Hetzner](https://hetzner.cloud/?ref=tQ1NdT8zbfNY). +> ⚠️ Best to run the bot on a VPS. I can recommend Hetzner's CX11 VPS for 2.89€/month. 1. Clone this repository `git clone https://github.com/vsnz/TradingView-Webhook-Bot.git` 1. Create your virtual environment `python3 -m venv TradingView-Webhook-Bot` 1. Activate it `source TradingView-Webhook-Bot/bin/activate && cd TradingView-Webhook-Bot` 1. Install all requirements `pip install -r requirements.txt` 1. Edit and update [`config.py`](https://github.com/vsnz/TradingView-Webhook-Bot/blob/master/config.py) -1. Setup TradingView alerts as shown [here](https://i.imgur.com/71UYTcu.png) - - TradingViews variables like `{{close}}`, `{{exchange}}` etc. work as well. More can be found [here](https://www.tradingview.com/blog/en/introducing-variables-in-alerts-14880/) +1. Setup TradingView alerts. An example alert message would be: + ``` + {"key": "9T2q394M92", "telegram": "-1001277977502", "discord": "789842341870960670/BFeBBrCt-w2Z9RJ2wlH6TWUjM5bJuC29aJaJ5OQv9sE6zCKY_AlOxxFwRURkgEl852s3", "msg": "Long #{{ticker}} at `{{close}}`"} + ``` + - `key` is mandatory! It has to match with `sec_key` in [`config.py`](https://github.com/vsnz/TradingView-Webhook-Bot/blob/master/config.py). It's an extra security measurement to ensure nobody else is executing your alerts + - `telegram` and `discord` is optional. If it is not set it will fall back to the config.py settings + - `msg` can be anything. Markdown for [Telegram](https://core.telegram.org/api/entities) and [Discord](https://support.discord.com/hc/en-us/articles/210298617-Markdown-Text-101-Chat-Formatting-Bold-Italic-Underline-) is supported as well + - TradingViews variables like `{{close}}`, `{{exchange}}` etc. work too. More can be found [here](https://www.tradingview.com/blog/en/introducing-variables-in-alerts-14880/) - Your webhook url would be `http:///webhook` -1. If you use a firewall be sure to open port the corresponding port -1. Run the bot `python main.py` +1. If you use a firewall be sure to open the corresponding port +1. Run the bot with `python main.py` *It is recommended to run flask on a different port like 8080. It is then necessary to forward port 80 to 8080.* diff --git a/config.py b/config.py index 341d72c..c0fe2ff 100644 --- a/config.py +++ b/config.py @@ -4,13 +4,10 @@ # File Name : config.py # # ----------------------------------------------- # -# Alert message in TradingView (ex. https://i.imgur.com/RFkuf1d.png) -# !! Case insensitive !! -whitelisted = [ - 'buy alert', 'sell alert' - ] +# TradingView Example Alert Message: +# {"key": "9T2q394M92", "telegram": "-1001298977502", "discord": "789842349670960670/BFeBBrCt-w2Z9RJ2wlH6TWUjM5bJuC29aJaJ5OQv9sE6zCKY_AlOxxFwRURkgEl852s3","msg": "Long #{{ticker}} at `{{close}}`"} -sec_code = '' +sec_key = '' # Can be anything. Has to match with "key" in your TradingView alert message # Telegram Settings send_telegram_alerts = False diff --git a/handler.py b/handler.py index e602d1f..5f2ec20 100644 --- a/handler.py +++ b/handler.py @@ -6,25 +6,34 @@ import config from telegram import Bot -from discord_webhook import DiscordWebhook +from discord_webhook import DiscordWebhook, DiscordEmbed import tweepy import smtplib, ssl from email.mime.text import MIMEText - + def send_alert(data): if config.send_telegram_alerts: + tg_bot = Bot(token=config.tg_token) try: - tg_bot = Bot(token=config.tg_token) - tg_bot.sendMessage(config.channel, data, parse_mode = 'MARKDOWN') - except Exception as e: - print(e) - + tg_bot.sendMessage(data['telegram'], data['msg'], parse_mode='MARKDOWN') + except KeyError: + tg_bot.sendMessage(config.channel, data['msg'], parse_mode='MARKDOWN') + except Exception as e: + print('[X] Telegram Error:\n>', e) + if config.send_discord_alerts: try: - discord_alert = DiscordWebhook(url=config.discord_webhook, content=data) - response = discord_alert.execute() - except Exception as e: - print(e) + webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" + data['discord']) + embed = DiscordEmbed(title=data['msg']) + webhook.add_embed(embed) + response = webhook.execute() + except KeyError: + webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" + config.discord_webhook) + embed = DiscordEmbed(title=data['msg']) + webhook.add_embed(embed) + response = webhook.execute() + except Exception as e: + print('[X] Discord Error:\n>', e) if config.send_twitter_alerts: tw_auth = tweepy.OAuthHandler(config.tw_ckey, config.tw_csecret) @@ -33,7 +42,7 @@ def send_alert(data): try: tw_api.update_status(status=data) except Exception as e: - print(e) + print('[X] Twitter Error:\n>', e) if config.send_email_alerts: try: @@ -47,4 +56,4 @@ def send_alert(data): server.sendmail(config.email_sender, config.email_receivers, email_msg.as_string()) server.quit() except Exception as e: - print(e) \ No newline at end of file + print('[X] Email Error:\n>', e) \ No newline at end of file diff --git a/main.py b/main.py index 5c051e8..a281281 100644 --- a/main.py +++ b/main.py @@ -7,28 +7,29 @@ import config import time from flask import Flask, request +import json from handler import * timestamp = time.strftime("%Y-%m-%d %X") app = Flask(__name__) -@app.route('/webhook', methods=['POST']) +@app.route('/webhook', methods=['POST']) def webhook(): try: if request.method == 'POST': - data = request.get_data(as_text=True) - for whitelisted in config.whitelisted: - if whitelisted.lower() in data.lower() and config.sec_code in data: - print('[✓]', timestamp, 'Alert Received & Sent!\n>', data) - send_alert(data) - return 'Sent alert', 200 + data = request.get_json() + key = data['key'] + if key == config.sec_key: + print(timestamp, 'Alert Received & Sent!') + send_alert(data) + return 'Sent alert', 200 + else: - print('[✗]', timestamp, 'Alert Received & Refused!\n>', data) + print('[X]', timestamp, 'Alert Received & Refused! (Wrong Key)') return 'Refused alert', 400 - else: - return 'Refused alert', 400 + except Exception as e: - print('[✘]', timestamp, 'Error:\n>', e) + print('[X]', timestamp, 'Error:\n>', e) return 'Error', 400 if __name__ == '__main__':