Telegram bot does not get updates from webhook - python

I have faced the following problem after moving my bot to the new server. I use webhook to get updates but now the bot does not get them from telegram servers. I tried to send POST request with curl from the remove server and bot handled it in a normal way. I checked webhook with getWebhookInfo and it returned an object with non-empty url and pending_update_count equal to 74 without errors. I guess, it means that telegram servers are not able to send POST request to my host for some reason.
OS of my server is Arch Linux.
I use pyTelegramBotAP.
CONFIG = ConfigParser()
CONFIG.read(os.path.join('data', 'config.ini'))
# webhook url
URL_BASE = "https://{}:{}".format(CONFIG['server']['ip'], CONFIG.getint('server', 'port'))
URL_PATH = "/{}/".format(CONFIG['telegram bot']['token'])
BOT = telebot.TeleBot(CONFIG['telegram bot']['token'])
# server that will listen for new messages
APP = web.Application()
URL = URL_BASE + URL_PATH
BOT.set_webhook(url=URL, certificate=open(CONFIG['ssl']['certificate'], 'rb'))
# Build ssl context
CONTEXT = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
CONTEXT.load_cert_chain(CONFIG['ssl']['certificate'], CONFIG['ssl']['private key'])
# Start aiohttp server
web.run_app(
APP,
host=CONFIG['server']['listen'],
port=CONFIG['server']['port'],
ssl_context=CONTEXT,
)
Please, help!

Telegram webhook only talks to https endpoints, so I suggest to check your server against https connections.
Also, getWebhookInfo call returns a status object with the latest error infomation of your endpoint. Have a look of that error info and might find the exact problem.

Please check the Firewall on your server, It is quite possible firewall on your server is not passing message to your application.

To check firewall status run $ ufw status
Please show you URL_BASE without real IP.
What operating system is on your server?
You send test request from the CURL to URL of the Telegram or of your server?
Can you getting response from your server if you run simple app?
Example:
from aiohttp import web
async def hello(request):
return web.Response(text='Hello world!')
app = web.Application()
app.add_routes([web.get('/', hello)])
web.run_app(app, host='localhost', port=3003)
Check response:
$ curl localhost:3003
Hello world!
Please provide more detailed information on how you troubleshoot.

Related

Http requests, 403 forbidden, Twilio Whatsapp

I am trying to create a connection to whatsapp and my python script via Twilio, to generate automatic conversations. I follow every step in order of this link https://www.pragnakalp.com/create-whatsapp-bot-with-twilio-using-python-tutorial-with-examples/?unapproved=4864&moderation-hash=3861b2bc00104a39b5f3211076dda854#comment-4864
The problem arrays when I start a conversation with the bot, that in my ngrok port, ngrok http 5000 it says POST/ 403 Forbidden, in the section of https requests.
Before sending the message to the bot I run my python script:
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
app = Flask(__name__)
##app.route("/wa")
#def wa_hello():
# return "Hello, World!"
#app.route("/wasms", methods=['POST'])
def wa_sms_reply():
"""Respond to incoming calls with a simple text message."""
# Fetch the message
msg = request.form.get('Body').lower() # Reading the message from the whatsapp
print("msg-->", msg)
resp = MessagingResponse()
reply = resp.message()
# Create reply
if msg == "hi":
reply.body("hello!")
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
I tried running commands like ngrok http https://localhost:5000, turning off firewalls on my Mac, allowing my country on the Twilio´s web page, inserting config.hosts << /.*\.ngrok\.io/ in my terminal and restaring my laptop, config.hosts << "a0000000.ngrok.io" and skip_before_action :verify_authenticity_token but nothing of this work for me. The error os shown here:enter image description here

Twilio Whatsapp Sandbox Configuration for deploying application via AWS elastic beanstalk

