Get picture profile user with getUserProfilePhotos in Telegram - python

I am trying to save the photos of the users of a Telegram bot (a game), using the getUserProfilePhotos method
I am testing it with my own id_user. The code:
def getUserProfilePicture (self, user : User):
if (user is None) : return None
requestStr = self.httpbase + self.token + "/getUserProfilePhotos"
par ={
"user_id" : user.id, #correct id passed.
"limit" : 5
}
dataReq = requests.post(requestStr, json=par)
updateData = json.loads(dataReq.content)
isOk = updateData.get("ok")
And the result (I have also tried with Postman, passing my user id, with and without the limit parameter):
{
"ok": true,
"result": {
"total_count": 0,
"photos": []
}
}
This is not the correct result. In my profile I have 3 images. I have tried with other profiles, and the result is the same: 0 images, and an empty array.
The link to the API is as follows: link getUserProfilePhotos method
Any idea?
Thank you.

If your privacy settings say that only your contacts can see your profile pictures, the bot can't see your profile picture (because you can't add it as contact).
Forgot about that when commenting …

Related

Django + React axios POST cant access Json properties

I created two abjects that need to be treated separated in the backend, and sent it to backend with:
const order = {
order_id: 1,
customer: {
name: "Jonas Illver"
age: 18
}
}
const car = {
model: 'XHL'
brand: 'Toyota'
}
const postData = {
order: order,
car: car
}
const res = await axios.post("orders/shipping/create", JSON.stringify(postData));
console.log(res);
And here I return the response: views.py
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def shipping_create_order(request):
if request.method == 'POST':
return JsonResponse(request.POST)
Here's what the console.log prints:
res.data // {"order:"{"order_id": 1, "customer": {"name": "Jonas Illver", "age": 18}}, "car": **car object content**}
The problem is that if I try to access those data in my django view, I always got a 500 error
I tried accessing it via:
order = request.POST['order']
# and also
data = json.loads(request.POST)
order = data['order']
# also
order = request.POST.get('order')
None os the above approaches worked, the only one that doesn't occurs an 500 error is the last one, using the POST.get, but as soon as I add the if not order: return HttpResponse("No order") line, it always return "No order"
How can I access specific info from the request.POST? Am I doing something wrong with the axios request?
Try using request.data to get the data passed in the body. Have a look at the rest-framework docs.
Or another way to get the data is using json.loads(request.body). But using request.data is a bit shorter as it does the json.loads job for you.

Python - Enum Keys From Another Enum

I have an enum class with the following code:
# enums.py
class AuthCode(Enum):
ALREADY_AUTHENTICATED = 1
MISSING_EMAIL = 2
MISSING_PASSWORD = 3
MISSING_REGISTRATION_TOKEN_CODE = 4
INVALID_EMAIL = 5
REDEEMED_EMAIL = 6
INVALID_PASSWORD = 7
INVALID_REGISTRATION_TOKEN_CODE = 8
REDEEMED_REGISTRATION_TOKEN_CODE = 9
INVALID_CREDENTIALS = 10
SIGNIN_SUCCESSFUL = 11
REGISTRATION_SUCCESSFUL = 12
class AuthCodeMessage(Enum):
AuthCode.ALREADY_AUTHENTICATED = "User was already logged in"
AuthCode.MISSING_EMAIL = "Email was not specified"
AuthCode.MISSING_PASSWORD = "Password was not specified"
AuthCode.MISSING_REGISTRATION_TOKEN_CODE = "Registration token code was not specified"
AuthCode.INVALID_EMAIL = "Email is invalid"
AuthCode.REDEEMED_EMAIL = "An account with this email has been created already"
AuthCode.INVALID_PASSWORD = "Password does not meet minimum password requirements"
AuthCode.INVALID_REGISTRATION_TOKEN_CODE = "Registration token code is invalid"
AuthCode.REDEEMED_REGISTRATION_TOKEN_CODE = "Registration token code has been redeemed already"
AuthCode.INVALID_CREDENTIALS = "Account with these credentials does not exist"
AuthCode.SIGNIN_SUCCESSFUL = "User has been signed in successfully"
AuthCode.REGISTRATION_SUCCESSFUL = "User account has been created successfully"
Is it possible to define the second enum (AuthCodeMessage) the way it is defined (i.e., using another enum as a key). How can I retrieve the enum value?
Edit 1:
I would like to call my this enumeration from my code using the an approach similar to the following:
from enums import AuthCode, AuthCodeMessage
def authResponse(authCode):
AuthCode.ALREADY_AUTHENTICATED
return jsonify({
"code": authCode,
"message": AuthCodeMessage.authCode
})
authResponse(AuthCode.ALREADY_AUTHENTICATED)
What you really want is to map AuthCodes to strings. The usual way to do this in Python is with a dictionary, like this:
AUTHCODE_MESSAGES = {
AuthCode.ALREADY_AUTHENTICATED: "User was already logged in",
# copy the rest of the code/message pairs here
# make sure to replace the = with :
# and add a , on the end of every line
}
You can then use it like so:
# FIXME: enums is not a very clear name for what it does.
from enums import AuthCode, AUTHCODE_MESSAGES
def authResponse(authCode):
return jsonify({
"code": authCode,
"message": AUTHCODE_MESSAGES[authCode]
})
Instead of using two enums, just use one. Using the AutoNumber recipe from the docs (the second one), your code would look like this:
class AuthCode(AutoNumber):
ALREADY_AUTHENTICATED = "User was already logged in"
MISSING_EMAIL = "Email was not specified"
MISSING_PASSWORD = "Password was not specified"
...
def __init__(self, description):
self.description = description
and later on:
def authResponse(authCode):
return jsonify({
"code": authCode.value,
"message": authCode.description,
})
--
Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

