Automate Twitter In 6 Steps: API, Common Features & Code Examples (2023)

Olivia Rhye
11 Jan 2022
5 min read

2022 was a pivotal year for Twitter: in-between Elon Musk's takeover that increased Twitter's number of daily active users and the popularity of AI tools like Midjourney or OpenAI's ChatGPT that will change content creation forever, 2023 will be the year of Twitter automation.

Twitter is the 9th most frequented website in the world, and it only takes a few minutes with Rowy to automate Twitter tasks like scheduling tweets or receiving notifications to improve your online presence there in a distraction-free environment: in the following article, we'll use Twitter's API combined with Rowy's powerful spreadsheet user interface to create 6 useful Twitter automation features.

Prerequisite: Obtain a Twitter API key

You'll a secret key to use the Twitter API. First, create a developer account on the Twitter Developer website. Then, add a new project and application: you'll be able to generate your API key to connect to Twitter programmatically later on.

Twitter API key dashboard - 0.jpg

Without further ado, let's get building!

6 Useful Features To Automate Twitter

1. Sending Tweets Via API

Publishing new tweets is the first valuable use case of automating your Twitter: the more you tweets, the more likely you are to grow your following. To get started, we need to create a new Rowy table that will contain our tweets and low-code cloud functions to interact with the Twitter API.

We'll just start simple with one tweet column containing a short text to tweet (no more than 280 characters), an Action column to publish it, and a tweet_id column to store the tweet ID returned by the Twitter API:

Rowy table including a column containing a tweet content and a publish action column - 1.jpg

We can use the Action column to run API calls, so we'll use the following code to publish the tweet. Just copy and paste it in the Action column settings and you'll be good to go:

const action:Action = async ({ row }) => {
  const res = await fetch('https://api.twitter.com/2/tweets', {
      method: 'POST',
      headers: {
      'Authorization': `Oauth ${generateOauth()}`,
      'Content-Type': 'application/json'
      },
      body: JSON.stringify({
          text: row.tweet
      })
  }).then(response => response.json())

  row.tweet_id = res.data.id
}

We make a POST request to the Twitter API's endpoint for creating tweets using the fetch function. The headers contain the API token we generated earlier, and the body holds the tweet content in the status field. Depending on your preferred OAuth method (1 or 2), the OAuth token will take different parameters to be generated. Check out the official Twitter documentation to figure out which method is more appropriate.

You can check the code works fine by clicking the Action button in the table. You should see a new tweet appear in your Twitter account:

A tweet published via API - 2.jpg

2. Retrieving Tweets and Replies

Tweeting isn't everything though. Engaging with others is key to grow online relationships, and for that you can retrieve data from the Twitter API to avoid missing replies to your tweets or interesting tweets from people you follow.

When you send a tweet from Rowy, we store the tweet ID in the tweet_id column. We can use this tweet ID to retrieve its replies using the following code:

const action:Action = async ({ row }) => {
  const replies = await fetch(`https://api.twitter.com/2/tweets/search/recent?query=conversation_id:${row.tweet_id}&tweet.fields=in_reply_to_user_id,author_id,created_at,conversation_id`, {
      headers: {
      'Authorization': `Bearer ${rowy.secrets.TWITTER_BEARER_TOKEN}`,
      'Content-Type': 'application/json'
      }
  }).then(response => response.json())
}

The only problem is the Search API can only retrieve tweets up to 7 days old if you have a standard plan, and 30 days for premium and enterprise plans.

In this example, the originalTweetId variable is set to '1234567890', which is the tweet ID of the original tweet for which you want to retrieve the replies.

const action:Action = async ({ row }) => {
  const res = await fetch('https://api.twitter.com/2/tweets', {
      method: 'POST',
      headers: {
      'Authorization': `Oauth ${generateOauth()}`,
      'Content-Type': 'application/json'
      },
      body: JSON.stringify({
          text: 'this is a reply',
          reply: {
            in_reply_to_tweet_id: row.tweet_id
          }
      })
  }).then(response => response.json())
}

A tweet reply sent with an API call - 4.jpg

Additionally, you can retrieve tweets as you would in the search bar using the following code:

