Getting user in a app.view() handle method - python

I've have a modal for submitting ticket to trello, everything is working great but i need to output in slack a message to the user that his ticket is published.
In the slack api documentation (chapter 'Listening for view submissions') i can read :
# Handle a view_submission request
#app.view("view_1")
def handle_submission(ack, body, client, view, logger):
user = body["user"]["id"]
When i try the same I've got a KeyError: 'user'. Without that line the code work great but I need the user to know that his ticket is published on Trello and provide him the link (and other informations)
EDIT : I've printed the body dict content and nothing about the user :
{
"id":"XXXXXXXXX",
"team_id":"XXXXXXXXX",
"type":"modal",
"private_metadata":"",
"callback_id":"ticket_submission",
"state":{
"values":{
"block_type":{
"type":{
"type":"static_select",
"selected_option":{
"text":{
"type":"plain_text",
"text":"Feature",
"emoji":true
},
"value":"feature"
}
}
},
"block_priority":{
"priority":{
"type":"static_select",
"selected_option":{
"text":{
"type":"plain_text",
"text":"Critical",
"emoji":true
},
"value":"critical"
}
}
},
"block_description":{
"description":{
"type":"plain_text_input",
"value":"This is the description"
}
},
}
},
"hash":"1674058454.YvY8jNKh",
"title":{
"type":"plain_text",
"text":"Create Ticket",
"emoji":true
},
"clear_on_close":false,
"notify_on_close":false,
"close":{
"type":"plain_text",
"text":"Cancel",
"emoji":true
},
"submit":{
"type":"plain_text",
"text":"Submit",
"emoji":true
},
"previous_view_id":"None",
"root_view_id":"XXXXXXXXX",
"app_id":"XXXXXXXXX",
"external_id":"",
"app_installed_team_id":"XXXXXXXXX",
"bot_id":"XXXXXXXXX"
}

Related

Discord clicking button using api and requests in python not working

