Telegram BOT webook sending empty POST - django

I'm trying to get the payload of the webhook in a BOT in Django.
#csrf_exempt
def webhook(request):
print(request.get_full_path())
print(request.POST)
print(request.GET)
return HttpResponse("OK")
The webhook calls are working fine
{"ok":true,"result":{"url":"...","has_custom_certificate":false,"pending_update_count":0,"last_error_date":1516490058,"last_error_message":"Wrong response from the webhook: 503 Service Unavailable","max_connections":40}}
(last_error_message was solved)
<QueryDict: {}>
<QueryDict: {}>
[20/Jan/2018 23:16:17] "POST /webhook/secure/ HTTP/1.1" 200 2
But above text is what I'm getting in the POST and GET method each time I get a message. Always empty. Maybe I'm missing something in the Telegram part, since I've made a POST request to the same URL and it's printing correct information.

You have to POST testing data to your own server in order to know if there have something wrong.
Here are some payloads you can execute by curl, or this Android application have webhook debugger for new developers.

Related

How to get flask abort code from within after_request function?

I have a problem and after a few hours of searching I can't find a solution.
I have a flask based API. Under normal flow it works like this:
before_request handler is used to validate things like the customer and their API key etc.
Then the requested endpoint function is called
I then use after_request to log various stats about the API call
That all works great.
The problem is when I need to call abort during the before_request. For example, abort(404)
In this situation, the User receives the abort status error code (404) and the execution continues to the after_request handler (as expected)
My issue is that I cant work out how to "know", from within the after_request handler, that the request has been aborted.
Within the after_request function the response object has a status_code of 200, not 404 - I assume because the endpoint was never called and 200 is its default setting.
I either need the response object to reflect the actual code that was returned to the end-user or have some way of knowing that the abort/exception occurred.
Any suggestions?
I found the problem.
I had forgotten to return the error code as part of my custom error handler.
I am seeing different result than you are:
from flask import Flask, request, abort
def create_app(config_file=None):
app = Flask(__name__)
app.debug = True
#app.before_request
def before_request():
print("Before request: pre 404")
abort(404)
print("Aborts before getting to this")
#app.after_request
def after_request(request):
print("After request: pre")
print(request.status_code) # <-- this is 404
print("After request: post")
return request
#app.route('/')
def index():
return "This string never makes it screen"
return app
Before request: pre 404
After request: pre
404
After request: post
127.0.0.1 - - [19/Nov/2021 15:01:03] "GET / HTTP/1.1" 404 -
What is your setup and what is the result for what you are seeing with comparable code?

Test REST service based on request.user

I build SPA on Django and I want to GET and POST JSON data based on request.user.
Something like this:
def get(self, *args, **kwargs):
return {
"data": [
i.get_json() for i in Customer.objects.filter(pk=self.request.user.pk)]
}
But I confuse, how it possible to put my user in request by REST service, like "Postman" or "Curl".
Postman has "Authorization" field, so I put login and password into it and my headers update with:
Authorization Basic YWdlbmN5X3NwYUBtYWlsLnJ1OjExMTEx
And I test it with curl:
curl -u myuser:11111 http://127.0.0.1:8000/api/myurl/
But user still - AnonymousUser
It could work with angular later, but I don't understand how I can test it now.
I found solution. I need to login with my user first and take sessionid from Cookie, then put sessionid in request.
Postman has nice extension named "Postman Interceptor", it put all session from browser into request authomaticly.

How to parse request in django

Hi i am making an webserver , In which I have to hit some request from html page and return the response. The URL which is generated using html is
http://192.168.2.253:8080/searchSMS/?KPImsgId=0&circle=&subId=&startDate=DD-MM-YYYY&endDate=DD-MM-YYYY&Username=ashish
but in the server side I am not able to see the request data. I am using
q = QueryDict(request.body) but it is showing <QueryDict: {}>
How to find the all the parameters coming in request.
In your case you send the data in url so access the data through request.GET as follow:
username = request.GET.get('Username')
start_date = request.GET.get('startDate')
# ... the same for all the other parameter after the `?` marque.
In fact there is a difference between request data, request.body, request.GET and request.POST:
If you are sending POST request to django function view or class based view: you access the request data in request.body or request.POST.
If you are sending POST request to Django REST Framework: you access the data in request.data. You may also find in Internet request.DATA that correct but it's deprecated in the newer version of DRF in favor of request.data.
If you send parameter in the url like in you case, you access the data form request.GET as explained above.

Process Paypal IPN in Django view

