I would like to write an api with django rest framework, I got some issues with my callback function.
I can get the access code, but how to give it to my app?
This is my callback function :
#api_view(['GET'])
def callback(request):
if request.method == 'GET':
code = request.GET.get("code")
encoded_credentials = base64.b64encode(envi.SECRET_ID.encode() + b':' + envi.SECRET_PASS.encode()).decode("utf-8")
token_headers = {
"Authorization": "Basic " + encoded_credentials,
"Content-Type": "application/x-www-form-urlencoded"
}
token_data = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "http://127.0.0.1:800/callback"
}
test = "test :" + code
return JsonResponse(test, safe=False)
And this is my view where I try to do some stuff (I use spotify's API, with spotipy), I need to get the users name or mail :
#api_view(['GET'])
#permission_classes([permissions.IsAuthenticated])
def test(request):
if request.method == 'GET':
test = "test " + request.user.username
scope = "user-read-private"
sp = getScope(scope)
print(sp.current_user())
urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=envi.SECRET_ID, client_secret=envi.SECRET_PASS, redirect_uri=envi.SPOTIPY_REDIRECT_URI))
artist = sp.artist(urn)
print(artist)
user = sp.current_user()
return JsonResponse(user, safe=False)
def getScope(spotipyScope):
token = SpotifyOAuth(scope=spotipyScope,client_id=envi.SECRET_ID, client_secret=envi.SECRET_PASS, redirect_uri=envi.SPOTIPY_REDIRECT_URI)
spotifyObject = spotipy.Spotify(auth_manager= token)
return spotifyObject
When I do a get on 127.0.0.1:8000/test/, I have a new page on my browser, from spotify, I connect my account, and then, it redirects me on 127.0.0.1:8000/callback/?code=some_code
How can I give it to my first page waiting for the code so I can print the users stuff pls?
Related
If I go into my firebase console and setup a campaign my end devices receive the notification just fine, but for messages to specific devices using the device's registration token, sent from django/python, I get no notification on my mobile devices.
Not sure if this matters but my app is still in development, it is not in production, so if this matters please let me know.
My frontend is flutter, here is the flutter code I am using to get the registration token and send it to the backend:
Future<StreamedResponse> AddProductPut(context, pk, name, quantity, cost, selling, XFile? chosenImage) async {
String id_token = await FirebaseAuth.instance.currentUser!.getIdToken();
late String? fcm_token;
await FirebaseMessaging.instance.getToken().then((token) async {
fcm_token = token!;
}).catchError((e) {
print(e);
});
print(fcm_token);
var url = backend + "/pm/createproduct/" + pk.toString() + "/";
var request = http.MultipartRequest('PUT', Uri.parse(url));
print("FCM TOKEN");
print(fcm_token);
request.headers["Authorization"] = "Token " + id_token;
request.fields["name"] = name;
request.fields["quantity"] = quantity.toString();
request.fields["cost_price"] = cost.toString();
request.fields["selling_price"] = selling.toString();
request.fields["barcode"] = "11111";
request.fields["token"] = fcm_token!;
request.files.add(
await http.MultipartFile.fromPath(
'image',
chosenImage!.path
)
);
return await request.send();
}
Here is the python code in my django serializer to send the notification message:
registration_token = self.context['request'].data["token"],
print(registration_token[0])
print(type(registration_token[0]))
# See documentation on defining a message payload.
message = Message(
notification=Notification(
title='New Product Added',
body='A new product called ' + validated_data['name'] + ' has been added to your account.',
),
token=registration_token[0]
)
# Send a message to the device corresponding to the provided
# registration token.
response = send(message)
print(response)
I am not getting any errors in my django/python console when sending this message, and response prints something like this:
projects/<project name>/messages/16641.......0329
My registration token is something like this:
cmLYCAbL0EsJrxppKzXvhF:APA..............qdt5ySYLbkQC_bpqwL6RdCwSzK_tX8iclp-e0QZB................lgw9g2eFNzfXpn2C4U................UnMphyWa6L9d-wUg
Not sure what the problem is, but I am receiving FCM messages on Apple and Android now...
registration_token = subuser.fcm
print(registration_token)
message = Message(
notification=Notification('Added As A Sub-User', f'A user with the phone {instance.userprofile.phone} has added you to their account as a sub user.'),
token=registration_token
)
and my flutter code that updates the database with the user's fcm registration token...
FirebaseMessaging.instance.getToken().then((token) async {
print(token);
String id_token = await FirebaseAuth.instance.currentUser!.getIdToken();
String uid = await FirebaseAuth.instance.currentUser!.uid;
final result = await http.put(
Uri.parse(backend + "/pm/setfcm/" + uid + "/"),
headers: {
"Content-Type": "application/json",
"Authorization": "Token " + id_token
},
body: jsonEncode({
"fcm": token,
})
);
}).catchError((e) {
print(e);
});
FirebaseMessaging.instance.onTokenRefresh.listen((newToken) async {
print(newToken);
String id_token = await FirebaseAuth.instance.currentUser!.getIdToken();
String uid = await FirebaseAuth.instance.currentUser!.uid;
final result = await http.put(
Uri.parse(backend + "/pm/setfcm/" + uid + "/"),
headers: {
"Content-Type": "application/json",
"Authorization": "Token " + id_token
},
body: jsonEncode({
"fcm": newToken,
})
);
});
response = send(message)
print(response)
my view is like :
def get_user_pending_order(request):
user_profile = get_object_or_404(Profile, user=request.user)
order = Order.objects.filter(owner=user_profile, is_ordered=False)
if order.exists():
return order[0]
return 0
MERCHANT = 'xxx...xxx'
ZP_API_REQUEST = "https://api.zarinpal.com/pg/v4/payment/request.json"
ZP_API_VERIFY = "https://api.zarinpal.com/pg/v4/payment/verify.json"
ZP_API_STARTPAY = "https://www.zarinpal.com/pg/StartPay/{authority}"
amount = ''
description = "text" # Required
email = 'example#email.com' # Optional
mobile = '09999999999' # Optional
# Important: need to edit for realy server.
CallbackURL = 'https://example.com/payment/verify/'
def send_request(request):
print(get_user_pending_order(request).owner.phone_number)
req_data = {
"merchant_id": MERCHANT,
"amount": int(get_user_pending_order(request).get_total()),
"callback_url": CallbackURL,
"description": description,
"metadata": {"mobile": mobile,
"email": email}
}
req_header = {"accept": "application/json",
"content-type": "application/json'"}
req = requests.post(url=ZP_API_REQUEST, data=json.dumps(
req_data), headers=req_header)
authority = req.json()['data']['authority']
if len(req.json()['errors']) == 0:
return redirect(ZP_API_STARTPAY.format(authority=authority))
else:
e_code = req.json()['errors']['code']
e_message = req.json()['errors']['message']
return HttpResponse(f"Error code: {e_code}, Error Message: {e_message}")
def verify(request):
t_status = request.GET.get('Status')
t_authority = request.GET['Authority']
if request.GET.get('Status') == 'OK':
req_header = {"accept": "application/json",
"content-type": "application/json'"}
req_data = {
"merchant_id": MERCHANT,
"amount": int(get_user_pending_order(request).get_total()),
"authority": t_authority
}
req = requests.post(url=ZP_API_VERIFY, data=json.dumps(req_data), headers=req_header)
if len(req.json()['errors']) == 0:
t_status = req.json()['data']['code']
if t_status == 100:
user = request.user
order_to_purchase = get_user_pending_order(request)
order_to_purchase.is_ordered = True
order_to_purchase.date_ordered=datetime.datetime.now()
order_to_purchase.created_on_time=datetime.datetime.now()
order_to_purchase.save()
order_items = order_to_purchase.items.all()
for order_item in order_items:
order_item.product.quantity = order_item.product.quantity - 1
order_item.product.save()
order_items.update(is_ordered=True, date_ordered=datetime.datetime.now())
subject = 'successful'
c = {
"refid":str(req.json()['data']['ref_id']),
"ref_code":order_to_purchase.ref_code,
"owner":order_to_purchase.owner,
}
email_template_name = "pay/after_pay_confirm_email.html"
email_html = render_to_string(email_template_name, c)
email_from = settings.EMAIL_HOST_USER
send_mail(subject, email_html, email_from, [user.email], html_message=email_html)
ctx = {'message_good':'good'}
return render(request, 'pay/verify.html', ctx)
elif t_status == 101:
...
else:
....
else:
...
else:
...
At first about user, is logged. and about send_request function it work totally fine...so it pass user into Payment gateway and after successful payment it come back to verify function by CallbackURL. to show success page and do order_to_purchase.is_ordered = True ...
for me with my pc, phone, other android phones, ios, windows, linux. and about browsers like chrome Firefox it work correctly and everything is fine.
but some clients tell me they face to 'AnonymousUser' object is not iterable after successful payment and when they back to verify. its kinda like that they logged out by pushing request to payment gateway.
also i made purchase by that account exactly same way and i didn't face to that error. it show is that phone or browser problem that half of my clients faced to that. i have no idea what should i do!!!
I am working with Postman for the first time and GET request to my simple API is working fine, but when I try POST request it gives me an error and I have no idea where is the problem. Can you please advise?
API function:
#app.route('/customer', methods=['POST'])
def create_customer():
request_data = request.get_json()
new_customer = {
"email": request_data['email'],
"username": request_data['username'],
"name": request_data['name'],
"newsletter_status": request_data['newsletter_status'],
"trips": []
}
for customer in customers:
if customer['username'] == new_customer['username']:
return jsonify({'error': 'username already exist'})
customers.append(new_customer)
return jsonify(new_customer)
Screenshots from postman
This I put in the body + error message
Headers set up - Content-Type application/json
I think your new customer variables should not be in string format, I don't know why they are and also try my option for getting the request body:
import json
def create_customer():
request_data = json.loads(request.body)
new_customer = {
email = request_data['email'],
username = request_data['username'],
name = request_data['name'],
newsletter_status = request_data['newsletter_status'],
trips: []
}
for customer in customers:
if customer['username'] == new_customer['username']:
return jsonify({'error': 'username already exist'})
customers.append(new_customer)
return jsonify(new_customer)
Yur code works fine , i just tested with postman:
from flask import jsonify
from flask import Flask
from flask import request
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
#app.route('/customer', methods=['POST'])
def create_customer():
customers=[]
customers.append(request.get_json())
request_data = request.get_json()
new_customer = {
"email": request_data['email'],
"username": request_data['username']+"HHH",
"name": request_data['name'],
"newsletter_status": request_data['newsletter_status'],
"trips": []
}
print(new_customer['username'])
print(customers[0]['username'])
for customer in customers:
if customer['username'] == new_customer['username']:
return jsonify({'error': 'username already exist'})
customers.append(new_customer)
return jsonify(new_customer)
Can you check what is exactly send in postman ?
you can do it by clicking console ( can get from left botom corner or by pressing ctrl+alt+c ) >request > requestbody
I'm attempting to submit my form, but it continually fails as there's something wrong with the POST. I'm unsure where/what exactly is causing the server to not process the request whether it's related to syntax, request routing, etc. I've also commented out every line related to file uploads, as well as comment out the if (validated) statement. There are no errors in the console as a result of this, but the form submission still fails. I'd appreciate any help/direction thanks.
I get this error message when I submit the form:
POST http://127.0.0.1:5051/register/ 400 (BAD REQUEST)
views.py
#blueprint.route("register/", methods=['GET', 'POST'])
def register():
"""Renders register page."""
form = RegisterForm()
if request.method == 'POST':
if not form.validate_on_submit():
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
ticket, err = create_ticket2(customer_id, organization + "\n" + venue_name + "\n" + street + "\n" + country + "\n" + teamviewquestion + "\n" + teamviewerid + "\n" + deviations + "\n" + deviationsnotes + "\n" + displaydirector + "\n" + composer + "\n" + decryptor + "\n" + motionrocket + "\n" + othersoftware,
location=location)
if err:
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=False, message=err, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
else:
success_msg = "Error"
.format(ticket.get('id'))
return render_template('main/register.html', page_title="Service Registration",
form=form, form_success=True, message=success_msg, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
return render_template('main/register.html', page_title="Service Registration",
form=form, media_types=current_app.config["ACCEPTED_"
"MEDIA_TYPE"])
"""Handles file upload POSTs."""
first_name = request.form.get("first_name")
last_name = request.form.get("last_name")
name = request.form.get("first_name") + " " + request.form.get("last_name")
email = request.form.get("email")
filename = request.form.get("filename")
file_type = request.form.get("file_type")
if filename == '':
response = make_response("No selected file")
return response, 400
if check_file_type(file_type):
filename = clean_filename(filename)
filename = secure_filename(filename)
filename = unique_filename(filename)
response = generate_presigned_post(filename, file_type)
# CREATE DB REFERENCE
url = "http://nevcodocs.s3.amazonaws.com/Uploads/{}".format(filename)
instance = CustomerFileUpload.query.filter_by(url=url).first()
if not instance:
instance = CustomerFileUpload(url=url, email=email, name=name)
db.session.add(instance)
db.session.commit()
else:
instance.update(created_at=datetime.utcnow())
return response, 200
js (ticket submission function)
$('#ticket-form').submit(function(event) {
if (validated) {
$('#filename').val($('#upload').val());
$.ajax({
type: 'POST',
url: '/register/',
data: $('#ticket-form').serialize()
}).done(function(data) {
var formData = new FormData();
for (var key in data.data) {
formData.append(key, data.data[key]);
}
formData.append('file', $('#upload').prop('files')[0]);
formData.append('csrf_token', '{{ csrf_token }}');
var req = new XMLHttpRequest();
req.onload = function() {
showSpinner(false);
$('#ticket-form').removeClass("support-form-show");
$('#ticket-form').addClass("support-form-hide");
};
req.onerror = function() {
showSpinner(false);
$('#ticket-form-failed').removeClass("support-form-hide");
$('#ticket-form-failed').addClass("support-form-show");
};
req.open('POST', '/register/');
req.send(formData);
}).fail(function(err) {
showSpinner(false);
$('#ticket-form-failed').removeClass("support-form-hide");
$('#ticket-form-failed').addClass("support-form-show");
});
} else {
showSpinner(false);
enableSubmit(true);
}
});
Usually, bad request means that you're trying to fetch data from request object using invalid keys. So you need to make sure that your POST request body (that was sent by javascript) contains all keys which you're using as arguments of request.form.get() method: first_name, last_name, etc...
I have created a fb bot which simply echoes the user input.
I want it to echo the user inputs continuously and stop when the user types in "bye".
How do I do that? Please help out.
Code :
```import os
import sys
import json
import requests
import time
from flask import Flask, request
app = Flask(__name__)
#app.route('/', methods=['GET'])
def verify():
if request.args.get("hub.mode") == "subscribe" and request.args.get("hub.challenge"):
if not request.args.get("hub.verify_token") == os.environ["VERIFY_TOKEN"]:
return "Verification token mismatch", 403
return request.args["hub.challenge"], 200
return "Hello world", 200
#app.route('/', methods=['POST'])
def webhook():
data = request.get_json()
if data["object"] == "page":
for entry in data["entry"]:
for messaging_event in entry["messaging"]:
if messaging_event.get("message"): # someone sent us a message
sender_id = messaging_event["sender"]["id"]
recipient_id = messaging_event["recipient"]["id"]
message_text = messaging_event["message"]["text"]
reply = "Received : " + message_text
if "bye" in message_text.lower():
reply = "Good-bye"
send_message(sender_id, reply)
return "ok", 200
def send_message(recipient_id, message_text):
log("sending message to {recipient}: {text}".format(recipient=recipient_id, text=message_text))
params = {
"access_token": os.environ["PAGE_ACCESS_TOKEN"]
}
headers = {
"Content-Type": "application/json"
}
data = json.dumps({
"recipient": {
"id": recipient_id
},
"message": {
"text": message_text
}
})
r = requests.post("https://graph.facebook.com/v2.6/me/messages", params=params, headers=headers, data=data)
if r.status_code != 200:
log(r.status_code)
log(r.text)
if __name__ == '__main__':
app.run(debug=True) ```
How about return without send_message(sender_id, reply) function? Like this
if "bye" in message_text.lower():
return "bye", 200
This code is very similar to yours, except the fact that I used class based view
To break the loop add fbid of the user in a file or a DB after he/she says bye.
Everytime a message is posted check fbid to see whether user had already said "bye". If yes return empty response
def post_facebook_message(fbid, recevied_message):
"""
takes a user fb id and posts the bot message as response
"""
post_message_url = 'https://graph.facebook.com/v2.6/me/messages?access_token='+PAGE_ACCESS_TOKEN
response_msg = json.dumps({"recipient":{"id":fbid}, "message":{"text":recevied_message}})
status = requests.post(post_message_url, headers={"Content-Type": "application/json"},data=response_msg)
print status.json()
class FBBotView(generic.View):
#this is to verify your FB account with your program
#use ythe same verify token used while registering the bot
#method_decorator(csrf_exempt)
def get(self, request, *args, **kwargs):
if self.request.GET['hub.verify_token'] == VERIFY_TOKEN:
return HttpResponse(self.request.GET['hub.challenge'])
else:
return HttpResponse('Error, invalid token')
#method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return generic.View.dispatch(self, request, *args, **kwargs)
# Post function to handle Facebook messages
def post(self, request, *args, **kwargs):
# Converts the text payload into a python dictionary
incoming_message = json.loads(self.request.body.decode('utf-8'))
# Facebook recommends going through every entry since they might send
# multiple messages in a single call during high load
for entry in incoming_message['entry']:
for message in entry['messaging']:
# Check to make sure the received call is a message call
# This might be delivery, optin, postback for other events
if 'message' in message:
if recieved_message.lower() == "bye":
#sends an empty response
message = "Good bye"
post_facebook_message(message['sender']['id'],message)
#this line is important because many times FB checks validity of webhook.
return HttpResponse()