im trying to make an api in flask that takes in 2 inputs

ive got an api that takes in an id
http://127.0.0.1:5000/api/v1/resources/books?id=u3qR4Ps4TbATrg97
looks like that
what im trying to do after that is add something to the end of the url, for example
http://127.0.0.1:5000/api/v1/resources/books?id=u3qR4Ps4TbATrg97uid=something
im not 100% sure if this is possible
# Create some test data for our catalog in the form of a list of dictionaries.
books = [
{'id': 'u3qR4Ps4TbATrg97',
'uid': 'what',
'title': 'A Fire Upon the Deep',
'author': 'Vernor Vinge',
'first_sentence': 'The coldsleep itself was dreamless.',
'year_published': '1992'}
]
#app.route('/api/v1/resources/books', methods=['GET'])
def api_id():
# Check if an ID was provided as part of the URL.
# If ID is provided, assign it to a variable.
# If no ID is provided, display an error in the browser.
if 'id' and 'uid' in request.args:
id = str(request.args['id'])
uid = str(request.args['uid'])
else:
return "Error: No id field provided. Please specify an id."
results = []
for book in books:
if book['id'] == id:
results.append(book)
if book['uid'] == uid:
results.append(book)
this is what i have so far, mostly copy pasted from here
thats no the whole file just the important bits i can think of
You can add two inputs inside the GET query like this
http://127.0.0.1:5000/api/v1/resources/books?id=u3qR4Ps4TbATrg97&uid=something
Just put an & in between!
Use request.args.get method to get parameters from your url. Also add & to your URL as a parameter separator.
from flask import Flask, request
app = Flask(__name__)
#app.route('/api/v1/resources/books')
def books():
id_ = request.args.get('id')
uid = request.args.get('uid')
return f'id: {id_}, uid: {uid}'
app.run()
Open http://127.0.0.1:5000/api/v1/resources/books?id=u3qR4Ps4TbATrg97&uid=something
in browser and you'll get:
id: u3qR4Ps4TbATrg97, uid: something
Multiple parameters|arguments are passed with & character. ?params1=5&params2=3. For your example: http://127.0.0.1:5000/api/v1/resources/books?id=u3qR4Ps4TbATrg97&uid=what. For the code, I would do:
from flask import Flask, request, jsonify, make_response
app = Flask(__name__)
# Create some test data for our catalog in the form of a list of dictionaries.
books = [
{
"id": "u3qR4Ps4TbATrg97",
"uid": "what",
"title": "A Fire Upon the Deep",
"author": "Vernor Vinge",
"first_sentence": "The coldsleep itself was dreamless.",
"year_published": "1992",
}
]
#app.route("/api/v1/resources/books", methods=["GET"])
def api_id():
# Check if an ID was provided as part of the URL.
# If ID is provided, assign it to a variable.
# If no ID is provided, display an error in the browser.
if set(["id","uid"]).intersection(set(request.args)):
id_ = str(request.args["id"])
uid = str(request.args["uid"])
else:
return make_response(
jsonify({"message": "Error: No id field provided. Please specify an id."}),
400,
)
results = []
for book in books:
if book["id"] == id_:
results.append(book)
if book["uid"] == uid:
results.append(book)
response = make_response(
jsonify({"message": results}),
200,
)
response.headers["Content-Type"] = "application/json"
return response
This would return status code 400 if no match and 200 when match

How to send JSON payload to create buttons with pymessenger Facebook chatbot

