How to deploy a Python Telegram Bot to Azure without using Flask? - python

I create a Telegram bot using Python, here is the code:
TOKEN = BOT TOKEN
# deploy
def run(updater):
PORT = int(os.environ.get('PORT', '8443'))
updater.start_webhook(listen="0.0.0.0",
port=PORT,
url_path=TOKEN)
updater.bot.set_webhook("Azure WEB APP URL".format(TOKEN))
def start_handler(bot, update):
do something
def callback_func(bot, job):
do something
def trigger_callback(bot, update, job_queue):
logger.info("User {} trigger bot".format(update.effective_user["id"]))
bot.send_message(chat_id=update.message.chat_id, text='Starting!')
job_queue.run_repeating(callback_sql, 600, context=update.message.chat_id)
def stop_callback(bot, update, job_queue):
logger.info("User {} stop bot".format(update.effective_user["id"]))
bot.send_message(chat_id=update.message.chat_id,
text='Stoped!')
job_queue.stop()
if __name__ == '__main__':
logger.info("Starting bot")
updater = Updater(TOKEN)
updater.dispatcher.add_handler(CommandHandler('start', start_handler))
updater.dispatcher.add_handler(CommandHandler('trigger', trigger_callback, pass_job_queue=True))
updater.dispatcher.add_handler(CommandHandler('stop', stop_callback, pass_job_queue=True))
run(updater)
I have test the Bot in local and it run perfectly. So now how can I deploy it to the Azure Cloud??? Thank guys for you helping!!!
I see the introduction about Azure Bot Service but don't know how to do!

It's actually pretty easy:
Install azure cli, then create a requirements.txt file in the root of your python app with the libraries you need. For example:
python-telegram-bot>=13.3,<=13.3
Open Powershell or Bash, depending on your OS, and run
az webapp up -n <app-name> -g <rg-name> --sku <your-sku> --location <your-location>
A few notes:
Name the main file app.py so that Azure will run it automatically
Configure Always On on your app service in Configuration -> General Settings. This will always keep the bot running. Otherwise Azure will turn it off when idle and only restart it when the website is requested. As your bot works in pull mode, it will never be restared again unless you do it manually, so you need the Always On feature. You'll need a B1 or App Service Plan or better, the free plan does not support Always On.

Related

Github webhooks not working on Raspberry Pi 3 but works on Windows 10 computer

I am new to using raspberry pi's and don't really have any knowledge on flask.
So, I'm trying to implement Github webhooks with a python flask + ngrok to automatically git pull when a new push has been made to the repository. This is so I can just work on my Windows computer, push via Github Desktop and have it automatically pull the code from the repository using webhooks (the url from ngrok) to my raspberry's local repository. I use flask and ngrok to receive the webhook, which when received, starts pulling from the repo.
The issue is that the code for receiving the webhook doesn't work on my raspberry pi. The code below works perfectly fine on my Windows pc and works as expected, but when use the exact same code on my raspberry pi it just doesn't receive the webhook nor print anything. I don't really know what's going on, should work as expected.
from flask import Flask, request, json
import subprocess
app = Flask(__name__)
#app.route('/')
def root():
return 'Working'
# This receives the webhooks and does code when received
#app.route('/', methods=['POST'])
def webhook():
print("Receiving data...")
data = json.loads(request.data)
print ("\n\nNew commit by: {}".format(data['commits'][0]['author']['name'])) # Inform that someone has committed
print("\n\nPulling repository...")
subprocess.run(["git", "pull"]) # Pull new code from repo
print("Finished pulling.\nLocal repository up-to-date!\n\n")
return "OK"
if __name__ == '__main__':
app.run(debug=True)

Cannot Host Discord Bot on repl.it

I recently made a discord bot and ran in on repl.it as it has free hosting (I use uptime robot). But, when I run main.py the uptime robot says that the website that I use for keep_alive() is "Down" and when I try to access the website from my browser it doesn't load either saying that the site "can't be reached". When I close the repl.it tab my bot goes offline as well.
Repl.it is not made for hosting discord bot's it's prone to rate limits.
It's good for writing code online and hosting basic web apps or collaborating with others while coding.
You should definitely invest in a proper host like PebbleHost, PloxHost and etc if you need something to write code online. However, a VPS provider like Linode, Digitalcoean or even PloxHost would be more beneficial as you have your own dedicated IP and are not affected by rate limits from other users. However, this does require knowledge of Linux.
For your issue of your keep_alive you should try this:
from flask import Flask
from threading import Thread
import time
app = Flask('')
#app.route('/')
def home():
return "Hello World!"
def run():
app.run(host='0.0.0.0',port=8080)#127.0.0.1 or ::
def keep_alive():
t = Thread(target=run)
t.start()
Then in your main.py:
from keep_alive import keep_alive
keep_alive()
You should take a look at UptimeRobot to send pings to the URL of the web server associated with the repl. This video is for node.js but should apply to python as well on the UptimeRobot chunk

Trading view alerts to trigger market order through python and Oanda's API