enter image description here
Currently I am developing a chatbot for my application with django, using a twilio trial account.
The chatbot functions properly with ngrok.io, i.e. when the server is operating locally, which mean that when I send a whatsapp message to the twilio sandbox with operation of simply "python manage.py runserver", he will automatically reply me according to my script.
However, as I started deploying the application using the AWS elastic beanstalk, I found that it is only possible for the sandbox to send out whatsapp message by POST request on the web application, but not capable to respond to POST request sent out from whatsapp.
In what way I can deal with it? Is it related to AWS settings or Twilio settings? Some CORS related issues?
Great thanks in advance.
(Please forgive me if my use of language is not accurate as I am not with computer science background.)
Below is part of the code that I applied.
#csrf_exempt
def message(request):
account_sid = 'xxx'
auth_token = 'xxx'
client = Client(account_sid, auth_token)
client_phone_number = request.POST.get('From').removeprefix("whatsapp:+852")
client_phone_number.removeprefix("+852")
incoming_message = request.POST.get('Body')
conversation_sid = request.POST.get('conversation_sid')
incoming_message = incoming_message.lower()
response = MessagingResponse()
#processing the incoming message to produce the text
resp = "text"
response.message(resp)
return HttpResponse(str(response))
I have tried pasting https://xxxxx-env.yyyyyyy.us-east-1.elasticbeanstalk.com/whatsapp/ to the sandbox configuration cell as shown in the image and it resulted to what I mentioned above. The whatsapp url is set just like typically done for other urls for django, followed by message(request) to process the request sent out from the whatsapp. Any other proper way I can do it?

Telegram Bot not working with Webhook, programme is running but not getting any response

I have create a telegram bot in python but I am unable to set webhook. After some research I have set the webhook but it's not working. the code is working with start_polling() method but stop working in heroku server after some time so I want to run the code using webhook.
The code is running properly but not getting any response from telegram
PORT = int(os.environ.get('PORT', '5000'))
updater.start_webhook(listen="0.0.0.0", port=PORT, url_path=token,
webhook_url='https://git.heroku.com/pytelestock.git' + token)
When run the api got this error.
{"ok":true,"result":{"url":"https://git.heroku.com/pytelestock.git1851418449:token","has_custom_certificate":false,"pending_update_count":2,"last_error_date":1622897956,"last_error_message":"Wrong response from the webhook: 404 Not Found","max_connections":40,"ip_address":"xx.xxx.xxx.xxx"}}
As i am new in this field i don't know why i am getting the error and how to solve this.
The webhook_url should rather be 'pytelestock.herouk.com/' + token.

Instagram Real-time API can't see my server

I'm testing the Instagram Real-time API with Python and Flask and I get everytime this response from the Instagram server:
{
"meta":{
"error_type":"APISubscriptionError",
"code":400,
"error_message":"Unable to reach callback URL \"http:\/\/my_callback_url:8543\/instagram\"."
}
}
The request:
curl -F 'client_id=my_client_id...' \
-F 'client_secret=my_client_secret...' \
-F 'object=tag' \
-F 'aspect=media' \
-F 'object_id=fox' \
-F 'callback_url=http://my_callback_url:8543/instagram' \
https://api.instagram.com/v1/subscriptions/
And this is the code of the Flask server:
from flask import Flask
from flask import request
from instagram import subscriptions
app = Flask(__name__)
CLIENT_ID = "my_client_id..."
CLIENT_SECRET = "my_client_secret..."
def process_tag_update(update):
print 'Received a push: ', update
reactor = subscriptions.SubscriptionsReactor()
reactor.register_callback(subscriptions.SubscriptionType.TAG, process_tag_update)
#app.route('/instagram', methods=['GET'])
def handshake():
# GET method is used when validating the endpoint as per the Pubsubhubub protocol
mode = request.values.get('hub.mode')
challenge = request.values.get('hub.challenge')
verify_token = request.values.get('hub.verify_token')
if challenge:
return challenge
return 'It is not a valid challenge'
#app.route('/instagram', methods=['POST'])
def callback():
# POST event is used to for the events notifications
x_hub_signature = request.headers.get('X-Hub-Signature')
raw_response = request.data
try:
reactor.process(CLIENT_SECRET, raw_response, x_hub_signature)
except subscriptions.SubscriptionVerifyError:
print 'Signature mismatch'
return 'done'
def server():
""" Main server, will allow us to make it wsgi'able """
app.run(host='0.0.0.0', port=8543, debug=True)
if __name__ == '__main__':
server()
The machine have a public IP and the port is open for everyone. I can reach the url from others networks.
Why can't Instagram reach my url? Is there a black list or something like that?
Update 1
I have tested the same code with some frameworks and WSGI servers (Django, Flask, Node.js, Gunicorn, Apache) and different responses in the GET/POST endpoint and I always get the same 400 error message.
Also I have checked the packages received in my network interface with Wireshark and I get the expected results with calls from any network. But I don't get any package when I do the subscription request.
So... Is this a bug? Could be my IP in any blacklist for some reason?
I had exactly the same. It worked when I accidentally restarted the router, getting a different IP. It seems that it could be an IP issue indeed and the Unable to reach callback URL... is not really helpful in this case.
I agree, there are plenty of AWS servers answering to that API and some are not working. Ping api.instagram.com and you'll see you get multiple and different IP for that domain name. There is a DNS round robin and you are not reaching the same server every time.
I've found one server (IP : 52.6.133.72) which seems to be working for subscription and have configured my server to use that one (by editing the /etc/hosts file). Not a reliable solution ... but it's working.

