Foursquare API - can't get User (my own) check in history - node.js

I have been referencing this https://developer.foursquare.com/docs/api/users/checkins
to try and download my own check in history.
I was able to get their own example from the "getting started" page to work:
const request = require('request');
request({
url: 'https://api.foursquare.com/v2/venues/explore',
method: 'GET',
qs: {
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET',
ll: '40.7243,-74.0018',
query: 'coffee',
v: '20180323',
limit: 1
}
}, function(err, res, body) {
if (err) {
console.error(err);
} else {
console.log(body);
}
});
When I tried to change this to get my own checkins by replacing the url above this endpoint, https://api.foursquare.com/v2/users/USER_ID/checkins, it gives me an error requiring a version (even though it's not in the parameters docs).
I've left in the v param from the example and get this error: "A user is required to call this endpoint." I have also tried changing the URL because some examples online had this/the docs say regarding the userid: "For now, only self is supported" I tried replacing the USER_ID with my userid and also tried this: https://api.foursquare.com/v2/users/self/checkins, but it gives me the same error.
qs: {
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET',
v: '20180323',
user_id: 'userid' //tried with self, tried without it
}
I don't care about getting this to work as much as I do being able to download my own foursquare data. The link that I was able to use about 5 years ago is no longer supported.

You can not use client_id and client_secret parameters in this API (User Auth API). Try the following parameters:
qs: {
oauth_token: 'OAUTH_TOKEN',
v: '20180323',
user_id: 'self'
}
How to get oauth_token
https://developer.foursquare.com/docs/api/configuration/authentication

Related

401 failed request when trying to exchange authorization code for tokens w/ google