I have made this code to make a user interact with a button of my bot’s message, but i am unable to make it work. Please help.I get the following error:
{"code": 50035, "errors": {"session_id": {"_errors": [{"code": "BASE_TYPE_REQUIRED", "message": "This field is required"}]}}, "message": "Invalid Form Body”}
header = {
'authorization': auth
}
r = requests.get("https://discord.com/api/v9/channels/<channel_id>/messages", headers = header)
message = json.loads(r.text)[0]
data = {
"type": 3,
"guild_id": '<guild_id>',
"channel_id": '<channel_id>',
"message_id": message['id'],
"application_id": '<bot_id>', #the id of the bot to which i want to interact
"data": {
"component_type": 2,
"custom_id": message['components'][0]['components'][2]['custom_id'] #gets the custom_id of the button to interact
}
}
r = requests.post('https://discord.com/api/v9/interactions', json = data, headers = header)
Turns out, I need to add a session_id under the data dict, the problem got solved! Thanks furas for your help!
The code now:
data = {
"type": 3,
"guild_id": '<guild_id>',
"channel_id": '<channel_id>',
"message_id": message['id'],
"session_id": '<session_id>', #if you don't know the string, a random string worked for me
"application_id": '<bot_id>', #the id of the bot to which i want to interact
"data": {
"component_type": 2,
"custom_id": message['components'][0]['components'][2]['custom_id'] #gets the custom_id of the button to interact
}
}

Flask-restplus returning marshal model instead of the data

So I'm pretty new to implementing flask-restplus and I have encountered this road block.
I have read the restplus docs over and over again and followed several exampled. But the behavior that I'm facing is very much different from what is supposed to be.
So I have a model that is supposed to be a list of objects of another model (returned from the function drone_model()).
drones_list = api.model('drones_list', {
'items': fields.List(fields.Nested(drone_model())),
'message':fields.String(''),
'code': fields.Integer('')
})
Everything works fine, no errors. But when I try the API (http://127.0.0.1:5000/datamine/v2/drones), as a response I get the Marshalling model back instead of the data itself. If I print the data, it gets printed, but for some reason in the web, the restplus model is returned.
Below I have the code that I had written. If I take the marshal_with decorator off, then the data is returned just fine.
#api.route('/')
class DronesList(Resource):
#api.marshal_with(drones_list, envelope='data')
#api.response(200, 'All drones successfully fetched!')
def get(self):
"""
Get all drones!.
"""
from app.utils.common import get_start_end_date_from_request
start_date, end_date = get_start_end_date_from_request(request)
drones = []
for drone in Drone.objects:
drones.append({
'id': str(drone.id),
'serial_id': drone.serial_id,
'maintenances': [],
'status': get_dynamic_status(drone, start_date, end_date),
'picture_url': drone.asset.picture_url,
'manufacturer': drone.asset.manufacturer,
'model_name': drone.asset.model_name,
'drone_type': drone.asset.drone_type,
'payload_type': drone.asset.payload_type,
'asset_url': drone.get_url(drone.id)
})
success = ClientSuccessFunctionClass('All drones successfully fetched!', 200, drones)
return (success.to_dict())
These are the outputs on the browser:
1. Without the marshal decorator:
{
"data": {
"items": [
{
"id": "5aeafcb93a33683f73827e91",
"serial_id": "Drone 1",
"maintenances": [],
"status": "Decommissioned",
"picture_url": "some img url",
"manufacturer": "DJI",
"model_name": "Phantom 4 Pro",
"drone_type": "Quadcopter",
"payload_type": "RGB Camera",
"asset_url": "http://127.0.0.1:5000/datamine/v1/drones/5aeafcb93a33683f73827e91"
},
{
"id": "5aeaff374f85747f90df2714",
"serial_id": "Drone 2",
"maintenances": [],
"status": "Available",
"picture_url": "sime url",
"manufacturer": "DJI",
"model_name": "Phantom 4",
"drone_type": "Quadcopter",
"payload_type": "RGB Camera",
"asset_url": "http://127.0.0.1:5000/datamine/v1/drones/5aeaff374f85747f90df2714"
}
],
"message": "All drones successfully fetched!",
"code":200
}
}
2. With the marshal decorator:
{
"data": {
"items": [
{
"id": "Id of Drone",
"serial_id": "Name of Drone",
"status": "Status of Drone",
"maintenances": null,
"picture_url": "Picture URL",
"manufacturer": "Manufacturer of Drone",
"model_name": "Model name of Drone",
"drone_type": "Type of Drone",
"payload_type": "Payload type of Drone",
"asset_url": "Asset URL of Drone"
}
],
"message": "",
"code": ""
}
}
It would be really helpful if someone could tell me what I'm doing wrong as I need to recive the output as the one shown in snippet of the output without the decorator.
Thank you.
Here is a diagram showing invocation order from top to bottom to help make sense of what is happening:
get()
→ api.response(200, 'All drones successfully fetched!') # documents the response
→ api.marshal_with(drones_list, envelope='data')` # returns marshalled dict
The result from invoking get is passed to the api.response decorator function whose result is passed on to api.marshal_with decorator function.
Looking at the shape of the dictionary returned from invoking get()
{
data {
items [
{
id,
serial_id,
maintenances,
status,
picture_url,
manufacturer,
model_name,
drone_type,
payload_type,
asset_url
}
],
message,
code
}
}
The message and code in the response are nested inside of the data.
You need to model the data appropriately, to be able to marshal it. This can be done by passing an argument for what field to look up in the marshal dictionary.
drones_list = api.model('drones_list', {
'items': fields.List(fields.Nested(drone_model()), attribute='data.items'),
'message':fields.String(attribute='data.message'),
'code': fields.Integer(attribute='data.code')
})
As you can see, it's pretty redundant applying the api.marshal_with decorator function on the view given that it's only unnests then nests the result in data field.

Iterating through json request with multiple objects - django

I have a django project that I am working on. I have a api request that is returning a json response. With the json reponse that I am getting, there is a list of funding sources and within each funding source is an item that has the name with the object. I want to go though each json item and grab the names from the list of objewcts. how can I do this with the following response. I will also attach the request code that I sent...
response:
{
'funding-sources':[
{
'_links':{
'self':{
'href':'https://api-sandbox.dwolla.com/funding-sources/..546a9720a01',
'type':'application/vnd.dwolla.v1.hal+json',
'resource-type':'funding-source'
},
'customer':{
'href':'https://api-sandbox.dwolla.com/customers/..524dde5a',
'type':'application/vnd.dwolla.v1.hal+json',
'resource-type':'customer'
},
'initiate-micro-deposits':{
'href':'https://api-sandbox.dwolla.com/funding-sources/..6a9720a01/micro-deposits',
'type':'application/vnd.dwolla.v1.hal+json',
'resource-type':'micro-deposits'
}
},
'id':'56b3ab2c-da7b-4edc-83a8-5546a9720a01',
'status':'unverified',
'type':'bank',
'bankAccountType':'checking',
'name':'Cheese',
'created':'2017-11-02T05:37:39.000Z',
'removed':False,
'channels':[
'ach'
],
'bankName':'SANDBOX TEST BANK',
'fingerprint':'..ff1d7dcd22'
},
{
'_links':{
'self':{
'href':'https://api-sandbox.dwolla.com/funding-sources/..a51126e4',
'type':'application/vnd.dwolla.v1.hal+json',
'resource-type':'funding-source'
},
'customer':{
'href':'https://api-sandbox.dwolla.com/customers/..6b56524dde5a',
'type':'application/vnd.dwolla.v1.hal+json',
'resource-type':'customer'
},
'with-available-balance':{
'href':'https://api-sandbox.dwolla.com/funding-sources/..d3a51126e4',
'type':'application/vnd.dwolla.v1.hal+json',
'resource-type':'funding-source'
},
'balance':{
'href':'https://api-sandbox.dwolla.com/funding-sources/..6e4/balance',
'type':'application/vnd.dwolla.v1.hal+json',
'resource-type':'balance'
}
},
'id':'522d3f3c-5ea2-4751-a485-4ad3a51126e4',
'status':'verified',
'type':'balance',
'name':'Balance',
'created':'2017-11-02T01:51:27.000Z',
'removed':False,
'channels':[
]
}
]
}
here is the code that I have right now for the request... the funding sources is in the -embedded objects as you will see in the code below:
sources = app_token.get('%s/funding-sources' % account_url)
accounts = sources.body['_embedded']

Facebook Messenger bot Generic Template Not Working

I have created a Facebook Messenger bot which works fine. I have used the Button Template and Image template, and both work perfectly. But when I try the Generic Template, I get no response. I have simply copy pasted the code from here, by performing the appropriate modifications.
I don't know how to debug. Facebook Messenger gives no output on the messaging box. I am currently running the app via Heroku.
Here is my code:
def send_message(token, recipient):
r = requests.post("https://graph.facebook.com/v2.6/me/messages",
params={"access_token": token},
data=json.dumps({
"recipient":{
"id":recipient
},
"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"generic",
"elements":[
{
"title":"Welcome to Peter\'s Hats",
"image_url":"http://www.godominion.com/content/images/feature-img-small-appliance-electronics.png",
"subtitle":"We\'ve got the right hat for everyone.",
"default_action": {
"type": "web_url",
"url": "https://peterssendreceiveapp.ngrok.io/view?item=103",
"messenger_extensions": true,
"webview_height_ratio": "tall",
"fallback_url": "https://peterssendreceiveapp.ngrok.io/"
},
"buttons":[
{
"type":"web_url",
"url":"https://petersfancybrownhats.com",
"title":"View Website"
}
]
}
]
}
}
}
}),
headers={'Content-type': 'application/json'})
if r.status_code != requests.codes.ok:
print r.text
I would appreciate any help.
Thank you.
EDIT 1: SOLUTION
I got rid of the issue by commenting out:
"messenger_extensions": true,
and
"fallback_url": "https://peterssendreceiveapp.ngrok.io/"},
I'm sure this is not the correct method. But as I am creating a bot, without actual links, this works.
On the second button, "url":"https://petersfancybrownhats.com" is broken.
Try like this
firstly make a function
def function():
extra_data = {
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"elements": [
{
"title": "Any Title",
"image_url": "https://mbtskoudsalg.com/images/road-clipart-journey-3.png",
"subtitle": "Subtitle.",
"buttons": [
{
"type": "web_url",
"title": "View",
"url": "**MAKE SURE TO WHITELIST THIS URL**", # URL
"messenger_extensions": "true",
"webview_height_ratio": "full"
}
]
}
]
}
}
}
# w_message = "Hi there! How may I help you?"
fb_message_template(extra_data["attachment"], "****RECIEVER ID****")
Make another function
import requests
# // Importing User Defined Modules // #
from get_environ_var import get_environ_var
# // Global vars // #
ACCESS_TOKEN = "FB_ACCESS_TOKEN"
def fb_message_template(extra_data, sender_id):
"""This function sends template message to facebook"""
data = {
'recipient': {'id': sender_id},
'message': {
"attachment": extra_data
}
}
qs = 'access_token=' + ACCESS_TOKEN
resp = requests.post('https://graph.facebook.com/v2.6/me/messages?' + qs, json=data)
print(resp.content)

Why is code not executing after response received

I'm running the code below and it takes the user to PayPal to make a payment and then returns them to the return_url as expected. However the code doesn't execute any further and it doesn't execute the payment.
I have based my code on https://github.com/paypal/rest-api-sdk-python:
class PayPalHandler(tornado.web.RequestHandler):
def get(self):
logging.basicConfig(level=logging.INFO)
paypal.configure({
"mode": PAYPAL_MODE,
"client_id": PAYPAL_CLIENT_ID,
"client_secret": PAYPAL_CLIENT_SECRET})
payment = paypal.Payment({
"intent": "sale",
"payer": {
"payment_method": "paypal" },
"redirect_urls": {
"return_url": "http://127.0.0.1:8000/ty",
"cancel_url": "http://127.0.0.1:8000/" },
"transactions": [ {
"item_list": {
"items": [{
"name": "membership",
"price": "2.00",
"currency": "GBP",
"quantity": 1 }]},
"amount": {
"total": "2.00",
"currency": "GBP" },
"description": "One of membership fee." } ] } )
redirect_url = ""
if payment.create():
print("Payment[%s] created successfully"%(payment.id))
for link in payment.links:
if link.method == "REDIRECT":
redirect_url = link.href
print("Redirect for approval: %s"%(redirect_url))
return self.redirect(redirect_url)
else:
print("Error while creating payment.")
print(payment.error)
response = payment.to_dict()
print response
payment = paypal.Payment.find(payment.id)
if payment.execute({"payer_id": response['payer_id']}):
print ("Payment executed successfully")
else:
print(payment.error) # Error Hash
print payment.to_dict()
print userData
So in the example at https://devtools-paypal.com/guide/pay_paypal/python?success=true&token=EC-8JL96732FP068791F&PayerID=QQGSRNHDACTLJ. Step 5 is not happening and no response is sent from PayPal?
This is Avi from PayPal here. I am not super familiar with Tornado, but after the line return self.redirect(redirect_url) happens in your code, and returns the user to the return_url, in payment.execute({"payer_id": response['payer_id']}) are you getting the payer_id correctly? Payer_id is returned appended to the return_url as one of the parameters in the format http://<return_url>?token=EC-60U79048BN7719609&PayerID=7E7MGXCWTTKK2. Also, what is the status of the payment after you execute payment = paypal.Payment.find(payment.id). The other suggestion I would have is to see if print payment.error prints a useful debug message and a debug_id which paypal merchant technical services can use to look at the issue.
You need other url where papypal redirects when the payment had been successful, where you will receive the token and the PayerID. In that GET method, you can put this part of the code (pseudocode):
payerid_param = request.get('PayerID')
payment = paypal.Payment.find(db_payment.id)
if payment.execute({"payer_id": payerid_param}):
print ("Payment executed successfully")
else:
print(payment.error) # Error Hash
You will need to save the payment_id between calls.
Why you use
return self.redirect(redirect_url)
I think you can use just
self.redirect(redirect_url)
I've never seen return statement in Tornado handlers.

Categories