Facebook Realtime Updates Subscription Verification in Python

I've been trying to set up a subscription for my app with the Realtime Updates API but there have been some issues. For starters, this is the error I keep getting:
{"error":{"message":"(#2200) callback verification failed: Operation timed out after 6000 milliseconds with 0 bytes received","type":"OAuthException","code":2200}}
I've followed the documentation appropriately and configured a Flask endpoint on an Amazon EC2 instance that handles HTTP GET and POST. What happens is I hit and endpoint myself, manually, to invoke the subscription code.
curl -i -X GET http://public-ip-of-ec2:5000/subscribe
The above curl calls a script running in a flask application at the route of /subscribe on my ec2 instance. To make the POST with the required query string parameters including our access_token, object, fields, verify_token, and callback_url I'm using the python HTTP library requests.
VERIFY_TOKEN = 'my_verify_token'
#app.route('/subscribe')
def subscribe():
global VERIFY_TOKEN
FB_CLIENT_ID = 'my_app_id'
# access_token is sent as a query string parameter
APP_ACCESS_TOKEN = 'my_app_access_token'
# object, fields, callback_url, and verify_token are sent as urllib.urlencode([('param','val')])
CALLBACK_URL = 'http://my-public-ec2-ip:5000/'
payload_url = "https://graph.facebook.com/{0}/subscriptions".format(FB_CLIENT_ID)
payload = {"access_token": APP_ACCESS_TOKEN, "object": "user", "fields": "feed", "verify_token": VERIFY_TOKEN, "callback_url": CALLBACK_URL}
r = requests.post(payload_url, data=payload)
return r.text
#app.route('/', methods=['GET','POST'])
def handle_requests():
global VERIFY_TOKEN
if request.method == 'GET':
mode = request.args.get('hub.mode')
challenge = request.args.get('hub.challenge')
verification = request.args.get('hub.verify_token')
# if we have our verification token back echo the challenge back to facebook
if verification == VERIFY_TOKEN:
return challenge
elif request.method == 'POST':
# do some stuff with the updates
I'm confused as to why I'm getting
{"error":{"message":"(#2200) callback verification failed: Operation timed out after 6000 milliseconds with 0 bytes received","type":"OAuthException","code":2200}}
because when I fire up my flask application I can see a GET request from 173.252.110.113, which is a Facebook IP address. I have properly tested to make sure I'm echoing back the correct data by printing the challenge to my log for testing. So the code IS returning the challenge which facebook requires to verify subscription and at that point the subscription SHOULD be successful, but the aforementioned error is what I'm getting. Could it possibly just be a security issue I need to add a permission for in ec2 security groups or something??
Thanks in advance for the help!
ANSWER:
Facebook without forewarning sends multiple requests to the endpoint in question and with the Flask development server those requests have no way of being handled, therefore the timeout. I fired up a gunicorn server with a few workers to test that theory and it proved to be true because I now have a successful subscription verification. For anyone else having this issue with flask:
$ sudo pip install gunicorn
$ which gunicorn
/usr/local/bin/gunicorn
# fire up your endpoint with a few gunicorn workers to handle the load
# facebook tests our endpoint with (we will use 4 workers on port 5000)
# my_app is your_app_name.py without the .py part
$ /usr/local/bin/gunicorn -w 4 -b my-local-ipv4-ip:5000 my_app:app
"https://graph.facebook.com/{0}/subscriptions".format(FB_CLIENT_ID)
is for getting current subscriptions by GET method
to make new subscription you can try :
"https://graph.facebook.com/{0}/".format(FB_CLIENT_ID)
by POST method --- import : is do not include subscriptions at the end url

Categories

Resources