kopia lustrzana https://github.com/fabston/TradingView-Webhook-Bot
Beautified code
rodzic
e55d973f5b
commit
dca330cde5
|
@ -5,18 +5,18 @@ labels: bug
|
|||
|
||||
---
|
||||
|
||||
**Describe the bug:**
|
||||
## Describe the bug
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Steps to reproduce:**
|
||||
### Steps to reproduce
|
||||
Steps to reproduce the behavior.
|
||||
|
||||
**Expected behavior:**
|
||||
### Expected behavior
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Environment:**
|
||||
### Environment
|
||||
- OS: [e.g. Arch Linux]
|
||||
- Other details that you think may affect.
|
||||
|
||||
**Additional context:**
|
||||
### Additional context
|
||||
Add any other context about the problem here.
|
|
@ -5,14 +5,11 @@ labels: enhancement
|
|||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe:**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
## Summary
|
||||
Brief explanation of the feature.
|
||||
|
||||
**Describe the solution you'd like:**
|
||||
A clear and concise description of what you want to happen.
|
||||
### Basic example
|
||||
Include a basic example or links here.
|
||||
|
||||
**Describe alternatives you've considered:**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context:**
|
||||
Add any other context about the feature request here.
|
||||
### Motivation
|
||||
Why are we doing this? What use cases does it support? What is the expected outcome?
|
||||
|
|
|
@ -10,13 +10,13 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v1
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'It looks like this has been idle a while, so I am marking it as stale. Remove the label or comment if this issue should remain open.'
|
||||
stale-pr-message: 'It looks like this PR has been idle a while, so I am marking it as stale. Remove the label or comment if this is still being worked on.'
|
||||
stale-issue-label: 'no-activity'
|
||||
stale-pr-label: 'no-activity'
|
||||
exempt-pr-labels: 'help wanted'
|
||||
exempt-pr-labels: 'help wanted,enhancement'
|
||||
days-before-stale: 30
|
||||
days-before-close: 5
|
|
@ -45,7 +45,7 @@ Find out more at [WebhookAlerts.com](https://webhookalerts.com). Got a question?
|
|||
- 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/fabston/TradingView-Webhook-Bot/issues/new?assignees=&labels=&template=feature-request---.md) and I might implement it.
|
||||
> 💡 Got a feature idea? Open an [issue](https://github.com/fabston/TradingView-Webhook-Bot/issues/new?assignees=&labels=enhancement&template=feature-request---.md) and I might implement it.
|
||||
|
||||
## Installation
|
||||
> ⚠️ Best to run the bot on a VPS. I can recommend <a href="https://fabston.dev/hetzner" title="Get €20 in cloud credits">Hetzner</a>'s CX11 VPS for 2.89€/month.
|
||||
|
|
BIN
assets/bmac.png
BIN
assets/bmac.png
Plik binarny nie jest wyświetlany.
Przed Szerokość: | Wysokość: | Rozmiar: 262 KiB Po Szerokość: | Wysokość: | Rozmiar: 12 KiB |
30
config.py
30
config.py
|
@ -9,35 +9,37 @@
|
|||
# "key":"9T2q394M92", "telegram":"-1001298977502", "discord":"789842349670960670/BFeBBrCt-w2Z9RJ2wlH6TWUjM5bJuC29aJaJ5OQv9sE6zCKY_AlOxxFwRURkgEl852s3", "msg":"Long #{{ticker}} at `{{close}}`"
|
||||
# }
|
||||
|
||||
sec_key = '' # Can be anything. Has to match with "key" in your TradingView alert message
|
||||
sec_key = (
|
||||
"" # Can be anything. Has to match with "key" in your TradingView alert message
|
||||
)
|
||||
|
||||
# Telegram Settings
|
||||
send_telegram_alerts = False
|
||||
tg_token = '' # Bot token. Get it from @Botfather
|
||||
tg_token = "" # Bot token. Get it from @Botfather
|
||||
channel = 0 # Channel ID (ex. -1001487568087)
|
||||
|
||||
# Discord Settings
|
||||
send_discord_alerts = False
|
||||
discord_webhook = '' # Discord Webhook URL (https://support.discordapp.com/hc/de/articles/228383668-Webhooks-verwenden)
|
||||
discord_webhook = "" # Discord Webhook URL (https://support.discordapp.com/hc/de/articles/228383668-Webhooks-verwenden)
|
||||
|
||||
# Slack Settings
|
||||
send_slack_alerts = False
|
||||
slack_webhook = '' # Slack Webhook URL (https://api.slack.com/messaging/webhooks)
|
||||
slack_webhook = "" # Slack Webhook URL (https://api.slack.com/messaging/webhooks)
|
||||
|
||||
# Twitter Settings
|
||||
send_twitter_alerts = False
|
||||
tw_ckey = ''
|
||||
tw_csecret = ''
|
||||
tw_atoken = ''
|
||||
tw_asecret = ''
|
||||
tw_ckey = ""
|
||||
tw_csecret = ""
|
||||
tw_atoken = ""
|
||||
tw_asecret = ""
|
||||
|
||||
# Email Settings
|
||||
send_email_alerts = False
|
||||
email_sender = '' # Your email address
|
||||
email_receivers = ['', ''] # Receivers, can be multiple
|
||||
email_subject = 'Trade Alert!'
|
||||
email_sender = "" # Your email address
|
||||
email_receivers = ["", ""] # Receivers, can be multiple
|
||||
email_subject = "Trade Alert!"
|
||||
|
||||
email_port = 465 # SMTP SSL Port (ex. 465)
|
||||
email_host = '' # SMTP host (ex. smtp.gmail.com)
|
||||
email_user = '' # SMTP Login credentials
|
||||
email_password = '' # SMTP Login credentials
|
||||
email_host = "" # SMTP host (ex. smtp.gmail.com)
|
||||
email_user = "" # SMTP Login credentials
|
||||
email_password = "" # SMTP Login credentials
|
||||
|
|
93
handler.py
93
handler.py
|
@ -4,72 +4,97 @@
|
|||
# File Name : handler.py #
|
||||
# ----------------------------------------------- #
|
||||
|
||||
import config
|
||||
from telegram import Bot
|
||||
from discord_webhook import DiscordWebhook, DiscordEmbed
|
||||
from slack_webhook import Slack
|
||||
import tweepy
|
||||
import smtplib, ssl
|
||||
import smtplib
|
||||
import ssl
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
import tweepy
|
||||
from discord_webhook import DiscordEmbed, DiscordWebhook
|
||||
from slack_webhook import Slack
|
||||
from telegram import Bot
|
||||
|
||||
import config
|
||||
|
||||
|
||||
def send_alert(data):
|
||||
if config.send_telegram_alerts:
|
||||
tg_bot = Bot(token=config.tg_token)
|
||||
try:
|
||||
tg_bot.sendMessage(data['telegram'],
|
||||
data['msg'].encode('latin-1', 'backslashreplace').decode('unicode_escape'),
|
||||
parse_mode='MARKDOWN')
|
||||
tg_bot.sendMessage(
|
||||
data["telegram"],
|
||||
data["msg"]
|
||||
.encode("latin-1", "backslashreplace")
|
||||
.decode("unicode_escape"),
|
||||
parse_mode="MARKDOWN",
|
||||
)
|
||||
except KeyError:
|
||||
tg_bot.sendMessage(config.channel,
|
||||
data['msg'].encode('latin-1', 'backslashreplace').decode('unicode_escape'),
|
||||
parse_mode='MARKDOWN')
|
||||
tg_bot.sendMessage(
|
||||
config.channel,
|
||||
data["msg"]
|
||||
.encode("latin-1", "backslashreplace")
|
||||
.decode("unicode_escape"),
|
||||
parse_mode="MARKDOWN",
|
||||
)
|
||||
except Exception as e:
|
||||
print('[X] Telegram Error:\n>', e)
|
||||
print("[X] Telegram Error:\n>", e)
|
||||
|
||||
if config.send_discord_alerts:
|
||||
try:
|
||||
webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" + data['discord'])
|
||||
embed = DiscordEmbed(title=data['msg'])
|
||||
webhook = DiscordWebhook(
|
||||
url="https://discord.com/api/webhooks/" + data["discord"]
|
||||
)
|
||||
embed = DiscordEmbed(title=data["msg"])
|
||||
webhook.add_embed(embed)
|
||||
response = webhook.execute()
|
||||
webhook.execute()
|
||||
except KeyError:
|
||||
webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" + config.discord_webhook)
|
||||
embed = DiscordEmbed(title=data['msg'])
|
||||
webhook = DiscordWebhook(
|
||||
url="https://discord.com/api/webhooks/" + config.discord_webhook
|
||||
)
|
||||
embed = DiscordEmbed(title=data["msg"])
|
||||
webhook.add_embed(embed)
|
||||
response = webhook.execute()
|
||||
webhook.execute()
|
||||
except Exception as e:
|
||||
print('[X] Discord Error:\n>', e)
|
||||
print("[X] Discord Error:\n>", e)
|
||||
|
||||
if config.send_slack_alerts:
|
||||
try:
|
||||
slack = Slack(url='https://hooks.slack.com/services/' + data['slack'])
|
||||
slack.post(text=data['msg'])
|
||||
slack = Slack(url="https://hooks.slack.com/services/" + data["slack"])
|
||||
slack.post(text=data["msg"])
|
||||
except KeyError:
|
||||
slack = Slack(url='https://hooks.slack.com/services/' + config.slack_webhook)
|
||||
slack.post(text=data['msg'])
|
||||
slack = Slack(
|
||||
url="https://hooks.slack.com/services/" + config.slack_webhook
|
||||
)
|
||||
slack.post(text=data["msg"])
|
||||
except Exception as e:
|
||||
print('[X] Slack Error:\n>', e)
|
||||
print("[X] Slack Error:\n>", e)
|
||||
|
||||
if config.send_twitter_alerts:
|
||||
tw_auth = tweepy.OAuthHandler(config.tw_ckey, config.tw_csecret)
|
||||
tw_auth.set_access_token(config.tw_atoken, config.tw_asecret)
|
||||
tw_api = tweepy.API(tw_auth)
|
||||
try:
|
||||
tw_api.update_status(status=data['msg'].replace('*', '').replace('_', '').replace('`', ''))
|
||||
tw_api.update_status(
|
||||
status=data["msg"].replace("*", "").replace("_", "").replace("`", "")
|
||||
)
|
||||
except Exception as e:
|
||||
print('[X] Twitter Error:\n>', e)
|
||||
print("[X] Twitter Error:\n>", e)
|
||||
|
||||
if config.send_email_alerts:
|
||||
try:
|
||||
email_msg = MIMEText(data['msg'].replace('*', '').replace('_', '').replace('`', ''))
|
||||
email_msg['Subject'] = config.email_subject
|
||||
email_msg['From'] = config.email_sender
|
||||
email_msg['To'] = config.email_sender
|
||||
email_msg = MIMEText(
|
||||
data["msg"].replace("*", "").replace("_", "").replace("`", "")
|
||||
)
|
||||
email_msg["Subject"] = config.email_subject
|
||||
email_msg["From"] = config.email_sender
|
||||
email_msg["To"] = config.email_sender
|
||||
context = ssl.create_default_context()
|
||||
with smtplib.SMTP_SSL(config.email_host, config.email_port, context=context) as server:
|
||||
with smtplib.SMTP_SSL(
|
||||
config.email_host, config.email_port, context=context
|
||||
) as server:
|
||||
server.login(config.email_user, config.email_password)
|
||||
server.sendmail(config.email_sender, config.email_receivers, email_msg.as_string())
|
||||
server.sendmail(
|
||||
config.email_sender, config.email_receivers, email_msg.as_string()
|
||||
)
|
||||
server.quit()
|
||||
except Exception as e:
|
||||
print('[X] Email Error:\n>', e)
|
||||
print("[X] Email Error:\n>", e)
|
||||
|
|
30
main.py
30
main.py
|
@ -4,10 +4,12 @@
|
|||
# File Name : main.py #
|
||||
# ----------------------------------------------- #
|
||||
|
||||
import config
|
||||
import time
|
||||
from flask import Flask, request
|
||||
import json
|
||||
import time
|
||||
|
||||
from flask import Flask, request
|
||||
|
||||
import config
|
||||
from handler import *
|
||||
|
||||
app = Flask(__name__)
|
||||
|
@ -18,27 +20,27 @@ def get_timestamp():
|
|||
return timestamp
|
||||
|
||||
|
||||
@app.route('/webhook', methods=['POST'])
|
||||
@app.route("/webhook", methods=["POST"])
|
||||
def webhook():
|
||||
try:
|
||||
if request.method == 'POST':
|
||||
if request.method == "POST":
|
||||
data = request.get_json()
|
||||
key = data['key']
|
||||
key = data["key"]
|
||||
if key == config.sec_key:
|
||||
print(get_timestamp(), 'Alert Received & Sent!')
|
||||
print(get_timestamp(), "Alert Received & Sent!")
|
||||
send_alert(data)
|
||||
return 'Sent alert', 200
|
||||
return "Sent alert", 200
|
||||
|
||||
else:
|
||||
print('[X]', get_timestamp(), 'Alert Received & Refused! (Wrong Key)')
|
||||
return 'Refused alert', 400
|
||||
print("[X]", get_timestamp(), "Alert Received & Refused! (Wrong Key)")
|
||||
return "Refused alert", 400
|
||||
|
||||
except Exception as e:
|
||||
print('[X]', get_timestamp(), 'Error:\n>', e)
|
||||
return 'Error', 400
|
||||
print("[X]", get_timestamp(), "Error:\n>", e)
|
||||
return "Error", 400
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
from waitress import serve
|
||||
|
||||
serve(app, host='0.0.0.0', port=80)
|
||||
serve(app, host="0.0.0.0", port=80)
|
||||
|
|
|
@ -1,6 +1,36 @@
|
|||
flask
|
||||
waitress
|
||||
python-telegram-bot
|
||||
discord-webhook
|
||||
slack-webhook
|
||||
tweepy
|
||||
appdirs==1.4.4
|
||||
APScheduler==3.6.3
|
||||
black==21.5b1
|
||||
cachetools==4.2.2
|
||||
certifi==2021.5.30
|
||||
chardet==4.0.0
|
||||
click==8.0.1
|
||||
discord-webhook==0.14.0
|
||||
flake8==3.9.2
|
||||
Flask==2.0.1
|
||||
idna==2.10
|
||||
isort==5.8.0
|
||||
itsdangerous==2.0.1
|
||||
Jinja2==3.0.1
|
||||
MarkupSafe==2.0.1
|
||||
mccabe==0.6.1
|
||||
mypy-extensions==0.4.3
|
||||
oauthlib==3.1.1
|
||||
pathspec==0.8.1
|
||||
pycodestyle==2.7.0
|
||||
pyflakes==2.3.1
|
||||
PySocks==1.7.1
|
||||
python-telegram-bot==13.6
|
||||
pytz==2021.1
|
||||
regex==2021.4.4
|
||||
requests==2.25.1
|
||||
requests-oauthlib==1.3.0
|
||||
six==1.16.0
|
||||
slack-webhook==1.0.6
|
||||
toml==0.10.2
|
||||
tornado==6.1
|
||||
tweepy==3.10.0
|
||||
tzlocal==2.1
|
||||
urllib3==1.26.5
|
||||
waitress==2.0.0
|
||||
Werkzeug==2.0.1
|
||||
|
|
Ładowanie…
Reference in New Issue