const tweets = await fetch(`https://api.twitter.com/2/tweets/search/recent?query=${your_query_params}`, {
      headers: {
      'Authorization': `Bearer ${rowy.secrets.TWITTER_BEARER_TOKEN}`,
      'Content-Type': 'application/json'
      }
  }).then(response => response.json())

Note that you can also export tweets and replies linked to your account in a JSON file from Twitter and import them in a Rowy table using the Import JSON feature.

3. Direct Messaging People

Automatically respond to users in Direct Messages via Rowy Webhooks: This feature allows you to set up webhooks that automatically respond to users who send you direct messages. This can help you handle customer service inquiries more efficiently.

Twitter represents an incredible opportunity for businesses to engage with potential customers: with the Direct Message feature, you can use Rowy as a CRM to automatically send custom private messages to leads with a single API call:

curl -X POST "https://api.twitter.com/2/dm_conversations/with/:participant_id/messages" -d '{"text": "This is a one-to-one Direct Message with an attachment","attachments": [{"media_id": "1455952740635586573"}]}' -H "Authorization: Bearer $ACCESS_TOKEN"

const action:Action = async ({ row }) => {
  const res = await fetch(`https://api.twitter.com/2/dm_conversations/with/${user_id}/messages`, {
      method: 'POST',
      headers: {
      'Authorization': `Oauth ${generateOauth()}`,
      'Content-Type': 'application/json'
      },
      body: JSON.stringify({
          text: 'DM sent via API',
          reply: {
            in_reply_to_tweet_id: row.tweet_id
          }
      })
  }).then(response => response.json())
}

Which results in the following DM I sent to myself:

A DM sent with an API call - 5.jpg

Note that you can find the user_id programmatically using the GET /2/users/by/username/:username endpoint.

4. Receive Notifications

If you want to automate your Twitter account, you'll need to find a way to be notified when something happens. For example, you can receive a notification when someone mentions your account, or when a new tweet is published by someone you follow.

Unfortunately, Twitter doesn't provide a webhook to receive notifications unless you subscribe to the Premium or Enterprise plan. If you have a Premium developer account, you can use the Account Activity API to receive notifications via webhooks relatively easily: you'll need to set up a webhook URL using Rowy (keep reading to learn how), subscribe to events, and then you'll directly receive notifications when something happens.

You'll need to pay though, and the prices start at $149 per month.

Another possibility is to implement a polling mechanism to check for new tweets: you can use a Rowy webhook to run a Twitter search via API at a specified time interval―every hour for example―and compare the results to your tweet database to see if any new one appeared. A webhook that monitors new replies, for example:

const basicParser: Parser = async({req, db, ref, logging}) => {
  const tweets = getDocs(db.collection('twitter'))
  const size = tweets.length 

  for(let i = 0 ; i < size ; i++) {
    const tweet = tweets[i]
    const replies = tweet.replies.map(r => r.id)

    const new_replies = await fetch(`https://api.twitter.com/2/tweets/search/recent?query=conversation_id:${tweet.tweet_id}&tweet.fields=in_reply_to_user_id,author_id,created_at,conversation_id`, {
        headers: {
        'Authorization': `Bearer ${rowy.secrets.TWITTER_BEARER_TOKEN}`,
        'Content-Type': 'application/json'
        }
    }).then(response => response.json())

    new_replies.map(r => {
      if(!replies.includes(r.id)){
        tweet.update(...tweet, replies: [...tweet.replies, r])
      }
    })
  }
}

You can just click on the webhooks icon in your Rowy table, add a new webhook, and paste the code above in the webhook settings. You can then use the webhook URL to set up a cron job to run the webhook every hour:

A Rowy webhook - 3.jpg

Once your webhook detects a new event, you can send notifications to your favorite messaging app, to keep track of what is being said about you and your brand online. Check out our article on building a Slack bot to send notifications to Slack, for example.

You can use the same principles to monitor Twitter trends, stay on top of the latest news in your industry, or track mentions.

5. Drafting Tweets, Replies & DMs With OpenAI

What if you didn't even have to write your own tweets, DMs or replies? You could just let OpenAI do it for you, train it to match your brand tone, and let it propose new content ideas.

