A powerful Telegram bot for managing and scheduling social media posts with AI support. Self-hosted, open-source, and easy to deploy with Docker.
- โ๏ธ Manual Post Creation - Write your posts directly
- ๐ค AI-Powered Content - Generate posts with OpenAI GPT
- ๐ Smart Scheduling - Schedule posts for optimal timing
- ๐ Timezone Support - Configure your local timezone for scheduling
- ๐ Notifications - Get notified when scheduled posts are published
- ๐งต Auto Thread Creation - Automatically splits long posts into threads (respects 280 char limit)
- ๐ฏ Topic Presets - Save favorite topics for quick AI post generation
- ๐งฉ Templates - Reusable content blocks for quick posts
- ๐ Secure & Private - Self-hosted, only you have access
- ๐ณ Docker Ready - Easy deployment with docker-compose
- ๐ Statistics - Track your posting performance
- ๐ Drafts - Save posts and finish later
- ๐ Weekly Planning - Plan up to 7 days with multiple slots per day
- ๐๏ธ Weekly Calendar View - Review scheduled posts by week
- ๐ผ๏ธ Image Posts - Publish posts with a single attached image
- ๐พ Persistent Storage - SQLite database for reliability
- ๐จ Beautiful UI - Interactive menus and inline buttons
- ๐ Localization Ready - i18n support with English fallback
- Docker and Docker Compose installed
- A Telegram Bot Token from @BotFather
- X Developer Account with API credentials
- (Optional) OpenAI API key for AI features
- Open a chat with @userinfobot
- It replies with your User ID
- Copy the number into
TELEGRAM_USER_ID
Example reply:
Your user ID: 123456789
- Go to developer.twitter.com
- Create a new app or use existing one
- Generate API keys and access tokens
- You'll need:
- API Key
- API Secret
- Access Token
- Access Token Secret
git clone https://github.com/artcc/postflow-telegram-bot.git
cd postflow-telegram-botCreate a .env file from the example:
cp .env.example .envEdit the .env file with your credentials:
# Telegram Bot Configuration
TELEGRAM_BOT_TOKEN=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
TELEGRAM_USER_ID=123456789
# Timezone (required) - Your local timezone for scheduling
# Examples: Europe/Madrid, America/New_York, Asia/Tokyo
TZ=Europe/Madrid
# Twitter/X API Credentials
TWITTER_API_KEY=your_api_key_here
TWITTER_API_SECRET=your_api_secret_here
TWITTER_ACCESS_TOKEN=your_access_token_here
TWITTER_ACCESS_TOKEN_SECRET=your_access_token_secret_here
# OpenAI API (optional - leave empty to disable AI features)
OPENAI_API_KEY=sk-your-openai-api-key-here
# Database Configuration (default: /data/postflow.db)
DATABASE_PATH=/data/postflow.dbImportant: All variables are required except
OPENAI_API_KEY(optional). The bot won't start without the required credentials.
Timezone: Use standard timezone names from IANA Time Zone Database (e.g.,
Europe/Madrid,America/New_York,Asia/Tokyo).
The docker-compose.yml configuration:
services:
postflow-bot:
image: ghcr.io/artcc/postflow-telegram-bot:latest
container_name: postflow-bot
environment:
# Telegram Bot Configuration
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_USER_ID=${TELEGRAM_USER_ID}
# Timezone (required) - e.g., Europe/Madrid, America/New_York
- TZ=${TZ}
# Twitter/X API Credentials
- TWITTER_API_KEY=${TWITTER_API_KEY}
- TWITTER_API_SECRET=${TWITTER_API_SECRET}
- TWITTER_ACCESS_TOKEN=${TWITTER_ACCESS_TOKEN}
- TWITTER_ACCESS_TOKEN_SECRET=${TWITTER_ACCESS_TOKEN_SECRET}
# OpenAI API (optional)
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
# Database Configuration
- DATABASE_PATH=${DATABASE_PATH:-/data/postflow.db}
volumes:
- ./data:/data # Database persistence
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"Start the bot:
# Start the bot in detached mode
docker-compose up -dThe docker-compose.yml automatically:
- Pulls the latest image from GitHub Container Registry
- Loads environment variables from
.envfile - Creates a persistent volume for the database (
./data) - Configures automatic restarts
- Sets up log rotation
Note: The image is pulled from
ghcr.io/artcc/postflow-telegram-bot:latest- no build required!
# Check container status
docker ps | grep postflow-bot
# View real-time logs
docker logs -f postflow-botExpected output:
2026-02-02 10:30:15 - bot.config - INFO - Bot configured for user ID: 123456789
2026-02-02 10:30:15 - bot.config - INFO - Twitter API: Enabled
2026-02-02 10:30:15 - bot.config - INFO - OpenAI API: Enabled
2026-02-02 10:30:15 - bot.main - INFO - Starting PostFlow Telegram Bot...
2026-02-02 10:30:16 - bot.main - INFO - Bot is running... Press Ctrl+C to stop.
Troubleshooting startup:
- If you see errors about missing variables, check your
.envfile - If container exits immediately, check logs:
docker logs postflow-bot - Verify all required credentials are set correctly
- Open Telegram and find your bot
- Send
/startto verify authorization - Use
/menuto access the main menu - Click "โ๏ธ New" to create your first post
- Click "โ๏ธ New" โ "โ๏ธ Write Manually"
- Type your content
- Preview and choose "๐ Publish Now" or "๐ Schedule"
- Click "โ๏ธ New" โ "๐ค AI"
- If you have topic presets, select one or choose "โ๏ธ Custom Prompt"
- For custom: Describe what you want: "Post about Python advantages"
- Review generated content
- Publish or schedule
- Click "โ๏ธ New" โ "๐งฉ Templates"
- Choose a template
- Review the prefilled content
- Edit if needed, then publish or schedule
Topic presets allow you to quickly generate AI posts on your favorite subjects.
- Click "๐ฏ Topics" in main menu or use
/topics - Click "โ Add Topic"
- Enter a topic name (3-30 characters)
- Examples: "Python Programming", "AI & ML", "Tech News"
- Topic is saved for quick access (max 10 topics)
- Click "โ๏ธ New" โ "๐ค AI"
- Select a topic preset button
- AI generates a professional post about that topic
- Review, edit if needed, then publish or schedule
- List Topics: View all your saved topics
- Delete Topic: Remove individual topics
- Delete All: Clear all topics (with confirmation)
Note: Topics require OpenAI to be configured. Each topic generates unique content every time and is limited to a single post (max 280 characters).
- Click "๐งฉ Templates" in main menu or use
/templates - Add a template (name + content)
- List templates to view details
- Edit content or delete when needed
- Use a template to create a post in one tap
- Click "โ๏ธ New" โ "๐ Plan Week"
- Select days (rolling 7-day window)
- Choose posts per day (max 3)
- Enter time slots for each day
- Create each post manually or with AI
- Review summary and confirm scheduling
- Click "โ๏ธ New" โ "๐ผ๏ธ Image"
- Send an image with an optional caption (max 280 chars)
- Preview and choose "๐ Publish Now" or "๐ Schedule"
Posts longer than 280 characters are automatically converted to threads:
- Intelligent splitting at sentence boundaries
- Automatic numbering (1/3, 2/3, 3/3)
- Preview before publishing
- All tweets published as connected thread
- Create your post (manual or AI)
- Choose "๐ Schedule"
- Select quick option or custom date:
- โฐ In 1 hour
- โฐ In 3 hours
- ๐ Tomorrow 9am
- ๐ Custom date (format:
2026-01-25 18:00)
- Post will be published automatically at scheduled time
- You'll receive a notification when the post is published
Note: All times are displayed in your configured timezone (TZ environment variable).
When a scheduled post is published (or fails), you'll receive a notification:
Success notification:
๐ SCHEDULED POST PUBLISHED
โ
Your scheduled post #123 has been published successfully!
๐ View on X
Failure notification:
โ SCHEDULED POST FAILED
โ ๏ธ Your scheduled post #123 could not be published.
๐ Error: [error details]
๐ก Check /menu to retry or reschedule.
- Click "๐ Scheduled" in main menu
- View all pending posts
- Click on any post to:
- ๐๏ธ View details
- โ๏ธ Edit schedule time
- ๐๏ธ Delete
- Open "๐ Scheduled" in the main menu
- Tap "๐๏ธ Calendar" to see the current week
- Navigate weeks with Previous/Next buttons
- Review scheduled posts grouped by day and time
- Click "๐ Drafts" in main menu
- Select a draft to preview
- Edit, publish, or schedule from the preview
/start- Welcome message and authorization check/help- Show help information/menu- Open interactive main menu/new- New post/plan- Plan week/topics- Manage topic presets/templates- Manage templates/drafts- List drafts/scheduled- List scheduled posts/stats- Show statistics/status- Check bot and API status/settings- Show settings/chatid- Show your Telegram User ID/author- About the author/cancel- Cancel current operation
The bot uses your Telegram language_code and falls back to English when a locale is not available.
The bot tracks:
- Total posts created
- Published posts count
- Scheduled posts pending
- Failed posts (with error details)
- Success rate percentage
Access statistics via the "๐ Statistics" button in the main menu or with /status command.
โโโโโโโโโโโโโโโโโโโ
โ Telegram User โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ Telegram Bot API โ
โโโโโโโโโโฌโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PostFlow Bot โ
โ - Handlers โ
โ - Services โ
โ - Database (SQLite) โ
โ - APScheduler โ
โโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ X API โ โ OpenAI API โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
postflow-telegram-bot/
โโโ bot/
โ โโโ __init__.py
โ โโโ config.py # Configuration & environment variables
โ โโโ main.py # Bot entry point
โ โโโ database/
โ โ โโโ __init__.py
โ โ โโโ models.py # SQLAlchemy models
โ โ โโโ database.py # Database management
โ โโโ handlers/
โ โ โโโ __init__.py
โ โ โโโ commands.py # Command handlers
โ โ โโโ callbacks.py # Button callback handlers
โ โ โโโ posts.py # Post management logic
โ โ โโโ conversations.py # Multi-step conversations
โ โโโ locales/
โ โ โโโ de.json # UI strings
โ โ โโโ en.json # UI strings
โ โ โโโ es.json # UI strings
โ โ โโโ fr.json # UI strings
โ โ โโโ it.json # UI strings
โ โโโ services/
โ โ โโโ __init__.py
โ โ โโโ twitter_service.py # X API integration
โ โ โโโ openai_service.py # OpenAI API integration
โ โ โโโ scheduler_service.py # APScheduler management
โ โ โโโ post_service.py # Post business logic
โ โ โโโ topic_service.py # Topic presets management
โ โ โโโ template_service.py # Templates management
โ โโโ utils/
โ โโโ __init__.py
โ โโโ auth.py # Authorization helpers
โ โโโ formatting.py # Text formatting utilities
โ โโโ i18n.py # Localization helpers
โ โโโ keyboards.py # Telegram keyboard builders
โโโ data/ # SQLite database (volume)
โโโ .env # Environment variables (not in git)
โโโ .env.example # Example configuration
โโโ .gitignore
โโโ docker-compose.yml
โโโ Dockerfile
โโโ requirements.txt
โโโ LICENSE
โโโ README.md
- Go to your Portainer instance
- Navigate to Stacks โ Add Stack
- Name it:
postflow-bot - Select Repository as build method
- Enter repository URL:
https://github.com/artcc/postflow-telegram-bot - Compose path:
docker-compose.yml - Add environment variables:
TELEGRAM_BOT_TOKEN=your_bot_token TELEGRAM_USER_ID=your_user_id TZ=Europe/Madrid TWITTER_API_KEY=your_api_key TWITTER_API_SECRET=your_api_secret TWITTER_ACCESS_TOKEN=your_access_token TWITTER_ACCESS_TOKEN_SECRET=your_access_token_secret OPENAI_API_KEY=your_openai_key DATABASE_PATH=/data/postflow.db - Click Deploy the stack
- Go to your Portainer instance
- Navigate to Stacks โ Add Stack
- Name it:
postflow-bot - Select Web editor
- Paste the
docker-compose.ymlcontent - Add the environment variables as shown above
- Click Deploy the stack
Tip: In Portainer, you can easily edit environment variables after deployment without recreating the stack.
# Pull the latest image
docker-compose pull
# Recreate and start the container
docker-compose up -d
# Verify the update
docker logs -f postflow-botNote: Your data is safe! The
./datavolume persists your database across updates.
- Go to Stacks โ Select
postflow-bot - Click Pull and redeploy button
- Wait for the update to complete
- Check Containers to verify it's running
# Check image version
docker images | grep postflow-telegram-bot
# Check when the image was pulled
docker inspect ghcr.io/artcc/postflow-telegram-bot:latest | grep CreatedEvery push to the main branch automatically:
- Builds a new Docker image
- Publishes it to GitHub Container Registry
- Tags it as
latest
The bot uses the pre-built image from ghcr.io/artcc/postflow-telegram-bot:latest, so you just need to pull the latest version.
Note: The GitHub Container Registry package is public, so anyone can pull the image without authentication.
- Never commit your
.envfile - it contains sensitive tokens - Your bot token gives full control of your bot - keep it secret
- Only the configured
TELEGRAM_USER_IDcan use the bot - All unauthorized access attempts are logged
- API keys are stored securely in environment variables
- Database is stored in a persistent Docker volume
Currently, the bot is designed for single-user, single-account use. Each instance manages one X account. To manage multiple accounts, deploy separate instances with different configurations.
Yes. All API keys are stored in environment variables (.env file) which is never committed to git. The keys are only used by your self-hosted instance.
Scheduled posts are stored in the SQLite database. When the bot restarts, APScheduler automatically reschedules all pending posts.
Yes. OpenAI is optional. If you don't configure OPENAI_API_KEY, the bot will work perfectly fine for manual post creation and scheduling. You just won't have AI generation features or topic presets.
Topic presets are saved keywords that trigger AI to generate posts on specific subjects. You can save up to 10 topics (e.g., "Python", "AI News", "Tech Tips"). When creating an AI post, select a topic button and the AI generates unique content about that subject each time. Topics require OpenAI to be configured.
You need at least Basic access tier from X's Developer Portal to post. The Free tier has very limited posting capabilities.
- Check if container is running:
docker ps - Check logs:
docker logs -f postflow-bot - Verify bot token is correct in
.env - Ensure bot is not rate-limited by Telegram
- Verify your User ID is correct in
.env - Use
/chatidcommand to see your actual ID - Restart container after changing
.env:docker-compose restart
Error: 401 Unauthorized
- Check your API credentials in
.env - Verify tokens haven't expired
- Regenerate tokens if needed at developer.twitter.com
Error: 429 Rate Limit
- X API has rate limits
- Wait for rate limit reset (shown in error message)
- Posts are saved and can be retried
Invalid API Key
- Verify
OPENAI_API_KEYin.env - Check key hasn't expired
- Ensure you have credits in your OpenAI account
Rate Limit Exceeded
- OpenAI has usage limits based on your plan
- Wait a few minutes before retrying
- Upgrade your OpenAI plan if needed
Database locked
- Stop the container:
docker-compose down - Start again:
docker-compose up -d
Lost data after restart
- Verify volume is mounted correctly in
docker-compose.yml - Check that
./datadirectory exists
sudo chown -R 1000:1000 ./data
sudo chmod -R 755 ./data- Manual post creation
- AI-powered content generation (OpenAI GPT)
- Twitter/X publishing
- Auto thread creation for long posts
- Post scheduling (quick & custom)
- Scheduled posts management
- Post editing after creation
- Statistics & monitoring
- Docker deployment
- SQLite persistent storage
- Timezone support (TZ configuration)
- Notifications for scheduled posts
- Draft system
- Weekly planning wizard (rolling 7-day window)
- Support for images in posts
- Topic presets for AI random post generation
- Additional locales (i18n)
- Publication calendar with weekly view
- Post templates
- Multi-platform support (Instagram, LinkedIn, Facebook, etc.)
Contributions are welcome. Please read CONTRIBUTING.md for setup, conventions, and i18n guidelines.
You can use the official bot avatar for your own instance:
To set this image as your bot's profile picture:
- Right-click the image above and save it
- Open @BotFather on Telegram
- Send
/setuserpic - Select your bot
- Upload the downloaded image
- python-telegram-bot - Excellent Telegram Bot API wrapper
- Tweepy - X API library
- OpenAI - AI content generation
- APScheduler - Advanced Python Scheduler
If you encounter any issues or have questions:
- Check the Troubleshooting section
- Search existing GitHub Issues
- Open a new issue with detailed information
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
100% built with GitHub Copilot (GPT-5.2-Codex)
Arturo Carretero Calvo โ 2026