I'm trying to trigger a python module (market order for Oanda) using web hooks(from trading view).
Similar to this
1) https://www.youtube.com/watch?v=88kRDKvAWMY&feature=youtu.be
and this
2)https://github.com/Robswc/tradingview-webhooks-bot
But my broker is Oanda so I'm using python to place the trade. This link has more information.
https://github.com/hootnot/oanda-api-v20
The method is web hook->ngrok->python. When a web hook is sent, the ngrok (while script is also running) shows a 500 internal service error and that the server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
This is what my script says when its running (see picture);
First says some stuff related the market order then;
running script picture
One thing I noticed is that after Debug it doesn't say Running on... (so maybe my flask is not active?
Here is the python script;
from flask import Flask
import market_orders
# Create Flask object called app.
app = Flask(__name__)
# Create root to easily let us know its on/working.
#app.route('/')
def root():
return 'online'
#app.route('/webhook', methods=['POST'])
def webhook():
if request.method == 'POST':
# Parse the string data from tradingview into a python dict
print(market_orders.myfucn())
else:
print('do nothing')
if __name__ == '__main__':
app.run()
Let me know if there is any other information that would be helpful.
Thanks for your help.
I fixed it!!!! Google FTW
The first thing I learned was how to make my module a FLASK server. I followed these websites to figure this out;
This link helped me set up the flask file in a virtual environment. I also moved my Oanda modules to this new folder. And opened the ngrok app while in this folder via the command window. I also ran the module from within the command window using flask run.
https://topherpedersen.blog/2019/12/28/how-to-setup-a-new-flask-app-on-a-mac/
This link showed me how to set the FLASK_APP and the FLASK_ENV
Flask not displaying http address when I run it
Then I fixed the internal service error by adding return 'okay' after print(do nothing) in my script. This I learned from;
Flask Value error view function did not return a response

Basic Python Echo Bot not addressable through Bot Framework Emulator (Post 500) after linking to Azure QnA Maker

I have followed the official instructions (Docs) on how to create a python echo bot with the SDKv4 and as soon as the described init function is added my bot ceases to work. The echo bot by itself, without the connection to the Azure QnA Maker works perfectly within the Bot Framework Emulator.
The Error displayed in the Bot Framework Emulator:
POST500directline/conversations//activities. Also it doesn't display the welcoming message any more and when I send a message the bot apparently does not receive that message (send failed, retry is displayed below the message).
This problem occurs after adding the init function from the guide to the MyBot class from the bot.py file. The function reads:
def __init__(self, config: Config):
self.qna_maker = QnAMaker(
QnAMakerEndpoint(
knowledge_base_id=config["QNA_KNOWLEDGEBASE_ID"],
endpoint_key=config["QNA_ENDPOINT_KEY"],
host=config["QNA_ENDPOINT_HOST"],
)
)
When following the guide, I had to move the bot instance creation to the very bottom of the app.py file, below:
APP = web.Application(middlewares=[aiohttp_error_middleware])
APP.router.add_post("/api/messages", messages)
if __name__ == "__main__": (...)`
as the code otherwise doesn't run: BOT = MyBot(APP.config) causes: NameError: name 'APP' is not defined
Also I get the problem in the app.py file: No name 'DefaultConfig' in module 'config' - even though config.py exists and is obviously used as the ports change when I change them in the config file.
Aside from that I followed the guide precisely. I would be very thankful for any help or resource recommendations, over the past two days I've tried to everything I could find online. Thank you!

How to use telegram webhook on google cloud functions?

I have set up a telegram bot using webhooks in python on google cloud functions. Based on some sample code from the internet I got it to work as a simple echo-bot however the structure is very different to the bots I coded before using long polling:
# main.py
import os
import telegram
def webhook(request):
bot = telegram.Bot(token=os.environ["TELEGRAM_TOKEN"])
if request.method == "POST":
update = telegram.Update.de_json(request.get_json(force=True), bot)
chat_id = update.message.chat.id
# Reply with the same message
bot.sendMessage(chat_id=chat_id, text=update.message.text)
return "ok"
I do not understand how to add any more handlers or different functions to this, especially because cloud functions needs me to name only one function to run from the script (in this case the webhook function).
How can I convert the above logic to the one I am more familiar with below:
import os
TOKEN = "TOKEN"
PORT = int(os.environ.get('PORT', '8443'))
updater = Updater(TOKEN)
# add example handler
def start(update, context):
context.bot.send_message(chat_id=update.message.chat_id, text="Hello, I am dice bot and I will roll some tasty dice for you.")
start_handler = CommandHandler('start', start)
dispatcher.add_handler(start_handler)
# start webhook polling
updater.start_webhook(listen="0.0.0.0",
port=PORT,
url_path=TOKEN)
updater.bot.set_webhook("https://<appname>.herokuapp.com/" + TOKEN)
updater.idle()
This code has the same structure as long polling so I know how to add additional handlers. However it has two problems:
It is the code snippet from the documentation for heroku, so I do not know whether this works the same for google cloud functions
This does not produce one function I can call in cloud functions, I tried wrapping all my code above in one big function webhook and simply running that but it does not work (and does not produce an error on my google dashboard).
Any help is appreciated!
I found this github telebot repo from yukuku with the setup of a telegram bot on App Engine and the webhook implementation using python. As mentioned before you may want to use App Engine in order to implement your bot with many functions on the same main.py file.
I just tried and it's working for me.
i did that here's my snippet
from telegram import Bot,Update
from telegram.ext import CommandHandler,Dispatcher
import os
TOKEN = os.getenv('TOKEN')
bot = Bot(token=TOKEN)
dispatcher = Dispatcher(bot,None,workers=0)
def start(update,context):
context.bot.send_message(chat_id=update.effective_chat.id,text="I am a bot, you can talk to me")
dispatcher.add_handler(CommandHandler('start',start))
def main(request):
update = Update.de_json(request.get_json(force=True), bot)
dispatcher.process_update(update)
return "OK"
# below function to be used only once to set webhook url on telegram
def set_webhook(request):
global bot
global TOKEN
s = bot.setWebhook(f"{URL}/{TOKEN}") # replace your functions URL,TOKEN
if s:
return "Webhook Setup OK"
else:
return "Webhook Setup Failed"

Categories

Resources