I am trying to create job of mediaconverter aws service through lambda but I m getting error
"Error BadRequestException: You must use the customer-specific
endpoint"
AWS.config.update({region: 'us-east-1'});
var mediaconvert = new AWS.MediaConvert("https://xyzyzyzzz.mediaconvert.us-east-1.amazonaws.com");
console.log("End Point Set");
await mediaconvert.createJob(params, function(err, data) {
console.log('started execution');
if (err){ console.log(err, err.stack);
console.log("non promise error");
callback(null, {
statusCode: 200,
body: JSON.stringify(data)
});
} // an error occurred
else { console.log("non promise no error");
callback(null, {
statusCode: 200,
body: JSON.stringify(data)
});
}
// successful response
});
the easiest way to find you mediaconvert endpoint is to go to mediaconvert service -> from left panel select account and there's your endpoint.
I found mine https://xxxxx.mediaconvert.ap-south-1.amazonaws.com
Hope this helps.
You did not specify the params in your createJob call.
The documentation tells you what you need in order to create a job.
That is the error you get when the endpoint is not specified or if it's an invalid value. The constructor for MediaConvert accepts an object, not just a string, as outlined in the docs. You need to pass the endpoint URI in an object like so:
var mediaconvert = new AWS.MediaConvert({
endpoint: "https://xyzyzyzzz.mediaconvert.us-east-1.amazonaws.com"
});
For context, the endpoint can be found in the console in the MediaConvert service under the Account section or it can be fetched through the API as outlined here. In general, this value should be cached as it has a much lower request rate limit than the other MediaConvert endpoints. There is one endpoint per account per region.
Related
Problem
I was trying to use 'aws-amplify' GET API request with query parameters on the client side, but it turned out to be Request failed with status code 403, and the response showed:
"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
Note: React.js as front-end, Javascript as back-end.
My code
Front-end
function getData() {
const apiName = 'MyApiName';
const path = '/path';
const content = {
body:{
data:'myData',
},
};
return API.get(apiName, path, content);
}
Back-end
try {
const result = await dynamoDbLib.call("query", params);
} catch (e) {
return failure({ status: false });
}
What I did to debug
The GET lambda function works fine in Amazon Console (Tested)
If I change the backend lambda function so that the frontend request can be made without parameters, i.e. return API.get(apiName, path), then no error shows up.
My question
How can I make this GET request with query parameters works?
I changed GET to POST (return API.post()), everything works fine now.
If anyone can provide a more detailed explanation, it would be very helpful.
I created an AWS API Gateway route for Websocket connections. I started with the AWS provided Simple Web Chat templates but have modified it to fit my needs. The API Gateway calls a Lambda function that writes to a DynamoDB table.
I am able to make a websocket connection but when I make my next request to insert some data the data appears successfully in my DynamoDB table but the response I get back is Internal Server Error.
I don't understand what is causing the Internal Server Error. When I look in the CloudWatch logs I just see normal traffic with no errors.
I could use some help understanding what is going wrong or how I can troubleshoot this better.
Here is the Lamba function that is being called:
const AWS = require("aws-sdk");
const customId = require("custom-id");
const ddb = new AWS.DynamoDB.DocumentClient({
apiVersion: "2012-08-10",
region: process.env.AWS_REGION,
});
exports.handler = async (event) => {
const uniqueId = customId({
randomLength: 1,
});
const data = {
uniqueId: uniqueId,
members: [
{
connectionId: event.requestContext.connectionId,
},
],
events: [],
parameters: [],
};
const putParams = {
TableName: process.env.EVENT_TABLE_NAME,
Item: data,
};
try {
await ddb.put(putParams).promise();
} catch (err) {
return {
statusCode: 400,
body: "Failed to create: " + JSON.stringify(err),
};
}
return { statusCode: 200, body: putParams };
};
Image of AWS CloudWatch Logs
The error returned by wcat looks like this:
{"message": "Internal server error", "connectionId":"NZxV_ddNIAMCJrw=", "requestId":"NZxafGiyoAMFoAA="}
I just had the same problem. The issue in my case was because API Gateway did not have permission to call the Lambda function in order to process a message arriving from the websocket. The 'internal server error' in this case is API Gateway saying it had some problem when it tried to invoke the Lambda function to handle the websocket message.
I was using CDK to deploy the infrastructure, and I created one WebSocketLambdaIntegration for the connect, disconnect and default websocket handlers, but this doesn't work. You have to create separate WebSocketLambdaIntegration instances even if you are calling the same Lambda function for all websocket events, otherwise CDK does not set the correct permissions.
I could see this was the problem because 1) I was using the same Lambda function for the connect, disconnect and default routes, and 2) in CloudWatch Logs I was only seeing log messages for one of these routes, in this case the 'connect' one. When I sent a message over the websocket, I was not seeing the expected log messages from the Lambda that was supposed to be handling incoming websocket messages. When I disconnected from the websocket, I did not see the expected log messages from the 'disconnect' handler.
This was because CDK had only given Lambda invoke permission to specific routes on the API Gateway websocket stage, and it had only authorised the 'connect' route, not the others.
Fixing the CDK stack so that it correctly assigned permissions, allowing API Gateway to invoke my Lambda for all websocket routes, fixed the problem.
I see it now. It was the last line. I changed it and now it works fine.
return { statusCode: 200, body: JSON.stringify(putParams) };
I am using aws lambda function for google smart home action. I used aws api gateway for fulfillment url to reach lambda. I can successfully handle google assistant's intents with below code:-
const {smarthome} = require('actions-on-google');
const app = smarthome();
app.onExecute((body, headers) => {
return {
requestId: 'ff36...',
payload: {
// ...
},
};
});
app.onQuery((body, headers) => {
return {
requestId: 'ff36...',
payload: {
// ...
},
};
});
app.onSync((body, headers) => {
console.log("body: "+JSON.stringify(body));
console.log("headers: "+JSON.stringify(headers));
return {
requestId: 'ff36...',
payload: {
// ...
},
};
});
exports.handler = app;
On hard coding device details in this function, It can successfully reflect in google home app. But to get actual devices of user I need to get oauth token from "SYNC" intent. But all I got from this code is this output:-
body: {"inputs":[{"intent":"action.devices.SYNC"}],"requestId":"5604033533610827657"}
headers: {}
Unlike "Discover Directive" of Alexa's skill, which contains token in request.directive.endpoint.scope.token, google's intent doesn't seems to carry it. For O Auth, I am using AWS Cognito which works fine with Alexa Account linking and for google home too it can successfully link the account and show devices which I hardcode in lambda function.
As per this answer, the token is in
headers.authorization.substr(7)
I've tried that and got nothing. It shows
"Cannot read property 'substr' of undefined".
The lambda handler in the Actions on Google client library assumes that the request headers are present at event.headers within the input event parameter of a Lambda Proxy Integration. If you have a custom Lambda integration or have otherwise modified the input mapping, you may need to edit your mapping template to ensure the headers are placed where the client library expects.
I have some web-enabled actions that are exposed through API Connect in IBM Cloud Serverless Functions.
Some of my actions use request-promises to call external REST services and I need to be able to catch an error and respond with an appropriate status-code to the caller.
Since the actions are web-enabled, the documentation indicates that I can use an annotated JSON to set the headers, status-code and body of the response. But it seems that, seems the API expects to always get a Content-Type=application/json, the response processor is failing to understand my annotations in the case of an error.
I tried the following without success:
let rp = require('request-promise');
function main(params){
//setup options
return rp(options).then(
res => {
return res;
}
).catch(
err => {
return { error: { statusCode:err.statusCode } }
}
);
}
Another variation:
let rp = require('request-promise');
function main(params){
//setup options
return rp(options).then(
res => {
return res;
}
).catch(
err => {
return { statusCode:err.statusCode }
}
);
}
The problem is that the status-code I always get is 200... I also tried to change the runtime to node8.0 without success.
Thanks!
I found the answer myself :)
In order to get the status-code and headers, one must set the field Response Content Type to `Use "Content-Type" header from action", while setting up the mapping between the API call and the action....
I am using AWS Lambda and API Gateway to create a custom endpoint for load tests. I have uploaded my handler function which is in a file, along with the node modules needed for the function in a zip, and set up the API Gateway API correctly according the instructions (in line with the way that I had made it work before), but I keep getting the error: {"error": "Missing Authentication Token"}. Everything I have seen online thus far points to the idea that the url that I am passing in with the POST request is invalid, but I have made a similar endpoint work with a GET request. As far as I know I have set up the POST request (using Superagent) correctly, and am passing in a valid access-token, as well as hardcoded params as part of the URL (valid params).
// Dependencies
var request = require('superagent');
var sync = require('synchronize');
exports.handler = function(event, context) {
sync.fiber(function() {
// Grabs params passed into the URL as a JSON object
var querystring = (event.querystring);
// Replaces params with an updated version which includes a single quotation
var queryStringUpdate = querystring.replace(/=/g, ":").replace(/}/g, "'}").replace(/:/g, ":'").replace(/,/g, "',");
// Updates the param information and sets it as a new string
eval('var queryString2 =' + queryStringUpdate);
// Define specific query params to be used in the REST calls
var userId = (queryString2.userId === undefined ? '229969' : queryString2.userId);
var roomdId = (queryString2.roomId === undefined ? '4' : queryString2.roomId);
var inviterId = (queryString2.inviterId === undefined ? '212733' : queryString2.inviterId);
var createInvitePost = function() {
request
.post('https://some_url/v2/invites/212733/create')
.set({'access-token': 'some_access_token'})
.set('Content-Type', 'application/json')
.query({user_id: "229969"})
.query({room_jid: "4"})
.end(function(err, res){
if (err) {
context.fail("Uh oh, something went wrong");
} else {
context.done(null, "Hurray, it worked!!");
}
});
};
try {
createInvitePost();
} catch(errOne) {
alert("No bueno!!");
}
});
};
Any thoughts on this?? Thanks
I usually get this error when I've missed some part of the URL needed for my API. In the past it's either been the name of the stage, misspelled resource name, or a missing Path parameter.
I'm from the Api Gateway team.
As others have said, the most common cause of the 403 response you're getting is an incorrect path/method. I'm not familiar with Superagent, but if you've run the same request in Postman and cURL then I would be surprised if you had the wrong path/method.
Maybe also check on a wire log if possible, to make sure that your querystring logic isn't appending a forward slash prior to the '?'.
Some things to check:
Have you deployed any recent changes to your API?
Is the stage 'v2' (I'm assuming that's the stage) pointing at a deployed version of the API that has the POST to invites/212733/create?
The 'access-token' should have no effect on the Api Gateway layer. If you're trying to use a native Api Gateway Api Key, the header is 'x-api-key'.
Jack