Two distinc response from same AWS Lambda in Api Gatway and Postman - python

I have this simple Lambda
def lambda_handler(event, context):
# TODO implement
message = {
'statusCode': 200,
'headers': { 'Content-Type': 'application/json' },
'body': json.dumps({ 'username': 'bob', 'id': 200 })
}
return message
I couple it with a Api Gateway
I was having dificulties to confiure permissions o I created more than one api enpoint resources.
As far as I know, both resources are identical.
However when I call them from Postman they return difent results:
/activation returns
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"username\": \"bob murrey\", \"id\": 200}"
}
and /myPythonLambda
{
"username": "bob murrey",
"id": 200
}
I canĀ“t find any configurantion that I could change that would explaing this difference.

Obviously you have done something different in API Gateway for each endpoint.
From looking at the two different responses, it appears you have ticked the Proxy integration in Method Request for the myPythonLambda endpoint.

Related

My slack app seems to fail in interaction

I'm new to slack app development. Following this page: https://api.slack.com/messaging/interactivity/enabling, I'm trying to create a simple interactive slack-app that
is launched by a slash command
can interact with users through a button.
I use AWS API-gateway and Lambda as backends. Lambda functions are written in Python 3.6.
I succeeded in creating a slash command, but failed in updating a message after pushed the button.
Precise structure of my app
When I type the slash command /test in my slack channel, my app makes a post request to an API gateway (https://xxx.execute-api.ap-northeast-1.amazonaws.com/prod/test) and a lambda function returns the following response with a button.
The lambda function is as follows:
import json
import datetime
def lambda_handler(event, context):
try:
response = {
"statusCode": 200,
"response_type": "in_channel",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "This is a section block with a button."
},
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Button",
"emoji": True
},
"action_id": "test"
}
]
}
]
}
return response
except Exception as e:
return {"error": str(e)}
After the button pushed, my app sends a post request to another API gateway (https://xxx.execute-api.ap-northeast-1.amazonaws.com/prod/test2) and another lambda function receives a request like follows
{
'type':'block_actions',
'team':{
'id':'xxx',
'domain':'xxx'
},
'user':{
'id':'xxx',
'username':'xxx',
'name':'xxx',
'team_id':'xxx'
},
'api_app_id':'xxx',
'token':'xxx',
'container':{
'type':'message',
'message_ts':'1564687520.001900',
'channel_id':'xxx',
'is_ephemeral':False
},
'trigger_id':'xxx.yyy.zzz',
'channel':{
'id':'xxx',
'name':'slack_app_test'
},
'message':{
'type':'message',
'subtype':'bot_message',
'text':"This content can't be displayed.",
'ts':'1564687520.001900',
'bot_id':'xxx',
'blocks':[
{
'type':'section',
'block_id':'ygl6',
'text':{
'type':'mrkdwn',
'text':"This is a section block with a button. {'token': 'xxx', 'team_id': 'xxx', 'team_domain': 'xxx', 'channel_id': 'xxx', 'channel_name': 'slack_app_test', 'user_id': 'xxx', 'user_name': 'mail', 'command': '/recommend', 'response_url': '<https://hooks.slack.com/commands/xxx/yyy/zzz>', 'trigger_id': 'xxx.yyy.zzz'}",
'verbatim':False
}
},
{
'type':'actions',
'block_id':'jlzD',
'elements':[
{
'type':'button',
'action_id':'test',
'text':{
'type':'plain_text',
'text':'Button',
'emoji':True
}
}
]
}
]
},
'response_url':'https://hooks.slack.com/actions/xxx/yyy/zzz',
'actions':[
{
'action_id':'test',
'block_id':'jlzD',
'text':{
'type':'plain_text',
'text':'Button',
'emoji':True
},
'type':'button',
'action_ts':'1564687524.157943'
}
]
}
and try to make a response by the following lambda function:
import json
import urllib.request
def lambda_handler(event, context):
try:
response_url = event.get("response_url", None)
if response_url is not None:
headers = {"Content-Type" : "application/json"}
print("From slack. Response url: {}".format(response_url))
response = json.dumps({
"replace_original": True,
"response_type": "in_channel",
"text": "Success!"
})
request = urllib.request.Request(
response_url,
data=response,
method="POST",
headers=headers
)
return None
except Exception as e:
return {"error": str(e)}
When I look at Cloudwatch logs of the lambda function above, the function seems to successfully send a message to my slack app.
Problem
I expect that my app displays a message Success! after pushing the button, but no updates are shown (just showing a loading animation). Any ideas?

directline v3 gives error 400

In the Step Sending an Activity to the bot As per the documentation Here,
https://docs.botframework.com/en-us/restapi/directline3/#navtitle
I should pass this as the body content of the post request
{
"type": "message",
"from": {
"id": "user1"
},
"text": "hello"
}
I am using the following parameters to make POST request in python, but its not working.
msg = {"type": "message","channelId": "directline","conversation":{"id": str(convId)},"from":{"id": "test_user1"},"text": "hello"}
header = {"Authorization":"Bearer q1-Tr4sRrAI.cwA.BmE.n7xMxGl-QLoT7qvJ-tNIcwAd69V-KOn5see6ki5tmOM", "Content-Type":"application/json", "Content-Length": "512"}
send2 = "https://directline.botframework.com/v3/directline/conversations/"+str(convId)+"/activities"
rsa1 = requests.post(send2,data=msg, headers=header)
This gives me this error:
{
"error": {
"code": "MissingProperty",
"message": "Invalid or missing activities in HTTP body"
}
}
Before this step everything is working fine.
Edit 1: Even i added content-length as updated in the code, it gives the same error
Edit 2: If i changed the msg to json.dumps(msg)
rsa1 = requests.post(send2,data=json.dumps(msg), headers=header)
I get response:
{u'error': {u'message': u'Failed to send activity: bot returned an error', u'code': u'ServiceError'}}
{
"error": {
"code": "ServiceError",
"message": "Failed to send activity: bot returned an error"
}
}
The directline API is only not working, on skype client everything is working fine.
According to the code that you've posted, your request body looks like this:
{
"type": "message",
"channelId": "directline",
"conversation": {
"id": str(convId)
},
"from": {
"id": "test_user1"
},
"text": "hello"
}
I'd suspect that your error is caused by the fact that the conversation ID value that you're including in the request body is not surrounded with double quotes in the JSON that's sent over the wire.
For simplicity (and to eliminate the error you're receiving), I'd suggest that you try omitting the channelId property and the conversation property from the request body, as I don't believe that either of these properties are necessary (i.e., you are issuing the request to the Direct Line URI, so the Bot Framework knows that Direct Line is the channel, and the conversation ID is already being specified in the request URI). In other words, try this as your request body:
{
"type": "message",
"from": {
"id": "test_user1"
},
"text": "hello"
}
When passing a dictionary to data it gets urlencoded automatically, so the api returns an error as it expects json data.
You can either use the json lib, or preferably pass your dictionary to the json parameter.
Using json.dumps :
rsa1 = requests.post(send2, data=json.dumps(msg), headers=header)
Using requests only :
rsa1 = requests.post(send2, json=msg, headers=header)
Also you don't have to add "Content-Length" in header and if you use the second example you don't have to add "Content-Type" either.

Outlook API email attachment issue

I am trying to use Outlook's REST API in my python code to send an email in behalf of a user who already gives me his consent.
I was able to successfully send text emails using their /me/sendmail node with the following payload:
email_payload = {
"Message": {
"Subject": email_subject,
"Body": {
"ContentType": "Text",
"Content": email_body
},
"ToRecipients": [
{
"EmailAddress": {
"Address": to
}
}
]
}
}
However, when trying to add attachments (based on their documentation), I encounter some issues:
email_payload["Message"]["Attachments"] = [
{
"ContentType": "application/pdf",
"Name": "{0}".format("something.pdf"),
"ContentBytes": base64.b64encode(attachment.read())
}
]
Issues consist in 415 response status code with the following content:
{u'error': {u'message': u'A missing or empty content type header was found when trying to read a message. The content type header is required.', u'code': u'RequestBodyRead'}}
Couldn't find anything regarding this in their documentation. Hope somebody can enlighten me :)
For anyone else having such issues, here's the context and fix:
Initially, since I was sending only plain-text emails, my request header looked like this:
request_headers = {
'Authorization': "Bearer {0}".format(token),
}
And the actual request:
api_response = requests.post(
request_url,
json.dumps(body),
headers=request_headers
)
As you might have noticed I wasn't sending any content-type in my headers (not sure why), but everything went well so far up until when I decided to add attachments too.
Seems like if my request_headers would contain Content-Type too, everything would go well:
request_headers = {
'Authorization': 'Bearer {0}'.format(refreshed_token),
'Content-Type': 'application/json'
}

POST to google apis compute engine gives 400

I am building a small flask app to handle automatic deployment for another project I am working on.
This involves setting a gcloud firewall rule using googleapis.
I have followed the below documentation.
https://cloud.google.com/compute/docs/reference/latest/firewalls/insert
When I make my POST call in the following manner.
headers = {
'Authorization': 'Bearer {}'.format(access_token)
}
name = unique_identifier + "-rule"
payload = {
"kind": "compute#firewall",
"name": name,
"sourceRanges": [
"0.0.0.0/0"
],
"sourceTags": [
unique_identifier
],
"allowed": [
{
"IPProtocol": "tcp",
"ports": [
port_number
]
}
]
}
data = json.dumps(payload)
r = requests.post("https://www.googleapis.com/compute/v1/projects/apollo-rocket-chat/global/firewalls?key={MY_API_KEY}", data=data, headers=headers)
where port_number and unique_idenifier are strings. access_token is retrieved using a service account I have set. I am confident that the token is good, since I can make a GET call to a protected resource using the token.
I am using python 3.5.
The response to this POST is the following.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required field 'resource' not specified"
}
],
"code": 400,
"message": "Required field 'resource' not specified"
}
}
The error message is claiming that I am missing a field, although I have all the required fields that are specified at the link below.
https://cloud.google.com/compute/docs/reference/latest/firewalls/insert#request-body
What exactly am I doing wrong?
Figured it out. I removed.
data = json.dumps(payload)
and changed
r = requests.post("https://www.googleapis.com/compute/v1/projects/apollo-rocket-chat/global/firewalls?key={MY_API_KEY}", data=data, headers=headers)
to
r = requests.post("https://www.googleapis.com/compute/v1/projects/apollo-rocket-chat/global/firewalls?key={MY_API_KEY}", json=data, headers=headers)

