0

I am attempting to post a tweet to Twitter from my NodeJS code (Lambda function). Using all my tokens in Postman, it works, the tweet goes. I've never used OAuth1 from Node before, and most references I'm finding online ate many years old using deprecated libraries (i.e. request)

Here's my code

const fetch = require('node-fetch');
const OAuth = require('oauth-1.0a');
const crypto = require('crypto');

...
const oauth = OAuth({
  consumer: {
      key: 'xxxxxxxxxxxxxxxxxxxxxxxxx',
      secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  },
  signature_method: 'HMAC-SHA1',
  hash_function(base_string, key) {
      return crypto
          .createHmac('sha1', key)
          .update(base_string)
          .digest('base64')
  },
})

const request_data = {
  url: 'https://api.twitter.com/2/tweets',
  method: 'POST',
  data: { text: 'Hello World!' },
}

const token = {
  key: 'xxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
}

const auth = oauth.authorize(request_data, token)

console.log('tweeting')
console.log(JSON.stringify(oauth.toHeader(auth)))
const tweetResp = await fetch(request_data.url, {
  method: request_data.method,
  body: request_data.data,
  headers: {
    ...oauth.toHeader(auth),
    'Content-Type': 'application/json'
  }
})
if (tweetResp.status !== 200) {
  console.error('returned status', tweetResp.status, tweetResp.statusText)
  const postedTweet = await tweetResp.json()
  console.error(JSON.stringify(postedTweet))
  throw JSON.stringify(postedTweet)
}
console.log('tweet sent')

my logging output shows

INFO    tweeting
INFO    {"Authorization":"OAuth oauth_consumer_key=\"xxxxxxxxxxxxxxxxxxxxxxxxx\", oauth_nonce=\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\", oauth_signature=\"xxxxxxxxxxxxxxxxxxx%xxxxxxxxx%xx\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1672968399\", oauth_token=\"xxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\", oauth_version=\"1.0\""}
ERROR   returned status 401 Unauthorized
ERROR   {"title":"Unauthorized","type":"about:blank","status":401,"detail":"Unauthorized"}

If I remove the ...oauth.toHeader(auth), line from headers I get the same errors. I've also tried the got library, getting same 401 back...

David Lozzi
  • 14,697
  • 9
  • 28
  • 44

1 Answers1

0

Further googling and I found this functional code! This works great

async function getRequest({
  oauth_token,
  oauth_token_secret
}) {

  const token = {
    key: oauth_token,
    secret: oauth_token_secret
  };

  const authHeader = oauth.toHeader(oauth.authorize({
    url: endpointURL,
    method: 'POST'
  }, token));

  const req = await got.post(endpointURL, {
    json: data,
    responseType: 'json',
    headers: {
      Authorization: authHeader["Authorization"],
      'user-agent': "v2CreateTweetJS",
      'content-type': "application/json",
      'accept': "application/json"
    }
  });
  if (req.body) {
    return req.body;
  } else {
    throw new Error('Unsuccessful request');
  }
}
David Lozzi
  • 14,697
  • 9
  • 28
  • 44