For example, we could create a new Action column to generate draft tweets on a given topic stored in a topicIdea column, which would be much easier than starting from scratch:

fetch("https://api.openai.com/v1/completions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
    "Authorization": `Bearer $${rowy.secrets.OPENAI_API_KEY}`
  },
  body: JSON.stringify({
    "model": "text-davinci-003",
    "prompt": `write a tweet about \"${row.topicIdea}\":`,
    "temperature": 0.7,
    "max_tokens": 256,
    "top_p": 1,
    "frequency_penalty": 0,
    "presence_penalty": 0
  })
})

Or we could generate draft replies to a given tweet:

fetch("https://api.openai.com/v1/completions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
    "Authorization": `Bearer $${rowy.secrets.OPENAI_API_KEY}`
  },
  body: JSON.stringify({
    "model": "text-davinci-003",
    "prompt": `write a reply to the following conversation:\nQ:${row.tweet}\nA:${row.reply}\nQ:`,
    "temperature": 0.7,
    "max_tokens": 256,
    "top_p": 1,
    "frequency_penalty": 0,
    "presence_penalty": 0
  })
})

Even better, we could tell GPT-3 to look at the profile of a Twitter user and send a matching DM:

fetch("https://api.openai.com/v1/completions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
    "Authorization": `Bearer $${rowy.secrets.OPENAI_API_KEY}`
  },
  body: JSON.stringify({
    "model": "text-davinci-003",
    "prompt": `Write a DM to the user @${row.receiver.twitter_username} with the profile description "${row.receiver.twitter_description}" to ask him to if they are interested in web development services. The message has to be polite, professional, but also personal and highly relevant to them.`,
    "temperature": 0.7,
    "max_tokens": 256,
    "top_p": 1,
    "frequency_penalty": 0,
    "presence_penalty": 0
  })
})

If I try it on my own Twitter profile, I get this:

A DM generated via OpenAI - 7.jpg

Impressive ugh?

6. Cross-Post Tweets to Other Platforms

Even though Twitter is an incredible platform, it can't hurt to share your tweets on other platforms. For example, you could cross-post a tweet to Medium―and even augment it using GPT-3 while you're at it―using a single Action column:

const action: Action = async ({ row, ref, db, storage, auth, actionParams, user }) => {

  const baseURL = "https://api.medium.com/v1/publications/d55b14096f33/posts"
  const blogContent = row.body? (row.body.trim().length>0 ? row.body:row.convertedRichtext):row.convertedRichtext;


  const body = JSON.stringify({
    title: row.title,
    contentFormat: 'markdown',
    content: blogContent,
    canonicalUrl: row.link,
    tags: ['firebase', 'nocode', 'lowcode'],
    publishStatus: 'public',
  })

  try {

    await fetch(baseURL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: "Bearer " + "29f7ef4f02bc5c21f3c51bb54e8d04e2a240424447f6dba406ebc86f2f30dc452",
        "accept-version": "1.0.0",
        'User-Agent': '*',
      },
      body
    })
      .then(async r => {
        const data = await r.json()
        console.log("Item updated 🌎🌎🌎🌎🌎🌎🌎")
        console.log(data)
      })


    return {
      success: true,
      message: `Successfully published to medium: ${row.title}`
    }
  } catch (e) {
    console.log(e)
    return {
      success: false,
      message: `Error in publishing:` + e
    }
  }

}

This is an example using tweets, but you can also use it for any CMS. At Rowy, we use this feature to cross-post our blog posts to Hashnode, Dev, and Medium, for example:

Rowy actions to publish to Medium - 9.jpg

And it works as expected:

Example of Medium post published using a Rowy action - 10.jpg

Join The Rowy Community

Rowy can automate a variety of tasks on Twitter, including sending tweets, responding to users, and monitoring trends. By obtaining a Twitter API key and leveraging the features of Rowy, you can streamline your social media strategy and achieve better results.

Make sure to tag along in our Discord Community for more tips and tricks on how to use Rowy!

Olivia Rhye
11 Jan 2022
5 min read
Get started with Rowy in minutes

Continue reading

Browse all