PayPal Adaptive Payments - Preapproval request results in "Invalid request" error

I can't figure out what's happening with my Preapproval HTTP POST request. I'm just trying to do a basic call to PayPal's Adaptive Payments API, the Preapproval call specifically. And the PayPal error 580001 "Invalid request" is not that helpful in itself.
Request Headers (based on my Sandbox's account credentials, which I changed to xxx):
{
'X-PAYPAL-REQUEST-DATA-FORMAT': 'JSON',
'X-PAYPAL-SECURITY-PASSWORD': 'xxx',
'X-PAYPAL-RESPONSE-DATA-FORMAT': 'JSON',
'X-PAYPAL-SECURITY-SIGNATURE': 'xxx',
'X-PAYPAL-SECURITY-USERID': 'xx',
'X-PAYPAL-APPLICATION-ID': 'APP-80W284485P519543T'
}
My request payload (HTTP POST, body encoded in JSON):
{
"requireInstantFundingSource": "TRUE",
"returnUrl": "http://www.google.com/?paypal=ok",
"maxTotalAmountOfAllPayments": 1002,
"maxNumberOfPaymentsPerPeriod": 1,
"endingDate": "2014-03-14T16:49:36+0000",
"requestEnvelope.errorLanguage": "en_US",
"clientDetails.applicationId": "XXX",
"cancelUrl": "http://www.google.com/paypal=cancel",
"startingDate": "2013-09-15T16:49:36+0000",
"feesPayer": "PRIMARYRECEIVER",
"currencyCode": "SEK"
}
The above POST body is posted to:
https://svcs.sandbox.paypal.com/AdaptivePayments/Preapproval
Response from Paypal ("prettified" for understanding):
{
"responseEnvelope": {
"ack": "Failure",
"timestamp": "2013-09-10T09:56:43.031-07:00",
"build": "6941298",
"correlationId": "26d55e6bfcaa0"
},
"error": [
{
"category": "Application",
"domain": "PLATFORM",
"severity": "Error",
"message": "Invalid request: {0}",
"subdomain": "Application",
"errorId": "580001"
}
]
}
Any feedback is appreciated.
OK fixed. How?
Fix #1
The arguments requestEnvelope.errorLanguage and clientDetails.applicationId need to be "JSONified" into objects on their own, such as:
"requestEnvelope": {
"errorLanguage": "en_US"
},
and
"clientDetails": {
"applicationId": "APP-XXXXXXXXXXXXX"
},
respectively.
Fix #2
Date formats; date format should be of the form 2014-03-15T20:14:38.007+00:00 and not 2014-03-14T20:14:38+0000 as I was passing. Note the milliseconds, and the timezone with the colon in the utc offset.
Next time an Invalid request comes up the parameters I'm passing will be the first thing to look at.

Categories

Resources