I'm trying to create a GotoWebinar webhook but I'm getting 400 bad requests each time
this is my callBackUrl function
Route::get('g2w/webhook', function(Request $request) {
return response()->json([
'success'=>true
],200);
});
this is my post webhook creation request to https://api.getgo.com/G2W/rest/v2/webhooks
[
{
"callbackUrl":"https://website.com/g2w/webhook/",
"eventName":"webinar.created",
"eventVersion":"1.0.0",
"product":"g2w"
}
]
and always I get this error
{
"timestamp": 1609341614915,
"status": 400,
"error": "Bad Request",
"exception": "com.logmein.webhooks.exceptions.InvalidRequestException",
"message": "Invalid callbackUrl. callbackUrl not returning 200 OK as response. Please retry after sometime",
"path": "/v1/webhooks"
}
GotoWebinar webhooks documentation
Thanks for helping
You callback endpoint needs to accept both GET and POST request. Change the 'g2w/webhook' route to:
Route:match(['get', 'post'], 'g2w/webhook', function(Request $request) {
return response()->json([
'success'=>true
],200);
});
Related
I'm trying to use Google Identity platform api's with my firebase project ( I configured a payment method to use the identity platform sendOobCode and sendVerificationCode methods. But I keep receiving a 400 ERROR.
I tried using the built-in api calls in the console and got back more detailed errors.
"errors": [ { "message": "CONFIGURATION_NOT_FOUND", "domain": "global", "reason": "invalid" } ] }
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
var url = 'https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=[]';
var data = {
// requestType: "VERIFY_EMAIL",
idToken: userCredential._tokenResponse.idToken
}
console.log(userCredential)
axios.post(url, data, {
headers: {
'Content-Type': 'application/json'
}
}).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
})
})
.catch((error) => {
.....
})
So I was able to get more information on my error by going into the Network Section in the dev tools. I checked the 400 request error and found in the response that I have an invalid API key. I forgot to remove the [] :)
I got some troubles configuring an Hasura auth hook using a Lambda. I need such a function as I am storing my JWT token in an HTTP-only cookie, for security reasons.
I'm using a serverless function which returns a correct response (either when testing a curl request directly, or even when logging lambda):
{
"statusCode":200,
"body":"{\"X-Hasura-User-Id\":\"74d3bfa9-0983-4f09-be02-6a36888b382e\",\"X-Hasura-Role\":\"user\"}"
}
Yet, Hasura hook doesn't seem to recognize the response:
{
"type": "webhook-log",
"timestamp": "2020-02-07T10:27:34.844+0000",
"level": "info",
"detail": {
"response": null,
"url": "http://serverless:3000/auth",
"method": "GET",
"http_error": null,
"status_code": 200
}
}
These two lines of logs are adjacent in my logs. I just reformatted them a little bit to ease reading.
My lambda code looks like:
export const handler = async (event) => {
const cookies = getCookiesFromHeader(event.headers);
const { access_token: accessToken } = cookies;
let decodedToken = null;
try {
const cert = fs.readFileSync("./src/pem/dev.pem");
decodedToken = jwt.verify(accessToken, cert);
} catch (err) {
console.error(err);
return {
statusCode: 401,
};
}
const hasuraClaims = decodedToken['https://hasura.io/jwt/claims'];
return {
statusCode: 200,
body: JSON.stringify({
"X-Hasura-User-Id": hasuraClaims['x-hasura-user-id'],
"X-Hasura-Role": hasuraClaims['x-hasura-default-role']
})
}
}
Any idea on what is going on? Note that I'm using serverless offline, in case of. :)
In AWS Lambda, the spec requires the response body to be stringified and the actual response will be a parsed JSON object which is what Hasura will receive from the auth webhook.
When you are using serverless-offline, the response body is returned as a String (since JSON.stringify is used) without getting parsed. A simple curl will give you the difference.
The above code will work on Lambda but not on local development using serverless-offline. You will have to use the event object to see if isOffline is true and return JSON directly and if not return the stringified version.
Example code:
if(event.isOffline) {
// make it work with serverless-offline
return { "x-hasura-role": "user" ....};
} else {
// make it work with lambda
return { statusCode: 200, body: JSON.stringify({"x-hasura-role": "user"}) };
}
Official example in the serverless-offline repo along with error handling.
Related issues:
https://github.com/dherault/serverless-offline/issues/530
https://github.com/dherault/serverless-offline/issues/488
I am sending a payload to facebook bot API something similar to:
{
"recipient":{
"id":"some-recipient-id"
},
"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"generic",
"elements":[ ... ]
}
},
"quick_replies":[ ... ]
}
}
The EXACT same payload sometimes succeeds and sometimes throws me an error like this:
HTTP 400:
{
"message":"(#-1) Unexpected internal error",
"type":"OAuthException",
"code":-1,
"error_subcode":2018012,
"fbtrace_id":"some-trace-id"
}
Can this be related to:
https://developers.facebook.com/status/issues/559896447845433/
I am referring to Amazon documentation for the purpose of Customer Authentication. Currently, I am using LWA.
Steps I followed:
I enabled the Send Alexa Events Permission from the Alexa developer Console in Build > Permission page.
I took the grant code from the request in the cloudwatch logs which was sent when I logged in using Alexa companion app.
Example:-
{
"directive": {
"header": {
"messageId": "Example",
"name": "AcceptGrant",
"namespace": "Alexa.Authorization",
"payloadVersion": "3"
},
"payload": {
"grant": {
"code": "Example2",
"type": "OAuth2.AuthorizationCode"
},
"grantee": {
"token": "Example3",
"type": "BearerToken"
}
}
}
}
Permission Page under build on Alexa Developer console gave me client-Id and client-secret Which I used for making the post request to https://api.amazon.com/auth/o2/token.
Example:-
POST /auth/o2/token HTTP/l.l
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
grant_type=authorization_code&code=&client_id=&client_secret=
I passed the code,client_id, and client_secret in the above example and made the post request to this URL https://api.amazon.com/auth/o2/token
I tried using x-www-form-urlencoded;charset=UTF-8 and also JSON for the Content-Type.
I followed the step given in the above documentation and I am stuck on the error ( 401 Unauthorized ):
{
"error_description": "The request has an invalid grant parameter : code",
"error": "invalid_grant"
}
I tried implementing it using Python code and Postman both. Ending up with the Same above error scenario.
Here is a sample code to help you and others who are looking to send events to alexa gateway.
const AWS = require('aws-sdk');
AWS.config.update({region: 'eu-west-1'});
// Create the DynamoDB service object
const ddb = new AWS.DynamoDB({ apiVersion: 'latest' });
const doc = new AWS.DynamoDB.DocumentClient({
convertEmptyValues: true,
service: ddb
});
// Using 'request' for http POST and GET request.
// https://www.npmjs.com/package/requests
// npm install --save requests
const r = require('request');
//Handle Authorization. Call this method from your lambda handler whenever you get Alexa.Authorization message. You will get this message only when you select permission to
//send events in your Smart Home Skill.
//Access to Event gateway allows you to enable Proactive Device Discovery and
//Proactive State Reporting in your skill
//More information on Alexa.Authorization can be found on https://developer.amazon.com/docs/device-apis/alexa-authorization.html
function handleAuthorization(request, context, user) {
//Even when you are using your own authentication, the url below will still
//point to amazon OAuth token url. The token you obtain here has to be stored
//separately for this user. Whenever sending an event to alexa event gateway you will
//require this token.
//URL below is for EU server. Look at following documentation link to identify correct url
//for your system.
//https://developer.amazon.com/docs/smarthome/send-events-to-the-alexa-event-gateway.html
var url = "https://api.amazon.com/auth/o2/token";
var body = {
grant_type : 'authorization_code',
code : request.directive.payload.grant.code,
client_id : 'your client id from permissions page on developer portal where you enable alexa events. This is id different than one you specify in account linking settings',
client_secret : 'client secret from permissions page'
}
//https://developer.amazon.com/docs/smarthome/authenticate-a-customer-permissions.html
r.post({
url: url,
form : body
}, function(error, response, b){
if (error) { return console.log(error); }
var body = JSON.parse(b);
var params = {
TableName: 'Devices',
Item: {
'id' : user,
'auth_token' : body.access_token,
'refresh_token' : body.refresh_token
}
}
log("DEBUG:", "Authorization Body", JSON.stringify(body));
log("DEBUG:", "Authorization Response", JSON.stringify(response));
log("DEBUG:", "Database Params", JSON.stringify(params));
// Call DynamoDB to add the item to the table
var putObjectPromise = doc.put(params).promise();
//Store auth_token and refresh_token in database. We will need these
//while sending events to event gateway.
//Send a success response.
putObjectPromise.then(function(data) {
var response = {
event: {
header: {
messageId: request.directive.header.messageId,
namespace: "Alexa.Authorization",
name: "AcceptGrant.Response",
payloadVersion: "3"
},
"payload": {
}
}
};
context.succeed(response);
}).catch(function(err) {
//TODO - Add a Authorization error response JSON here.
console.log(err);
});
});
}
After enabled CORS on API gateway, here is the request I sent to the http end point:
$.ajax({
type: 'put',
url: 'https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/artist/application/julian_test',
data: {params: {param1: "543543", param2: "fdasghdfghdf", test: "yes"}},
success: function(msg){
console.log(msg);
},
error: function(msg){
console.log(msg);
}
});
Here is the lambda function(I'm using node serverless package, and no mistakes on the code):
module.exports.julian_test = (event, context, callback) => {
console.log(event);
console.log(event.body);
var response_success = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({
firstUser: {
username: "Julian",
email: "awesome"
},
secondUser: {
username: "Victor",
email: "hello world"
},
thirdUser: {
username: "Peter",
email: "nice"
}
})
};
callback(null, response_success);
};
The console.log(event.body) logs out :
params%5Bparam1%5D=543543¶ms%5Bparam2%5D=fdasghdfghdf¶ms%5Btest%5D=yes
, which is not the format I want. I checked the OPTIONS Integration Request / body mapping template, here is the snapshot.
I tried to delete the "application/json" but after that I receive the following response:
XMLHttpRequest cannot load https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/artist/application/julian_test. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 500.
Does anyone know how to get a raw string request body in the back-end lambda? Please help!
The screenshot is for OPTIONS method which is used for CORS.
Your actual Lambda function call is likely made via POST method. Please check the integration request Body mapping templates under the POST method. If it is setup to pass through body (which is default), the body from your input request should be passed to Lambda as is.
Please use test feature in API Gateway console to see how the input is transformed to integration request. That should help you to debug.
Two things here:
Firstly, under your API Gateway resource, go to Method Response and make sure you have a response for 200 OK mapped.
Secondly, under your API Gateway resource, go to Integration Request, under Body Mapping Templates select application/json and enter the following code in the template text editor:
{
"method": "$context.httpMethod",
"body" : $input.json('$'),
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end
#end
},
"queryParams": {
#foreach($param in $input.params().querystring.keySet())
"$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
},
"pathParams": {
#foreach($param in $input.params().path.keySet())
"$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end
#end
}
}
When this is applied, you can access your request object as such: (Node.js)
console.log('Body:', event.body);
console.log('Headers:', event.headers);
console.log('Method:', event.method);
console.log('Params:', event.params);
console.log('Query:', event.query);
Took me a while to figure this out, props to Kenn Brodhagen for the explanation:
tutorial
The only way get real raw AWS Lambda request is via Stream for Handler Input.
As per documentation:
The input payload must be valid JSON but the output stream does not carry such a restriction. Any bytes are supported.
Example of streaming AWS Lambda input and output in Java:
public void handler(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
int letter;
while((letter = inputStream.read()) != -1)
{
outputStream.write(Character.toUpperCase(letter));
}
}
Tom's answer above adds everything except the raw request body. Adding this line to that mapping template allowed me to verify requests as per Slack's documentation:
"rawBody": $util.escapeJavaScript($input.body)