Over the past few years I’ve been running a gaming YouTube channel, Chambers Plays Games, and like most small creators I’ve found that making the content is only half the battle. The other half is the relentless work of promoting it… writing tweets, scheduling posts, engaging with other channels, and keeping track of which accounts in your following list are actually worth keeping around. I was doing all of this manually, which was both time-consuming and inconsistent. So, as I’ve done more than once before with problems that annoy me enough, I decided to write a tool to solve it.
That tool is PromoForge.
This isn’t my first attempt at Twitter automation. Back in early 2018, as part of a #30DayDev challenge, I built and open-sourced the Microcosm retweet bot, a Python and Tweepy script that retweeted content from a configurable set of hashtags on a schedule. It did one thing and did it reasonably well, and I wrote about it on this blog at the time. The repository is now archived. PromoForge is in some ways the natural successor to that project, built on the same instinct to automate the repetitive parts of being online, just considerably more ambitious about what “automated” actually means.
What started as a fairly simple idea (fetching my YouTube videos and generating tweets for them) has grown into something considerably more ambitious over the last ten days. This post covers what’s been built, some of the more interesting challenges I ran into along the way, and where I plan to take it next.
What Is PromoForge?
At its core, PromoForge is a promotion and audience-growth platform built specifically for gaming content creators. It has two entry points: a command-line tool for headless operation, and a full web UI that you run locally and access through your browser. The web interface is where most of the action happens and it covers three broad areas of work: content scheduling, audience growth, and channel maintenance.
The scheduling side of things works by connecting to the YouTube Data API, fetching your public videos, and then generating algorithm-optimised tweets for each one. It detects which game is being played from the video title using a combination of exact matching and fuzzy search, selects appropriate hashtags from a curated set, and composes a tweet from a template library. You can export everything as a CSV or push directly to Buffer or X’s own scheduling API. The whole flow from “fetch my videos” to “tweets are scheduled” can be done in a couple of clicks.

Growing an Audience on Two Platforms at Once
The feature set I’m most pleased with is the audience growth tooling, because it’s the thing I spent the most time doing manually before building this. PromoForge handles both X and YouTube growth independently but through a consistent plan-then-execute workflow. It discovers accounts or channels that match your niche, presents them for review, and only takes action when you give the go-ahead.

On the X side, you can discover accounts by bio keyword or by pulling from a competitor’s following list. Every account gets quality-scored on a 0–100 scale using signals like follower/following ratio, last activity date, bio content, and spam indicators. Anything below your configured threshold gets pre-deselected in the plan, so you’re never blindly following bots. There’s a daily cap on follows and replies to keep things within safe limits, and the tool randomises action delays between executions to avoid looking like a script.

The YouTube side works similarly but through the YouTube Data API. PromoForge searches for channels matching your keywords, scores each one using metrics like subscriber count, upload frequency, engagement ratio, and niche relevance, then plans subscribe and comment actions. Comments are generated contextually per video, not just copy-pasted from a generic template, which is something I felt was important to get right.
Owning Your Own Channel Engagement
One feature that I didn’t initially plan but ended up building fairly early on is the Own Channel engagement tab. The idea is simple: liking and commenting on your own channel’s videos provides engagement signals that the YouTube algorithm responds to. PromoForge connects via Google OAuth, fetches videos that haven’t been processed yet, and posts game-aware comments and likes automatically. It keeps a log of every video it’s touched so it never double-processes, and the comment templates are keyed by game name so the comments actually look appropriate rather than generic.

Knowing Who You’re Actually Following
The Follower Audit is probably the feature with the most immediate practical value. If you’ve been active on X for any length of time, your following list is almost certainly full of inactive accounts, bots, and people who followed you once during a follow-back campaign and haven’t posted since 2019. The audit fetches every account you follow, runs the same quality scoring algorithm used by the growth tools, and classifies them into five tiers: Unfollow, Review, Monitor, Keep, and High Value.

Once the audit is complete you can bulk unfollow entire tiers, which is considerably faster than doing it manually through X’s own interface. There’s a protected accounts list you can configure to make sure certain accounts can never be unfollowed regardless of their score, which is useful for friends and collaborators whose accounts might look suspicious to an automated scoring system but clearly aren’t.
The Activity Feed and Settings