I am creating a Facebook messenger chatbot with pymessenger, flask and wit.at. I want to add buttons as options in my chatbot conversation.
For example
"πŸŽ€ Generic Offer 1"+"\n"+"πŸŽ€ Generic Offer 2"+"\n"+"πŸŽ€ Generic Offer 3"
is what I want to show up as a button to user instead of just text. So the user can select one offer. Facebook has the option to add buttons https://developers.facebook.com/docs/messenger-platform/send-messages/template/button/ via JSON.
I want to do the similar thing. But I don't know how to do it. I can do simple text thing but now this, because I don't know JSON. As of now, my chatbot is replying via bot.send_text_message(sender_id, response).
def webhook():
data = request.get_json()
log(data)
if data['object'] == 'page':
for entry in data['entry']:
for messaging_event in entry['messaging']:
sender_id = messaging_event['sender']['id']
recipient_id = messaging_event['recipient']['id']
if messaging_event.get('message'):
if 'text' in messaging_event['message']:
messaging_text = messaging_event['message']['text']
else:
messaging_text = 'no text'
response = None
entity, value = wit_response(messaging_text)
if entity == 'newstype':
response = "OK. I will send you {} news".format(str(value))
elif entity == 'cust_greet':
response = get_message()
elif entity == 'cust_greet2':
response = get_message2()
elif entity == 'cust_offer':
#response = offer_response
response = "πŸŽ€ Generic Offer 1"+"\n"+"πŸŽ€ Generic Offer 2"+"\n"+"πŸŽ€ Generic Offer 3"+"\n"+" 🏷️ for more offer enter your cust id"
#val_off = test.val_off
bot.send_text_message(sender_id, response)
I think instead of bot.send_text_message, the correct way to send the JSON payload is via bot.send_raw. So using the example from your link you can test if it's working with something similar to:
payload = """{
"recipient":{
"id":"<PSID>"
},
"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"button",
"text":"What do you want to do next?",
"buttons":[
{
"type":"web_url",
"url":"https://www.example1.com",
"title":"Visit Example 1"
},
{
"type":"web_url",
"url":"https://www.example2.com",
"title":"Visit Example 2"
}
]
}
}
}
}"""
bot.send_raw(payload)
Don't forget to replace <PSID>.

Python/Django form where user selects from a list of Images

I'm new to django and want to make a form that allows a user to select one of three images using radio boxes, once the user selects the image it is saved to their profile and displayed on their profile page.
I am using:
django 1.8.3
userena 1.4.1
Any help or links to documentation that will help would be great.
Basic example. Models:
def get_upload(instance, filename):
return "uploaded_files/user_%s_%s_%s" % (instance.user, datetime.datetime.today().strftime("%d-%m-%Y %H-%M-%S"), filename)
class UserModel():
# your fields
image = models.FileField(upload_to=get_upload, default='')
FileField
Forms:
class UploadForm(forms.ModelForm):
"""Auxiliary class to make file uploading more convenient."""
def __init__(self, *args, **kwargs):
super(UploadForm, self).__init__(*args, **kwargs)
class Meta:
model = UserModel
fields = ('image')
View:
def upload(request):
if request.method == "POST":
profile = request.user.profile
image_type = request.POST.get("image_type", None)
if image_type == "blah":
profile.image = request.FILES[image_type]
else:
return HttpResponse("Error")
request.user.profile.save()
return HttpResponse('OK')
request.FILES
JS with soem Jquery:
var SIZE_RESTRICT = 10*1024*1024; //10 Mbytes
$(document).ready(function()
{
$(".upload_file").find(".upload_button").click(send_file);
$(".upload_file").find(".upload_file_form").find("input[type='file']").click(enable_upload);
});
function send_file()
{
if ($(this).attr("enabled") != "true") return;
// Prevent double-triple clicks with multiple upload.
$(this).attr("enabled", "false");
var form = $(this).parent().find(".upload_file_form").get(0);
var formData = new FormData(form);
var file = $(form).find("input[type='file']").get(0).files[0];
// Not sure about this
// Prevent attack with HUGE files, that will smash server memory
// TODO: Restrict file types (Ex. MIME-image, pdf, doc)
if (file.size > SIZE_RESTRICT)
{
alert("File is too big.");
return;
}
formData.append("proof_type", $(this).attr("upload-type"));
var xhr = new XMLHttpRequest();
var that = this;
// TODO: Define another events like error, abort
xhr.upload.onprogress = function(e) {
// TODO: Progressbar as e.loaded / e.total
if (e.lengthComputable)
console.log((e.loaded / e.total) * 100);
else
console.log("Cant count length");
};
xhr.onload = function(e){
// TODO: Show success confirmation to user.
if (this.response == "Success")
{
// pass
alert(this.response);
}
else if (this.response == "Error")
{
// pass
alert(this.response);
}
else
{
// pass
}
};
xhr.open('POST', '/upload_proof');
xhr.send(formData);
}
function enable_upload()
{
$(this).parent().parent().find(".upload_button").attr("enabled", "true");
}
Actually another simple example could be founded in docs
If the set of images is small and fixed, the best option is to use the choice attribute in the field that defines the image within your model.
The image field could be the path to the image file on the file system.
class UserProfile(models.Model):
GOOD = 'Good.jpg'
UGLY = 'Ugly.jpg'
BAD = 'Bad.jpg'
AVATAR_CHOICES = (
(GOOD, 'Good'),
(UGLY, 'Ugly'),
(BAD, 'Bad'),
)
avatar_img = models.CharField(max_length=255,
choices=AVATAR_CHOICES,
default=GOOD)
Another option is to use FilePathField as your model field
FilePathField(path="/path/to/avatar_images", match="*.jpg", recursive=False)
Another way is to fill the form field dynamically when the form is instantiated.
Please see this SO QA for more on that.
However, as Django docs say
But if you find yourself hacking choices to be dynamic, you’re
probably better off using a proper database table with a ForeignKey
To specify Radiobuttons to be used for the form field, please refer to the official docs on how to set the proper widget.

Categories

Resources