Linkedin webhooks event subscription not working - javascript

I've been stuck on this issue for some time now, I am trying to subscribe to Linkedin's webhook using ngrok for testing on localhost, and have been trying for some time now, i have tried using encode uri's as well but still running into error, I have verified that the APP_ID, profileId and organizationId i'm using are correct, but still i get the same error. I have also tried using the Restli protocol that linkedin suggests in their documentation but to no avail.
let url = `https://api.linkedin.com/v2/eventSubscriptions/(developerApplication:urn:li:developerApplication:${config.IN.APP_ID},user:urn:li:person:${profileId},entity:urn:li:organization:${organizationId},eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS)`;
return new Promise((resolve, reject) => {
request(
{
url,
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
// 'X-Restli-Protocol-Version': '2.0.0',
},
json: {
webhook: "https://url.ngrok.io/api/v1/webhook/linkedin/callback"
},
},
(err, response, body) => {
if (err) {
reject(err);
} else {
resolve(body);
}
},
);
});
I have been receiving this error constantly no matter what I try, I have tried sending the url like this:
https://api.linkedin.com/v2/eventSubscriptions/(developerApplication:urn:li:developerApplication:{${config.IN.APP_ID}},user:urn:li:person:{${profileId}},entity:urn:li:organization:{${organizationId}},eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS)
https://api.linkedin.com/v2/eventSubscriptions/${encodeURIComponent((developerApplication:urn:li:developerApplication:${config.IN.APP_ID},user:urn:li:person:${profileId},entity:urn:li:organization:${organizationId},eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS))
All I receive is this error
'{"serviceErrorCode":100,"message":"Unpermitted fields present in RESOURCE_KEY: Data Processing Exception while processing fields [/key]","status":403}'
Any help would be appreciated, I have been stuck on this for a while now.

The request seems to be OK , but the method should be GET (not PUT)

One thing is to check which ID are you using for application_id. The application ID is the one in the url - https://www.linkedin.com/developers/apps/<id from here>/settings
. You need to use and uncomment the header for Restli.
I'd say that your url needs to look like this, as this is from their original POSTMAN collection.
https://api.linkedin.com/v2/eventSubscriptions/(developerApplication:urn%3Ali%3AdeveloperApplication%3A{{application_id}},user:urn%3Ali%3Aperson%3A{{person_id}},entity:urn%3Ali%3Aorganization%3A{{organization_id}},eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS)
You can validate here, their full collection - https://www.postman.com/linkedin-developer-apis/workspace/e781b3ac-4101-4d60-8981-afcb4812623d/request/16069442-9d0bf046-ea81-4af0-9515-d07246a0ab39

LinkedIn webhooks does not support ngrok URIs

Related

Can't find any way to get POST requests working Reddit API - 403 Error

I'm trying to build a reddit-like app on react native, so i'm using axios to fetch requests to Reddit Api and I can't seem to be able to fetch any POST requests, I've tried everything I can, I'm trying to subscribe to a subreddit, here is my request :
subscribe: async function subscribe(action, sub, modhash) {
try {
const token = await this.getAccessToken();
console.log('token: ' + token)
let Headers = {'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
'X-Modhash': modhash}
let Params = {'action': action, 'sr_name': sub}
let Body = {'api_type': "json", "extension": "json"}
await axios.post('https://oauth.reddit.com/api/subscribe', Headers, Params, Body)
.then((response) => {
console.log('sub: ' + JSON.stringify(response.data));
console.log("Subbed to " + sub)
})
} catch (error) {
throw 'Could not sub: ' + error
}
},
Here is the Catch result:
"Could not sub: Error: Request failed with status code 403"
here is the official api about subscribe : https://www.reddit.com/dev/api/#POST_api_subscribe
action = "sub" and sr = "t5_2qh03" and I tried sr_name and sr but none seems to work, I'm sure the token is valid since it works with other GET requets I can't find what I did wrong here. Do you guys have any idea on what I'm missing ?
Edit: I've tried the same request with postman and the request actually worked, i did sub to a subreddit, but the same exact request is not working with axios, does my request is okay ?
To me, your code is alright.
However, the Reddit API is such a clusterfuck, that peoples are not much using it.
They are using pupeeter and similar.
For your problem, it all depends of the subreddit, some (many) are not allowing to POST by API at all, of course without warning, or with totally unclear HTTP error codes It just doesn't work.
There is also situations where it works, but only sometimes, or only the first time, or only from an IP of a given allowed country.
They are also widely using black/grey/white listing, shadow banning, and rate limiting. But no notices are ever given. The definition of a clusterfuck.

I can get correct response with Postman but body of the fetch response is empty

I send post request to my API that contains userName and password in the body. When I do that with Postman I can get a response which has a body contains a token.
But when I send the same request with fetch in fronted I get a responce with an empty body.
My feth is here:
async function login(){
await fetch('/auth/login',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(
{
'userName' : userName,
'password' : password,
}
)
}
).then(
res => {
console.log(res)
localStorage.setItem('Authorization',JSON.stringify(res))
}
).catch(
err => {
console.log("Erorororor: " + JSON.stringify(err))
}
)
}
What is the problem?
I changed my code to
.then(res => return res.text()).then(data => console.log(data)).catch(...)
and now I can get the result which I want.
TLDR Solution
It's caused by some header settings from the server side (For example, setting Access-Control-Allow-Origin: *
twice will likely cause this issue). By tuning the headers you can fix it.
Details
I met the same issue. It's NOT caused by javascript code as the browser itself doesn't get body either, but headers and cookies are got.
By expanding the timing tab you can see a warning showing the request is not finished!
But the postman can get the body:
When
The same code works in the past. It came out recently. I'm not sure what's changed as there are many things changed, for example, the browser version, the nodejs version upgraded, etc.
Fixed
By tunning the headers in the server side fixed the problem.