Because PromoForge operates across multiple platforms and features simultaneously, it has an activity feed that aggregates events from everything into one place. It’s useful for getting a quick read on what’s happened recently without digging into individual feature logs. The settings panel is extensive. It covers everything from YouTube API configuration and tweet templates through to the scoring weights used by the audit and growth algorithms, all of which are configurable through the UI rather than requiring you to touch code.
Ten Days, Eleven Commits, and ~17,000 Lines of Code
The first commit landed on 21st May 2026. The most recent was on 31st May 2026. That’s ten days of development, eleven commits, and what turned out to be a considerably larger project than I initially anticipated. Here’s what the codebase looks like at this point:
- 37 Python source files across app logic, YouTube, Twitter, publishing, and route layers, totalling 6,450 lines
- 5,779 lines of JavaScript in a single app.js (the entire frontend is a single-page app)
- 1,699 lines of Jinja2 HTML template for the web UI
- 781 lines of CSS
- 19 test files with 199 test functions covering 2,503 lines of unit and integration tests
- 71 API endpoints across 10 Flask route blueprints
- ~17,212 lines total across the entire codebase
The commit history tells the story fairly clearly. The first couple of days were the initial foundation: YouTube API integration, tweet generation, and CSV export. By day three the cross-platform growth tooling was starting to take shape. Then there was a gap before a very productive sprint on the 29th of May where five commits landed covering UI improvements, automated YouTube and Twitter growth, and the project roadmap. The final two commits added rate limiting, a code review improvement plan, comprehensive test coverage, and API resiliency improvements.
The pace was fast enough that the architecture had to be reasonably disciplined from the start to avoid becoming a mess. I settled on a Flask blueprint structure where each feature area lives in its own module, which made it easy to add new capabilities without the different parts of the codebase getting tangled together. The YouTube and Twitter client code, the publishing logic, and the route handlers all live in separate packages.
Challenges Worth Mentioning
Not everything went smoothly, and a few problems were interesting enough to be worth writing up.
The trickiest single thing was the Twitter/X integration. X’s official API has become increasingly restrictive and expensive, so PromoForge uses twikit, a library that operates through the same browser-session GraphQL API that the X web client uses. This works well in practice but twikit’s internals are fragile in a couple of places, and I ended up patching its User.__init__ method and transaction-ID generation at import time to handle cases where the API returns unexpected response shapes. It’s not the kind of thing you’d usually want to do but it was the right call here, since the alternative was either maintaining a fork of twikit or going without the features entirely.
The hashtag selection logic was another thing that required more thought than expected. The X algorithm actively penalises tweets with too many hashtags, so there’s a hard assertion in the code that caps tweet hashtags at two. The selection is randomised per tweet across four modes: game tag plus a niche tag, game tag only, niche tag only, or a fallback to a generic gaming tag when no game is detected. Getting this balance right, enough context without looking spammy, took a few iterations.
YouTube quota management was a persistent headache throughout development. The YouTube Data API v3 has a daily unit quota (10,000 units, resetting at PST midnight) and different operations cost different amounts. Fetching videos, searching for channels, and fetching channel details all have different costs, and a careless combination of features could burn through the daily quota faster than expected. PromoForge now tracks quota usage broken down by feature with a live display in the UI, and the growth and engagement flows are designed to be conservative about how many API calls they make in a single run.
The Buffer API was also less straightforward than their documentation suggests. Buffer uses custom GraphQL scalar types (ChannelId!, OrganizationId!, DateTime!) that have to be inlined directly in the query rather than passed as variables, which isn’t immediately obvious and took some experimentation to get right. The API token situation is also worth being aware of: it’s a personal key from their settings page with a 30-day expiry, not an OAuth token, and using the old OAuth format just silently fails.
What’s Coming Next
The project roadmap currently breaks down into a few areas. On the content side, I want to add support for threads (multi-tweet sequences rather than single posts) and explore AI-assisted caption generation for YouTube descriptions and community posts, not just tweets. The AI enhancement feature already exists for individual tweets using the Anthropic API, so the foundation is there.
For audience growth, the plan is to add analytics tracking so you can see which growth actions actually convert into followers and subscribers over time, rather than just tracking raw counts. I’d also like to add competitor analysis on the YouTube side, specifically being able to see who’s subscribing to similar channels and target those viewers directly.
Longer term, I’ve been thinking about whether PromoForge makes sense as a multi-channel tool, supporting Bluesky and TikTok alongside X and YouTube. The architecture is already reasonably well-separated between platforms, so it wouldn’t require a fundamental redesign, just additional client implementations.
There’s also the question of whether this could be useful to other creators beyond just my own channel. Right now it’s a self-hosted tool that requires a local Python environment to run. Making it accessible to people who aren’t comfortable with that would be a significant undertaking, but it’s something I’m keeping in mind.
Final Thoughts
What I find most interesting about this project, looking back at ten days of work, is how much the scope expanded once the core was in place. The original idea was genuinely just “make tweet scheduling less tedious.” But once you have a YouTube API integration and a Twitter client sitting there, it becomes obvious that there are a dozen adjacent problems you could solve with the same building blocks. The audience growth tools, the audit feature, the own-channel engagement; none of those were in the original spec, but they all made sense to add once the infrastructure existed to support them.
Whether all of those features survive long-term in their current form, or get refined or replaced as I actually use the tool in practice, remains to be seen. But that’s the nature of building something for yourself. You find out very quickly what actually matters and what seemed like a good idea at the time. I’ll post an update once PromoForge has had a few weeks of real-world use.
The project isn’t open source at the moment, whether it ever becomes available or if I try to release it as a SaaS remains to be seen. You can follow progress on @EpicChambers.
Also published on Medium.