I'm struggling with this specific step in the Google OAuth process: "Exchange authorization code for tokens" (As called in Google Developers' "OAuth 2.0 Playground", Step 2).
function getGoogleAuthURL() {
const rootUrl = "https://accounts.google.com/o/oauth2/v2/auth";
const options = {
redirect_uri: `http://${HOST}:${PORT}/auth/google`,
client_id: `${googleConfig.clientId}`,
access_type: "offline",
response_type: "code",
prompt: "consent",
scope: defaultScope.join(" "), // A list of scopes declared in the file scope
};
return `${rootUrl}?${querystring.stringify(options)}`;
}
app.get("/auth/google/url", (req, res) => {
res.redirect(getGoogleAuthURL());
});
After redircting the user to the consent prompt, the code above redirect the user to: http://${HOST}:${PORT}/auth/google, giving the 'Authorization code' necessary to get the refresh and access tokens.
app.get(`/auth/google`, async (req, res) => {
const code = req.query.code
const tokens = await getTokens({code})
});
My problem is coming from the getToken() function that is used to POST and return the tokens.
function getTokens({code}) {
const url = 'https://accounts.google.com/o/oauth2/token';
const values = {
code,
client_id: googleConfig.clientId,
client_secret: googleConfig.clientSecret,
redirect_uri: googleConfig.redirect,
grant_type: 'authorization_code',
};
console.log(`${url}${querystring.stringify(values)}`)
return axios
.post(url, querystring.stringify(values), {
headers: {
'Content-Type': 'application/x-www-form-url-encoded',
},
})
.then((res) => res.data)
.catch((error) => {
throw new Error(error.message);
});
}
I get Error: Request failed with status code 401 from the .catch((error) ...
The console.log(${url}${querystring.stringify(values)}) gives the full built link, which is:
https://accounts.google.com/o/oauth2/tokencode=X&client_id=X.apps.googleusercontent.com&client_secret=X&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fdashboard%3B&grant_type=authorization_code
What I troubleshooted:
I've compared many times my 'request' and 'url' with the ones on Google Developers' "OAuth 2.0 Playground", and the syntax doesn't seem to be the problem with the fields, though I have doubt about the punctuation between /token and code=... that I changed to /token and ?code=..., but still resulting in a failed request (401).
I've also been using two different ${url}:
https://oauth2.googleapis.com/token
https://accounts.google.com/o/oauth2/v2/auth
But I can tell which one I should be using.
The second param of axios post is the body, not query params.
You can set params in the third argument.
axios.post(url, {}, {
headers: { 'Content-Type': 'application/x-www-form-url-encoded' },
params: {
tokencode: values.code,
// etc
}
}
You are also missing key for code in your values object.
You can also just append the querystring in the first argument:
axios.post(url + querystring.stringify(values),{}, {
headers: {
'Content-Type': 'application/x-www-form-url-encoded'
},
})

Why do I get a 404 response when I try to post to github API whilst authenticated with oauth access tokens?

I am using the passportjs library to authenticate users into the application. An access token is usually generated when users authenticate successfully with passportjs. I am attempting to create a branch with the github API with this access token but without much success, both using the octokit wrapper as well as posting with super-agent.
I first attempted to authenticate the octokit by providing it username and password, in this fashion.
let octokit=new Octokit({
auth:{
username:username,
password:password
}
});
I was then able to create a ref/branch without much issue. However, when I did the same but with accesstokens generated by github SSO, like this
passport.use(new GitHubStrategy({
clientID: keys.clientId,
clientSecret: keys.clientSecret,
callbackURL: "/auth/github/callback"
},
async (accessToken, refreshToken, profile, done) => {
let octokit = new Octokit(auth: `token ${accessToken}`);
const branchName = 'refs/heads/vue' + Math.random();
let masterHash = '123x123x1231232';
octokit.git.createRef({
owner: owner,
repo: 'gitDemo',
ref: branchName,
sha: masterHash
}).then((data) => {
console.log('data ', data);
});
}
I receive an HttpError: Not found error. Another method that I tried is to post directly to the end point with superagent, putting the acccess code in the authorization header.
const data={
ref:'refs/heads/FooBranch',
sha:masterHash
};
const res2=await request.post('https://api.github.com/repos/SomeOwner/SomeRepo/git/refs')
.set('Authorization','token '+accessToken)
.send(data);
However, I still receive an HttpError :not found issue. I am quite confused as to what I may have done wrong. Thank you and any help would be greatly appreciated!
I found the anwser here
Basically you don't send data using JSON but rather FormData.
So the post should look like this (copied from link):
let data = new FormData()
data.append('client_id', options.client_id)
data.append('client_secret', options.client_secret)
data.append('code', code)
fetch(`https://github.com/login/oauth/access_token`, {
method: 'POST',
body: data
})
In case anyone else comes across this in the future, you have to specify the Content-Type and Accept when making the request. Without specifying it in the headers you will have to send and receive FormData.
Kudos #Github for not mentioning this at all in their docs.
Using node's built in fetch:
const githubRes = await fetch(githubUrl, {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
code,
client_id: config.github.clientId,
client_secret: config.github.clientSecret,
redirect_uri: config.github.redirectUri,
}),
});
const githubJson = await githubRes.json();
const token = githubJson.access_token;

How to access Wordpress authentication token

We are trying to link our website to Wordpresses API using OAuth 2.0. Hoping that a client can authenticate and post to WordPress from our site. We need to receive an access token to do this.
We have successfully connected with Wordpress to receive our access code. We've followed the Wordpress api, and have it working for a single user (with secret key not with OAuth). Things we have tried are adding a headers, changing data to different names examples: params, body
This is a simplified version of the code we have been using
const axios = require('axios');
axios({
method: "POST",
data: {
grant_type: 'authorization_code',
client_id: '12345',
client_secret: 'ABCABC1235412345',
code: 'Abc123',
redirect_uri: 'https://localhost:5000/wordpress/callback_wordpress'
},
url: 'https://public-api.wordpress.com/oauth2/token'
}).then( (response) => {
console.log(response);
}).catch( (error) => {
console.log(error);
});
We expect to receive a jwt access token, but instead are getting this 400 error:
data:
{ error: ‘invalid_client’,
error_description: ‘The required “client_id” parameter is missing.’ } } }
It seems clear that we are missing the client_id, however we have it included in our request. Is there somewhere else we need to include it?
var authOptions = {
url: 'https://public-api.wordpress.com/oauth2/token',
form:
{
grant_type: 'authorization_code',
code: code,
client_id: client_id,
client_secret: client_secret,
redirect_uri: redirect_uri,
},
headers: {
'Authorization': 'Basic ' + (Buffer.from(client_id + ':' + client_secret).toString('base64'))
},
json: true
};
We needed to include a header with that information, and we needed to use the variable 'form' instead of 'data'.