According to the PayPal IPN documentation, you have to respond to an IPN by first sending an empty HTTP 200 response to https://www.sandbox.paypal.com/cgi-bin/webscr and then send an HTTP POST request. The only way I could figure out to send an HTTP 200 response was by returning HttpResponse('') in the view, which works since the IPN simulator says the "IPN was sent and the handshake was verified." But then how would I send the HTTP POST request when the view has already returned? My plan was to use urllib2 to generate the POST request.
I also would like to send an HTTP 200 response without using HttpResponse('') since I don't know where the original request is coming from, and I want to be sure that I'm sending the response to https://www.sandbox.paypal.com/cgi-bin/webscr. I've looked at urllib2, requests, and PyCurl, and I've been unable to find a way to create an empty response to a particular URL.
You want to use requests or urllib2 to make a POST request to verify the IPN before you return the HttpResponse(''); the docs imply you have to do it in the opposite order, but you don't actually have to, and this way is a lot simpler in most web frameworks. So your view should look vaguely like
def ipn(request):
verification = requests.POST(PAYPAL_URL, data=request.body)
if verification.text == 'VERIFIED':
# process IPN
return HttpResponse('')
else:
return HttpResponseForbidden()
Note that if this errors somewhere, you will return a 500 to PayPal, and they will retry. If you do this too much, they will get annoyed at you and eventually deactivate your account, so make sure you are getting alerted of the error in some fashion. (You could also wrap things in a try/except block, but then you risk returning a 200 without actually doing your processing if there's an error, which may be worse.)
just respond to the request made by paypal. for the other requests no response (403 http status)
from django.http import HttpResponseForbidden
def answer_to_pp_ipn():
# ...
if 'paypal' in request.META['HTTP_HOST']:
return HttpResponse('OK 200')
return HttpResponseForbidden()
and as you mentioned, requests is the perfect choice to make a post request.

How to debug Django PayPal IPN?

I'm using this django app to implement PayPal IPN. I'm testing it using PayPal's IPN simulator, but it's telling me
IPN delivery failed. HTTP error code 500: Internal Server Error
So how can I debug this and see what's really going on? I've dug into code:
#require_POST
def ipn(request, item_check_callable=None):
"""
PayPal IPN endpoint (notify_url).
Used by both PayPal Payments Pro and Payments Standard to confirm transactions.
http://tinyurl.com/d9vu9d
PayPal IPN Simulator:
https://developer.paypal.com/cgi-bin/devscr?cmd=_ipn-link-session
"""
flag = None
ipn_obj = None
form = PayPalIPNForm(request.POST)
if form.is_valid():
try:
ipn_obj = form.save(commit=False)
except Exception, e:
flag = "Exception while processing. (%s)" % e
else:
flag = "Invalid form. (%s)" % form.errors
if ipn_obj is None:
ipn_obj = PayPalIPN()
ipn_obj.initialize(request)
if flag is not None:
ipn_obj.set_flag(flag)
else:
# Secrets should only be used over SSL.
if request.is_secure() and 'secret' in request.GET:
ipn_obj.verify_secret(form, request.GET['secret'])
else:
ipn_obj.verify(item_check_callable)
ipn_obj.save()
return HttpResponse("OKAY")
All looks fine and dandy there, but since it's not sending a response to my browser, it's kinda tricky to debug. What should I do? I'm trying to look at my apache logs, but it really isn't telling me much.
216.113.191.33 - - [06/Mar/2010:14:10:30 -0600] "POST /paypal/ipn HTTP/1.0" 500 16282 "-" "-"
I tried to send emails and log messages when this view was called, but neither wanted to work. It's possible that I entered the wrong URL into the IPN simulator :) I disabled the "post required" decorator and went to the page directly to see what was going on. My system started to logging "invalid transactions" as expected (since there was no post-data) and then I took a random stab in the dark and figured that Django's CSRF protection was kicking in and preventing PayPal from sending me the data. Adding the #csrf_exempt decorator seems to have fixed it. Yay for guessing errors.
In your django settings.py file, set DEBUG = False
Then for any HTTP 500s (incl. for those being returned to PayPal), you'll be sent a debugging email with all the python stack information.
You'll need to have Django email already set up for this to work, see http://docs.djangoproject.com/en/dev/howto/error-reporting/ for more info on that
You can install a Poster Add-on and make a POST to IPN notify_url from the browser. You will get a Response with all errors. Pretty helpful for debugging.
I just ran into the same problem and this was what I did wrong. Just in case anyone else is as silly as me...
Do not change the method signature from the wiki's
def show_me_the_money(sender, **kwargs):
to something like
def show_me_the_money(ipn, **kwargs):
Reason: in paypal.standard.ipn.models.PayPalIPN.send_signals the listeners are being called with a named argument: payment_was_successful.send(sender=self)
Therefore the method has to have an argument called sender.
I recall having hit (something like) this when using django-paypal too. I can't remember for sure what my cause was, but have you created/migrated the appropriate IPN tables in your database after including the ipn app in your setttings.py?