"message" : "Internal server error" issue with Lambda/API Gateway and iOS - ios

I've set up a lambda function and created some GET and POST methods inside the API Gateway which seem to work fine when testing them inside the web application.
I am then trying to call the functions inside an iOS application which is set up using the mobile hub. The functions also work inside the testing facility via the mobile hub perfectly fine, however when I actually test the functions inside the app I get:
"message" : "Internal server error"
I know the error is not much to work from, but I can't figure out a way to get a more detailed error description.
Any ideas?

This may happen because your Lambda function is not set to return a HTTP status code.
Changing from
exports.handler = (event, context, callback) => {
callback(null, 'Hello from Lambda');
};
to
exports.handler = (event, context, callback) => {
callback(null, { statusCode: 200, body: 'Hello from Lambda' });
};
Should fix the issue.

The JSON.stringify() solved my issue. The response.body needs to be in String format and not as JSON. I hope this helps.
exports.sendRes = (body, status = 200) => {
var response = {
statusCode: status,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(body)
};
return response;
};

I had the same issue with the following code:
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: event
};
};
To fix all I had to do was JSON.stringify() the body.
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: JSON.stringify(event), // <-- here
};
};

I had this problem until I click in "Deploy API" under the "Actions" button.

The other possible reason could be the payload/request/response limits on API Gateway (10MB) and/or Lambda (6MB)

None of the above answers worked for me. I was having a permission issue. Below is how I solved it.
Context
This is my lambda function:
exports.handler = function(event, context, callback) {
callback(null, {
statusCode: '200',
body: JSON.stringify({ 'message': 'hello world' }),
headers: {
'Content-Type': 'application/json',
},
});
};
I used terraform to provision api gateway and lambda. I used the example code provided by this blog post.
Diagnosis
In the lambda console I ran a test event on my lambda. As my lambda was super basic I used the hello world test template, named, and saved it. The test return success.
I checked cloudwatch logs, but couldn't find anything of use. I'm new to AWS so wasn't sure if I had to set anything up.
In the api gateway console I ran a test event. I just added Content-Type:application/json to the headers of the event and ran the test. For whatever weird reason the test results returned on the right side of the browser so had to scroll to the right to see them.
I got this result: Execution failed due to configuration error: Invalid permissions on Lambda function
SOLUTION
I checked the basic terraform example for api gateway and lambda integration here and noticed I was missing the aws_lambda_permission resource. This is needed to give permission to api gateway to invoke the lambda function.
For those that aren't using terraform here is a link to the aws docs on how to create the appropriate permissions.

please try to
Give execute lambda permission API Gateway
tick checkbox : Use Lambda Proxy integration
Handle null pointer for query string, headers & body.

I solved the issue by adding "isBase64Encoded": False/True to my lambda response
results = {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(res),
"isBase64Encoded": False
}

In my case, the issue resolved while adding the integration Response and redeploying API

Related

Why is my slack app posting only ephemeral messages? [duplicate]

Using Serverless and NodeJS, I have a Slack command set up like:
/myCommand doStuff
When I type /myCommand doStuff, the Slack output does this:
/myCommand doStuff
The content of the actual response I want shown goes here.
What I want to do is only have this:
The content of the actual response I want shown goes here.
without the /myCommand doStuff getting echoed.
How do I prevent that from happening?
Update - adding some code
Here's the actual command:
module.exports = () => {
return new Promise(function(fulfill) {
fulfill({
response_type: 'in_channel',
text: 'some testing text
});
});
};
Here's the handler:
module.exports.handler = (event, context, callback) => {
var response = {
statusCode: 200,
body: JSON.stringify(myCommand()),
};
callback(null, response);
};
When you are replying with
"response_type": "in_channel"
the reply is visible to all users in a channel and it will always copy the command back into the channel. This can not be turned off.
When you are replying with
"response_type": "ephemeral"
it is only visible to the user and the command will not be copied back. That is also the default, so you must be using in_channel in your script.
See here for the official documentation on that topic.

Twilio Studio: Forward SMS conversation log to email

