In Flask ignore all webhooks but one - python

I have a python script with flask incorporated running on a RaspberryPi. This is set to trigger a wakeonlan script when IFTTT sends the appropriate POST webhook. Since I've turned it on I've been getting a LOT of random webhooks from random IPs. Obviously, they all get a 404 error as nothing else is active, but it still concerns me a bit.
Is there a way to make flask ignore (just completely not respond) to any webhooks that aren't the specific one (a POST to /post) I'm looking for? I've tried screwing with the return line, but then flask throws an error saying "View function did not return a response" and returns an error 500.
Is this even possible?
#!/usr/bin/env python3
from flask import Flask, request
from wakeonlan import send_magic_packet
from datetime import datetime
app = Flask(__name__)
dt = datetime.now()
print("WakeOnLan started at: ", dt)
#app.route('/post', methods= ["POST"])
def post():
print("POST received at: ", dt)
body = request.get_data(as_text=True)
if body == "desktop":
send_magic_packet('XX.XX.XX.XX.XX.XX')
print("Magic Packet sent to", body, "at:", dt)
return ''
#Router forwards port 80 to 30000 on the pi
app.run(host='0.0.0.0', port = 30000)

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

JavaScript EventSource triggers onerror after every received message

I have a web app utilizing Python Flask where I am trying to use Server Sent Events (SSEs) to push messages to web pages without having to poll from the client side or request that data. I'm using Redis to listen for new data which will then be sent to the web page. To start and make sure that I can use SSEs correctly, I've used a template similar to an example like this (How to implement server push in Flask framework?).
The problem I'm running into is that every time the client receives a message, the EventSource onmessage() method is called and delivers the message properly, but then the .onerror() method immediately gets triggered, causing the client to try to reconnect. This results in the '/listen' endpoint being called over and over and over, leading to the creation of many redis pubsub objects that are redundant and subscribe to the same channels.
The python code that runs the flask app is as follows
import flask
from flask_bootstrap import Bootstrap
from redis import Redis
from flask_wtf import FlaskForm
app = flask.Flask(__name__)
bootstrap = Bootstrap(app)
red = Redis(host='localhost', port=6379, db=0)
#app.route('/listen')
def listen():
pubsub = red.pubsub()
pubsub.subscribe('chat')
def stream():
for message in pubsub.listen():
if message['type'] == 'message':
msg = f"data: {message['data'].decode('utf-8')}\n\n"
yield msg
for msg in stream():
return Response(msg, mimetype='text/event-stream')
#app.route('/sse_page', methods=['GET', 'POST'])
def sse_page():
form = FlaskForm()
return render_template('sse_page.html', title='Server Push Testing', form=form)
if __name__ == "__main__":
app.run(port=8000, threaded=True, debug=True)
The corresponding section of sse_page.html where I try to open the EventSource and listen for the events stream is
<body>
<div id="target_div">Watch this space...</div>
</body>
<script>
var source = new EventSource("/listen");
source.onmessage = function (event) {
console.log('data: ', event)
$("#target_div").text(event.data)
};
source.onerror = function (event) {
console.log('error ', event)
};
source.onopen = function (event) {
console.log('open', event)
};
</script>
Using the redis-cli to send messages like those seen
here (and transcribed below)
127.0.0.1:6379> publish chat a
(integer) 1
127.0.0.1:6379> publish chat b
(integer) 2
Result in the console logging messages from Eventsource.onopen(), Eventsource.onmessage(), and Eventsource.onerror() for every single message, as seen
here.
I cannot figure out why the eventsource has an error after every single message that is received or how to prevent that from happening.
The answer to this question is NOT a problem in the code itself.
What this ended up being was an issue with the anti-virus security that was being used on the machine. Using Sophos AV Endpoint was causing each SSE to be treated as a download, and so any of the text data was unable to be streamed until the 'download was complete'.
This is (apparently) a known issue (see link https://community.sophos.com/on-premise-endpoint/f/sophos-endpoint-software/74878/server-sent-events-blocked-by-download-scanner) and there are a couple of ways to deal with it. You can either disable web scanning by Sophos (which does not work if you do not have administrator permissions) or run the flask app securely over HTTPS (https://blog.miguelgrinberg.com/post/running-your-flask-application-over-https has a great tutorial).
Credit too should go to this post (JavaScript EventSource SSE not firing in browser), which is how I was able to find that the AV software was what ended up causing my issues.

Python flask error code 400, message Bad request version

The code of the website
from flask import *
app = Flask(__name__)
#app.route("/<name>")
def user(name):
return f"Hello {name}!"
#app.route("/")
def home():
return render_template("index.html")
#app.route("/admin")
def admin():
return redirect(url_for("home"))
if __name__ == "__main__":
app.run()
If I go to http://127.0.0.1:5000/ there are not issues but when I go to https://127.0.0.1:5000/ (https not http this time) I get the following error
127.0.0.1 - - [17/Nov/2019 17:43:25] code 400, message Bad request version ('y\x03Ðã\x80¨R¾3\x8eܽ\x90Ïñ\x95®¢Ò\x97\x90<Ù¦\x00$\x13\x01\x13\x03\x13\x02À+À/̨̩À,À0À')
The error code 400, message Bad request version is basically what I expected since I have not set up SSL nor have I declared what the website should do when getting a https request. What I am curious to find out is what the weird symbols mean (y\x03Ð.... and so on). This goes out to multiple questions such as: Where do they come from? Have the python code attempted to access a random memory location with no specific data? Is the data just in a format that the console cannot handle? What does it mean? You get the idea.
You're missing the ssl_context in app.run() which configures Flask to run with HTTPS support.
See the this article about it
If this is just for testing, you can use adhoc mode.
if __name__ == "__main__":
app.run(ssl_context="adhoc")

Twilio SMS Response - Python Quickstart Guide - 404 Not Found

Following the Twilio SMS Python Quickstart guide found here:
https://www.twilio.com/docs/sms/quickstart/python
I can get up to the "Receive and reply to inbound SMS messages with Flask" section perfectly fine, with both my http://localhost:5000/ and ngrok URL showing the correct "Hello World" message.
However, as soon as I replace the run.py file code with the instructed code to reply to the sender with an sms, both URLs become dead with a "404 Not Found" error.
Have tried restarting everything etc.
run.py:
# /usr/bin/env python
# Download the twilio-python library from twilio.com/docs/libraries/python
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
app = Flask(__name__)
#app.route("/sms", methods=['GET', 'POST'])
def sms_ahoy_reply():
"""Respond to incoming messages with a friendly SMS."""
# Start our response
resp = MessagingResponse()
# Add a message
resp.message("Ahoy! Thanks so much for your message.")
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
Any ideas?
As soon as I change the run.py code back to the original "Hello World" code both URLs run fine.
Also, the ngrok server does show an attempted connection when I send an sms message to the twilio number too, but with a "404 Not Found" message next to it.

Alexa - Python, There was an error calling the remote endpoint, which returned HTTP 404 : NOT FOUND

I am using flask with python to develop my code for an Alexa skill which fetched Wikipedia data. I am also using Wikipedia library of Python.
Every time I try to test my skill Service simulator gives an error. Please help me find the error.
"There was an error calling the remote endpoint, which returned HTTP 404 : NOT FOUND"
from flask import Flask
from flask_ask import Ask, statement, question, session
import json
import requests
import time
import unidecode
import wikipedia
app = Flask(__name__)
ask = Ask(app,"/wiki_reader")
def get_wikisummary(searchitem):
summ=wikipedia.summary(searchitem,sentences=3)
sober=[unidecode.unidecode(summ)]
return sober
#app.route('/')
def homepage():
return "hi there, how ya doin?"
#ask.launch
def start_skill():
welcome_message='Hi, ask me about any country of the World'
return question(welcome_message)
#ask.intent("AnswerIntent")
def answer(ans):
summ1=get_wikisummary(ans)
summ2=[unidecode.unidecode(summ1)]
return statement("{}",format(summ2))
if __name__=='__main__':
app.run(debug=True)
I am using ngrok to host code which is currently hosted on localhost, on my machine.
I just figured out I was trying to run multiple codes on a single port. This is why it was giving not found error.

Categories

Resources