Harrison Cramer
Harrison Cramer

Reputation: 4496

Posting Twitter Thread via Twit w/ Node.js

I'm using Node and the npm Twit module to post tweets to Twitter. It's working....sort of.

I'm able to successfully post a single tweet wihtout any problems. However, when I attempt to post a string of tweets together (like a thread on Twitter) the tweets don't display correctly. Here's the relevant bit of my code.

Essentially, I can post the initial tweet no problem (the "first" argument in the function). I then get that tweet's unique ID (again, no problem) and attempt to loop through an array of strings (the "subsequent" argument) and post replys to that tweet. Here's the code:

const tweet = (first, subsequent) => { 
  bot.post('statuses/update', { status: `${first}` }, (err,data, response) => {
    if (err) {
      console.log(err);
    } else {
      console.log(`${data.text} tweeted!`);

   /// Find the tweet and then subtweet it!
      var options = { screen_name: 'DoDContractBot', count: 1 };
      bot.get('statuses/user_timeline', options , function(err, data) {
        if (err) throw err;

        let tweetId = data[0].id_str;
        for(let i = 1; i < subsequent.length; i++){
          let status = subsequent[i];
          bot.post('statuses/update', { status, in_reply_to_status_id: tweetId }, (err, data, response) => {
            if(err) throw err;
            console.log(`${subsequent[i]} was posted!`);
          })
        }

      });
    }
  });
};

For whatever reason, the tweets aren't showing up under the same thread on Twitter. Here's what it looks like: (there should be two more 'subtweets' here. Those tweets "post" but are separated from the original):

enter image description here

Has anyone else had similar problems with the Twitter API? Any idea how to more gracefully do a thread via Twit? Thanks!

Upvotes: 1

Views: 1571

Answers (2)

Alpha Olomi
Alpha Olomi

Reputation: 115

Using twit-thread

Twit Thread is a Node.js module written in Typescript that add utility functions to Twit Twitter API Wrapper and help you implement threads in your twitter bot.

const { TwitThread } = require("twit-thread");
// or import { TwitThread } from "twit-thread" in Typescript

const config = {
  consumer_key:         '...',
  consumer_secret:      '...',
  access_token:         '...',
  access_token_secret:  '...',
  timeout_ms:           60*1000,  // optional HTTP request timeout to apply to all requests.
  strictSSL:            true,     // optional - requires SSL certificates to be valid.
};

}
async function tweetThread() {
   const t = new TwitThread(config);

   await t.tweetThread([
     {text: "hello, message 1/3"}, 
     {text: "this is a thread 2/3"}, 
     {text: "bye 3/3"}
   ]);
}

tweetThread();

More info: https://www.npmjs.com/package/twit-thread

Upvotes: 4

Harrison Cramer
Harrison Cramer

Reputation: 4496

I figured out what to do.

As Andy Piper mentioned, I needed to respond to the specific tweet id, rather than the original tweet id in the thread. So I refactored my code by wrapping the twit module in a promise wrapper, and used a for loop with async/await. Like this:

const Twit = require('twit');
const config = require('./config');
const util = require("util");
const bot = new Twit(config);

// Wrapping my code in a promise wrapper...
let post_promise = require('util').promisify( // Wrap post function w/ promisify to allow for sequential posting.
  (options, data, cb) => bot.post(
    options,
    data,
    (err, ...results) => cb(err, results)
  )
);

// Async/await for the results of the previous post, get the id...
const tweet_crafter = async (array, id) => { 
  for(let i = 1; i < array.length; i++){
    let content = await post_promise('statuses/update', { status: array[i], in_reply_to_status_id: id });
    id = content[0].id_str;
  };
};

const tweet = (first, subsequent) => { 
  post_promise('statuses/update', { status: `${first}` })
    .then((top_tweet) => {
        console.log(`${top_tweet[0].text} tweeted!`);
        let starting_id = top_tweet[0].id_str; // Get top-line tweet ID...
        tweet_crafter(subsequent, starting_id);
    })
    .catch(err => console.log(err));
};

module.exports = tweet;

Upvotes: 2

Related Questions