I'm using SMS studio do have a quick chat bot conversation with inbound SMS messages, and would like to forward the conversation log to email after it's complete. I've written a function that uses the SendGrid API to forward SMSes to email. It works independently - ie, if I configure the phone number to run the function immediately as a text comes in, it will email that single SMS input.
However, I'd like to add the function to the end of of Twilio Studio flow, so that it emails the entire log of the conversation to me, once it's over. Once I append the function to the end of the studio flow, it stops working, and I get a failure notice.
Here's the code in the function:
const got = require('got');
exports.handler = function(context, event, callback)
{
const requestBody = {
personalizations: [{ to: [{ email: context.TO_EMAIL_ADDRESS }] }],
from: { email: context.FROM_EMAIL_ADDRESS },
subject: `New SMS message from: ${event.From}`,
content: [
{
type: 'text/plain',
value: event.Body
}
]
}
got.post('https://api.sendgrid.com/v3/mail/send', {
headers: {
Authorization: `Bearer ${context.SENDGRID_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(response => {
let twiml = new Twilio.twiml.MessagingResponse();
callback(null, twiml);
})
.catch(err => {
callback(err);
});
};`
Here's the error the debugger returns, if I make this function the last step in a Twilio studio flow:
Error - 81017
Error on Twilio Function response
There was an error in the response back from a Twilio Function attached to the Studio flow.
Possible Causes
Your Function timed out before responding
Your Function returned an error response
Possible Solutions
Your Function must contain a callback.
Make sure you place the Function callback callback(err, response) is placed correctly in your Function code.
If you are using a JavaScript promise, make sure the callback is called in both success and catch blocks.
Your Function responded with an error.
I'm having a hard time figuring out what the error is. Does anyone have any tips?
Thanks!
Jarod from Twilio. I actually wrote an app very similar to this. Code looks good to me. Often when people encounter an error of this nature it is coming from the SendGrid promise. Here are two tips:
You can actually log errors and view responses from the function if you leave the function open while testing it. The logs will be at the bottom. These usually have more information.
Check that you are using an outbound email address that has been whitelisted on your SendGrid account Whitelabel - Sendgrid
Make sure you have added your environment variables to your Functions config. Twilio Functions Configuration - Console
Hope that helps! If not feel free to email support#twilio.com with more questions.

Zapier - Invalid API Response

I'm integrating a CRM with Facebook lead Ads using Zapier, and I can create a lead in Facebook and create it in the CRM without any issues.
After a successful post (i.e. successfully creating the lead), I'm curious what I should be returning, I would have thought
return Ok();
would have been enough. Instead, I get an error message saying:
- Got a non-object result, expected an object from create ()
What happened (You are seeing this because you are an admin):
Executing creates.ZapLead.operation.perform with bundle
Invalid API Response:
- Got a non-object result, expected an object from create ()
What should I be returning?
Code which makes the post is:
perform: (z, bundle) => {
const promise = z.request({
url: 'https://{{bundle.authData.subdomain}}.ngrok.io/api/zapier/create/lead/' + bundle.inputData.lead_type + '/' + bundle.inputData.core_customerTypeId,
method: 'POST',
body: JSON.stringify({
fields: bundle.inputData
}),
headers: {
'content-type': 'application/json'
}
});
// return promise.then((response) => JSON.parse(response.content));
return promise.then((response) => {
if (response.status != 200) {
throw new Error(`Unexpected status code ${response.status}`);
}
});
Any ideas?
Thanks,
David here, from the Zapier Platform team.
While your answer is technically correct, I wanted to add some context about the error and why your solution works.
Zapier expects a javascript object (basically anything valid and wrapped in {}) to come out of a create function. That's why JSON.parse(response.content) works, it's returning whatever the server said. Your code throws an error if it's not a 200, but doesn't return anything if it is a 200. Since undefined is not of type Object, the error you're seeing is thrown.
While {"Success":"Success","Attempt":null,"Id":null,"RequestId":null} is totally a valid response (it's an object!), it's more useful for the end-user to return data about the new lead that was created. That way, it can be used downstream for other actions.
​Let me know if you've got any other questions!
As a side note, we're very open to how to make that error message more clear; it's one devs struggle with a lot.
I think I found it. Looks like I need to return this if successful:
{"Success":"Success","Attempt":null,"Id":null,"RequestId":null}

Slack slash command response_type ephemeral are sent to the entire channel

Ephemeral messages are supposed to be only visible to the user that issued the command. However, in my experience, it's sent to the entire channel.
Am I missing anything?
According to Slack Slash commands documentation, the only attribute needed is to set response_type to ephemeral in the response of Node.js app.
The code in my app looks like this:
var t = {
"response_type": "ephemeral",
"text": "How to use /please"
}
request({
uri: uri,
headers: {
'content-type': 'application/json',
},
method: 'POST',
body: JSON.stringify(t)
}, function (error, response, body) {
return res.status(200).end();
});
Ephemeral messages are only supported in slash commands currently. From your screen capture it looks like you're sending your payload to an incoming webhook. Unfortunately, I can't find the wiki that backs this up, but here's another post with a similar answer: Slack API "attachments" not showing

Async API call error

I'm currently trying to call the twitter API using meteor and so far i got this:
updateTotalFoll:function(){
var Twit = Meteor.npmRequire('twit');
var T = new Twit({
consumer_key: 'AWzYAlWFRh9zsownZMg3',
consumer_secret: 'aYpL3zMPfqRgtX1usPQpEREEXVNPfNYna9FiIwTeDYR',
access_token: '4175010201-TEp9qNKO4mvjkj0GMjJFZIbGPYaVv4',
access_token_secret: 'EPpcJyN27E4PvhJpYaTHflNFOv3DuR05kTP2j'
});
var Id2=RandomCenas.findOne({api:"twitter"})._id;
T.get('statuses/user_timeline', { screen_name: 'jeknowledge' }, function (err, data, response){
//console.log(data[0].user.followers_count);
RandomCenas.update(Id2,{$set:{totalFoll:data[0].user.followers_count}});
});
}
with "RandomCenas" being a MongoDB.
What i'm trying to do is updating this collection with the info from the call , but i get this error
Error: Meteor code must always run within a Fiber.
Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
I've searched the web for a way to counter this , but i cant seem to apply the solutions that i came across with.
Any help with how i can deal with this?
try it like that
T.get('statuses/user_timeline', { screen_name: 'jeknowledge' }, Meteor.bindEnvironment(function (err, data, response) {
//console.log(data[0].user.followers_count);
RandomCenas.update(Id2,{$set:{totalFoll:data[0].user.followers_count}});
}));
the reason this is happening is because callback function which you pass it's happening outside the current Meteor's Fiber check the answer Error: Meteor code must always run within a Fiber

Resources