Facebook Messenger Bot - How to use NodeJS to get User Information?

I have a bare bones chatbot in messenger set up and would like to expand on its potential functionality. The first thing I want to be able to do is access user info, mostly the users first name. I know this is possible, but as I am new to NodeJS I am not sure how to achieve this. I have not been able to find very many tutorials on chatbots past the intro stage. Any help is greatly appreciated!
Below is a link to an abbreviated version of my chatbot
This is the main bit of code that I think needs refining (see it below in the context of the rest of the bot)
function getName(event){
request({
url: "https://graph.facebook.com/v2.6/" + sender,
qs: {
access_token : token,
fields: "first_name"
},
method: "GET",
}, function(error, response, body) {
if(error){
console.log("error getting username")
} else{
var bodyObj = JSON.parse(body)
name = bodyObj.first_name
sendText(sender, "Hi, ")
sendText(sender, name)
sendText(sender, " whatsup?")
}
})
}
Chatbot Code
You can get the facebook user info by below code:
request({
url: "https://graph.facebook.com/v2.6/" + senderId + "?",
qs: {
access_token: config.FB_PAGE_ACCESS_TOKEN
},
headers: {
'Accept': 'application/json',
'Accept-Charset': 'utf-8',
'User-Agent': 'test-bot'
},
method: "GET",
json: true,
time: true
},
function(error, res, faceUserInfo) {
console.log("faceUserInfo", faceUserInfo)
}
);
Double check your access token is correct.
I also suggest you check the what the error message is
console.log("error getting username", error);
Sender is not defined in your function.
It is being passed into your other functions, or delcared in the scope of your post request handler.
Make sure sender is defined, and your code should work fine.
Add the below line to your getName function:
var sender = event.sender.id
Your variable name is not defined, should add let name=... and it works fine

Mailchimp: The API key provided is linked to a different datacenter

I am trying to update a Mailchimp list but receive the following error:
{
"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/",
"title":"Wrong Datacenter",
"status":403,
"detail":"The API key provided is linked to a different datacenter",
"instance":""
}
However, the data-center referenced in my request URL is the same (us14) as the one suffixing my API key.
request.put({
url: 'https://us14.api.mailchimp.com/3.0/lists/xxxxxxxxx/members/',
auth: {
user: 'apikey:xxxxxxxxxxxxxxxxxxxxx-us14'
},
data: {
email_address: email,
status_if_new: 'subscribed',
email_type: 'html'
}
}
I have tried generating new API keys to no avail (they're all in us14).
Ok I was able to get this to work by first passing your API Key via the headers object. Second, I wrapped my data in JSON.stringify to ensure MailChimp was receiving a proper JSON Object on post. See below for sample code, hope this helps:
request.post({
url: 'https://usXX.api.mailchimp.com/3.0/lists/xxxxxxx/members',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic xxxxxxxxxxxxxxxxxxxxxxxxx-usXX'
},
form: JSON.stringify({
email_address: req.body.email,
status: 'subscribed',
interests: { 'xxxxxxx': true } // Interest Group
})
}, function(err, httpResponse, body) {
res.send(body);
});
const options = {
method: "POST",
auth: "uname:apikey656a******d2dfdb37c071a7cc-us19" //Should not give a space after a colon after uname
}
I had given a Space after the colon of uname. Now the API is working fine

Resources