Tutorial: Creating a Twitter (X) Bot using Python
Published at Oct 6, 2024
During my last semester at university, I found myself overwhelmed by the workload and the feeling that time was standing still. To cope, I decided to create a simple X bot that would remind me of the semester’s progress by tweeting the percentage of time that had passed. I’ll walk you through building your own X bot using Python and the X API, complete with scheduling and image generation.
This tutorial is up-to-date as of
October 2024February 2025 using the new X API. If you are reading this in the future, please check the official documentation for any changes.
Here is an example tweet from the bot:
🔴 ODTÜ'de 2024-2025 güz dönemi ilerlemesi: %6.61
— odtü dönem ilerlemesi (@OdtuSemesterBot) October 6, 2024
🗓️ Kalan gün sayısı: 88 pic.twitter.com/A7gKHiqmWi
I know most of my audience doesn’t speak Turkish, but the tweet simply says that the semester has progressed by 6.61% and there are 88 days left until the end of the semester.
You can reach the source code of the project from my github repository.
Structure
Features
- Post a tweet autonomously.
- Schedule the bot to tweet at a specific time, you can also set the interval.
- Retry posting the tweet if it fails.
- Create a beautiful progress graph that shows the progress of the semester.
- Completely free to deploy and use.
Getting Started
First, you need to create an X account for your bot. Then, you need to sign-in to the X Developer Portal and create a new project. After creating a project, you need to create an app and get the API keys.
Now, copy all of these keys and paste them into a .env
file in the root directory of your project. Here is an example of the .env
file:
API_KEY=YOUR_API_KEY
API_KEY_SECRET=YOUR_API_KEY_SECRET
BEARER_TOKEN=YOUR_BEARER
ACCESS_TOKEN=YOUR_ACCESS_TOKEN
ACCESS_TOKEN_SECRET=YOUR_ACCESS_TOKEN_SECRET
CLIENT_ID=YOUR_CLIENT_ID
CLIENT_SECRET=YOUR_CLIENT_SECRET
Hint: Notice that we ignore the
.env
file in the.gitignore
file so that we don’t share our keys with the public.
Requirements
First, you can find the required libraries in the requirements.txt
file. You can install them by running:
pip install -r requirements.txt
I will explain why we need each required library:
tweepy
: Tweepy is an easy-to-use Python library for accessing the X API.python-dotenv
: Reads the key-value pair from.env
file and adds them to the environment variable.matplotlib
andnumpy
: We use these libraries to create the graph that shows the progress of the semester.
Writing the Bot
- We set up basic logging to see the logs of the bot:
# Setup basic logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
Then, I have a very simple code that calculates how many seconds have passed since the beginning of the semester and how many seconds are left until the end of the semester. Then I calculate the percentage of the semester that has passed. Pretty simple, right?
After calculating the percentage, I create a graph that shows the progress of the semester using the
matplotlib
library. I’m not going to show the code snippet here, but you can find it in the source code.I have two functions that connect to the X API and post the progress image on X:
def connect_twitter() -> tuple:
"""
Connect to the Twitter API using Tweepy and environment variables.
Returns:
tuple: A tuple containing the Twitter client and API instances.
"""
load_dotenv()
tweepy_auth = tweepy.OAuth1UserHandler(
os.getenv("API_KEY"),
os.getenv("API_KEY_SECRET"),
os.getenv("ACCESS_TOKEN"),
os.getenv("ACCESS_TOKEN_SECRET"),
)
api = tweepy.API(tweepy_auth)
client = tweepy.Client(
os.getenv("BEARER_TOKEN"),
os.getenv("API_KEY"),
os.getenv("API_KEY_SECRET"),
os.getenv("ACCESS_TOKEN"),
os.getenv("ACCESS_TOKEN_SECRET"),
)
logging.info("Connected to Twitter API")
return client, api
def post_photo():
"""
Generate and post a progress image on Twitter with the remaining days and progress.
"""
client, api = connect_twitter()
remaining_days = (END_DATE - datetime.now()).days
percentage = calculate_percentage(START_DATE, END_DATE)
img_path = create_progress_image(percentage)
text = f"🔴 ODTÜ'de 2024-2025 bahar dönemi ilerlemesi: %{percentage}"
media = api.media_upload(filename=img_path)
client.create_tweet(text=text, media_ids=[media.media_id])
logging.info("Successfully posted progress image on Twitter")
- Finally, I have a main function that runs the bot.
if __name__ == "__main__":
post_photo()
Deployment
I deployed the function using GitHub Actions. The bot runs daily and posts the progress image on X. You will first need to secrets we use to the Github:
- Go to your Github Repository.
- Go to settings.
- Go to secrets and variables, select actions.
- Click “New Repository Secret” for each of the environment variables.
Then add the “daily_twitter_post” yaml file to ./.github/workflows Here is the daily_twitter_post.yml file:
name: Daily Twitter Post
on:
schedule:
- cron: '0 15 * * *' # Runs daily at 18:00 in Turkiye time
workflow_dispatch: # Allows manual triggering
jobs:
post_tweet:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: pip install -r requirements.txt # Ensure you have a requirements.txt file
- name: Run script
env:
API_KEY: ${{ secrets.API_KEY }}
API_KEY_SECRET: ${{ secrets.API_KEY_SECRET }}
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
ACCESS_TOKEN_SECRET: ${{ secrets.ACCESS_TOKEN_SECRET }}
BEARER_TOKEN: ${{ secrets.BEARER_TOKEN }}
run: python main.py
Conclusion
This project is just the beginning. You can extend the bot to post about other events or even integrate it with other APIs. I encourage you to explore different ways to make this bot more interactive. Have fun experimenting, and feel free to reach out with any questions or feedback!