Invalid input response and secret when verifying google reCaptcha

I am really struggling to get a successful response when doing a post request to the google recaptcha api. I am receiving the following response:
{
"success": false,
"error-codes": [
"invalid-input-response",
"invalid-input-secret"
]
}
I had a look at reCAPTCHA - error-codes: 'missing-input-response', 'missing-input-secret' when verifying user's response (missing details on POST) and followed the answer as closely as possible but with no success.
Here is my file below:
var request = require('request');
module.exports = {
verifyCaptcha: function(req, res) {
var secret = 'SECRET_KEY';
var response = JSON.stringify(req.body.response);
request({
url: 'https://www.google.com/recaptcha/api/siteverify',
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `secret=${secret}&response=${response}`,
}, function (err, response, body) {
if (err) {
res.status(500).send({
error: "Could not verify captcha"
});
} else {
res.status(200).send({
message: body
});
}
});
},
}
If anyone has a solution to this problem please let me know!
Due to the docs: https://developers.google.com/recaptcha/docs/verify
invalid-input-secret: The secret parameter is invalid or malformed.
Maybe you have mixed the site_key and the secret_key.
You need to add the user remote IP address.
var user_ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
request({
url: 'https://www.google.com/recaptcha/api/siteverify',
method: 'POST',
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `secret=${secret}&response=${response}&remoteip=${user_ip}`}...
Another thing I see that you are not using template literal, you should change the quotes to ` instead of '.
OR, You should use a ready-made module for reCaptcha, like this one:
https://www.npmjs.com/package/recaptcha
For reCAPTCHA Enterprise, check the official docs: https://cloud.google.com/recaptcha-enterprise/docs/create-assessment.
In short, you need to use the library that Google provides:
const { RecaptchaEnterpriseServiceClient } =
require('#google-cloud/recaptcha-enterprise');
const client = new RecaptchaEnterpriseServiceClient();
const [ response ] = await client.createAssessment({...});
RecaptchaEnterpriseServiceClient requires a service account to be created beforehand as described here. The key for that account with the right roles set can then be read by the app. Check the arguments of the constructor to see the available options to pass the data if the file cannot be retrieved automatically.
var response = JSON.stringify(req.body.response);
The stringifying here is probably the cause of the invalid-input-response error.
If your body is something like {"g-recaptcha-response": "..."}, you need to pull out the response value and pass that directly in your post.
Regarding invalid-input-secret, if you have set up your key and secret through the classic interface at https://www.google.com/u/1/recaptcha/admin/create, then you shouldn't have a problem.However if you set up a key with recaptcha Enterprise on Google Cloud, then it requires that you do Oauth authentication to the Google Cloud API and then use the create.assessment endpoint to get back information on the validity of the user. As Yuuhn implied, the Google provided library makes interaction with recaptcha Enterprise easier, without a lot of documentation digging to find where your REST API calls need to go.

Unsupported grant type when getting OAuth token for Reddit API

I'm trying to get an OAuth token for the Reddit API following the Application Only OAuth instructions. My reddit app is an installed app, so for my grant_type I'm using https://oauth.reddit.com/grants/installed_client.
Currently I'm running a very short JS script to query the API and get a token:
const APP_ID = 'MY_APP_ID'
const DEVICE_ID = 'TRACKING_ID_20_TO_30_CHARS'
let form = new FormData()
form.append('grant_type', 'https://oauth.reddit.com/grants/installed_client')
form.append('device_id', DEVICE_ID)
fetch('https://www.reddit.com/api/v1/access_token', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${btoa(`${APP_ID}:`)}`,
}),
body: form })
.then(handleResponse)
.then(function(data) {
console.log(data)
})
.catch(error => console.error(error))
function handleResponse(response) {
return response.json()
}
(Note: running the snippet as-is will give you a NetworkError because the APP_ID isn't a real one and I don't want to give mine out.)
The response I get is:
{
"error": "unsupported_grant_type"
}
When I try the same API request using a REST client I get back the expected response, so this makes me think that the problem is JavaScript-related. Since the grant_type matches what the instructions say I'm not really sure what to do with the error. I'm hoping someone else more experienced with OAuth will know what is going on here.
The problem was the use of the FormData object. In earlier stages of troubleshooting I found this answer on Reddit and decided to use it, but that didn't work for me.
It was submitting the data as multipart/form-data rather than application/x-www-form-urlencoded, which Reddit's OAuth server did not like. I wrote a helper function based on this answer which did the trick:
function urlEncode(data) {
let out = [];
for (let key in data) {
out.push(`${key}=${encodeURIComponent(data[key])}`);
}
return out.join('&')
}

Get browser response headers on API call (I'm using Meteor but vanilla would be helpful too)

I'm making an API call (specifically to stubhub) and I want to get the response headers found in the browser network tab:
Here's my API call (using Meteor HTTP)
HTTP.post('https://api.stubhub.com/login', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + base64
},
params: {
'grant_type' : 'password',
'username' : username,
'password' : password,
'scope' : 'PRODUCTION'
}
}, function(err, res) {
if (err) {
console.log(err)
} else {
console.log(res);
}
})
I console.log 'res' to see everything, and I saw a few objects but main ones are header and data. Data is the content object which is usable in other ways, but header just returns this:
How do I get the Response Headers?
Figured it out. I was making this call client-side (obviously not secure, just to get my app up and running/testing). If you make the call server-side, say via a Meteor method, the full header field will be available in the response.

Categories

Resources