Reputation: 227
I have a simple application that doesn't use very many packages. So I thought this would be the perfect opportunity to try out Deno, the one package I do require that isn't a third-party module is the Twitter API. No problem I thought since I don't need many of the functions it includes. I might as well write it myself!
So I wrote a function for generating an Bearer token using this doc from the Twitter docs:
function getOAuthBearer(consumer_key, consumer_secret) {
const basic = Buffer.from(`${consumer_key}:${consumer_secret}`).toString('base64')
const options = {
url: 'https://api.twitter.com/oauth2/token',
method: 'POST',
headers: {
'Authorization': `Basic ${basic}`,
'Content-Type': `application/x-www-form-urlencoded;charset=UTF-8`
},
body: querystring.stringify({
'grant_type': 'client_credentials'
})
};
return new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) reject(error);
else resolve(JSON.parse(body).access_token);
});
});
}
Which works! I got my bearer token, so I wrote a function to fetch some user_timeline
information from a request example from this doc
function getUserTimeline(bearer_token) {
const options = {
url: 'https://api.twitter.com//1.1/statuses/user_timeline.json?count=100&screen_name=twitterapi',
method: 'GET',
headers: {
'Authorization': 'Bearer ' + Buffer.from(bearer_token).toString('base64'),
}
}
return new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) reject(error);
else resolve(JSON.parse(body));
});
});
}
Which returns this:
{ errors: [ { code: 89, message: 'Invalid or expired token.' } ] }
Which is weird but I thought I could just invalidate the bearer and request a new one for which I wrote this function:
function invalideOAuthBearer(consumer_key, consumer_secret, bearer_token) {
const basic = Buffer.from(`${consumer_key}:${consumer_secret}`).toString('base64');
const options = {
url: 'https://api.twitter.com/oauth2/invalidate_token',
method: 'POST',
headers: {
'Authorization': `Basic ${basic}`,
'Content-Type': `application/x-www-form-urlencoded;charset=UTF-8`
},
body: querystring.stringify({
'access_token': bearer_token
})
};
return new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) reject(error);
else resolve(JSON.parse(body));
});
});
}
But this returns:
{ errors: [ { code: 348, message: 'Client application is not permitted to to invalidate this token.' } ] }
So now I'm somewhat stuck, I tried regenerating my credentials and that doesn't do much. I searched online but could only find old post of people saying it's a bug/infrastructure issue but since there are so many applications using the Twitter API this seems unlikely to me, and of course, there are people just recommending using a package like twitter, which I would but like I said the Deno platform doesn't have any packages like this :(
Upvotes: 1
Views: 555
Reputation: 141
The bearer token shouldn't be base64 encoded. Try this:
const options = {
url: 'https://api.twitter.com//1.1/statuses/user_timeline.json?count=100&screen_name=twitterapi',
method: 'GET',
headers: {
'Authorization': `Bearer ${bearer_token}`,
}
}
Upvotes: 2