Skip to content

AltaOfficial/ReachAI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 

Repository files navigation

πŸ”’ Note: The actual repository is private. This README showcases the project's architecture, features, and development journey.

πŸš€ ReachAI

AI-powered Twitter/X outreach automation platform that scales your DM campaigns across multiple accounts

image

Live Demo (Preview build. Payment is in test modeβ€”use Stripe test card numbers only.)

ReachAI Demo

πŸ“¦ Technologies

  • Frontend: Next.js 15.2.4, React 19, TypeScript, Tailwind CSS
  • UI Libraries: Radix UI, shadcn/ui, Framer Motion
  • Data Tables: TanStack Table
  • Backend: Node.js 22, Express.js, Socket.io
  • Database: MongoDB Atlas, Mongoose
  • Real-time: WebSockets, Server-Sent Events
  • Scheduling: node-cron for automated tasks
  • Authentication: Clerk
  • Payments: Stripe
  • Monitoring: Sentry
  • Integrations: Twitter/X API, SMSPVA, Svix webhooks
  • Deployment: Vercel (Frontend), Railway (Backend)

πŸ¦„ Features

image

Core Features:

  • Automated DM Campaigns: Send personalized direct messages at scale across multiple Twitter accounts
  • Multi-Account Management: Coordinate campaigns across numerous accounts from one dashboard
  • Real-time Conversation Tracking: Monitor all conversations and responses with live WebSocket updates
  • Campaign Analytics: Track performance metrics like open rates, response rates, and conversions
  • Profile Scraping & Interactions: Automated profile discovery and engagement
  • Subscription Management: Full SaaS model with Stripe integration for billing and payments

Planned Enhancements:

  • AI-Powered Messaging: GPT-based personalized messaging that learns from your communication style or follows custom scripts
  • Content Automation: Automated reposting capabilities
  • Twitter Blue Automation: Subscription process automation up to Stripe checkout
  • Follower Marketplace: Buy followers using platform credits
  • Custom Metrics: User-defined tracking metrics with export to spreadsheets
  • Multi-Platform Support: Expand to LinkedIn, Instagram, and WhatsApp

🎯 Why I Built This

In today's fast-paced digital landscape, social media outreach is essential for businesses, creators, and marketers. However, manual outreach on platforms like X/Twitter is inefficient, time-consuming, and difficult to scale.

The problem:

  • Manual DM outreach takes hours per day
  • Difficult to track conversations across multiple accounts
  • No way to measure campaign effectiveness
  • Response rates suffer from poor timing and personalization

The solution: Build ReachAI to automate and optimize outreach marketing, enabling users to focus on engagement and conversions rather than repetitive tasks. The goal is to cut down manual messaging time by over 90%.

πŸ‘©πŸ½β€πŸ³ The Process

Defining Core Features & Design

Since this was my first major web application, I started by designing the entire interface in Figma before writing any code. This helped me understand what I was building and included:

  • Campaign management dashboard
  • Real-time conversation tracking interface
  • Balance/billing page with Stripe integration
  • Home page and onboarding flow

The visual planning was crucial for someone with limited web dev experience at the time.

Choosing the Tech Stack

Frontend Stack

Technology Category Used in MVP? Reason
Next.js 15.2.4 Framework βœ… Yes Server-side rendering for better performance and SEO
React 19 UI Library βœ… Yes Component-based architecture for maintainable code
TypeScript Language βœ… Yes Type safety prevents bugs and improves developer experience
Tailwind CSS Styling βœ… Yes Rapid UI development with utility-first classes
Radix UI + shadcn/ui Component Library βœ… Yes Accessible, customizable component primitives
Framer Motion Animation βœ… Yes Smooth animations for better UX
TanStack Table Data Tables βœ… Yes Powerful data table for campaign management (steep learning curve!)
Socket.io Client Real-time βœ… Yes Real-time updates for conversations and metrics
Clerk Auth βœ… Yes Authentication and user management
Stripe Payments βœ… Yes Subscription billing and payments
Sentry Monitoring βœ… Yes Error tracking and performance monitoring

Backend Stack

Technology Category Used? Reason
Node.js 22 Runtime βœ… Yes JavaScript runtime for backend services
Express.js Framework βœ… Yes Lightweight web framework for APIs
TypeScript Language πŸ”„ In Progress Currently migrating from JavaScript for better type safety
NestJS Framework πŸ“‹ Planned Better structure as backend grows (inspired by Spring Boot experience)
MongoDB Atlas Database βœ… Yes Cloud database for campaigns, users, metrics (8 Mongoose models)
Mongoose ODM βœ… Yes Object modeling for MongoDB
Socket.io Real-time βœ… Yes WebSocket server for bidirectional real-time updates
node-cron Scheduling βœ… Yes Scheduled tasks for campaign automation

Technical Challenges I Faced

1. TanStack Table Learning Curve

image

The Problem: Coming from limited web dev experience, understanding TanStack Table was extremely difficult. The documentation wasn't beginner-friendly, and I couldn't figure out why the table wasn't rendering at all.

The Solution: After days of debugging, I finally discovered it was literally one missing parameter in a function. One word. That single missing argument was causing the entire table to fail. This experience taught me the importance of carefully reading function signatures and understanding exactly what each library expects.

// The issue was something like this:
// Wrong (missing 'data' parameter):
const table = useReactTable({
  columns,
  getCoreRowModel: getCoreRowModel(),
});

// Correct:
const table = useReactTable({
  columns,
  data: campaigns, // This one missing parameter broke everything!
  getCoreRowModel: getCoreRowModel(),
});

2. Next.js Server Actions Can't Handle Long-Running Tasks

The Problem: When I started the project, I didn't understand that Next.js Server Actions have strict time limits and aren't designed for long-running background processes. I initially tried to run the entire campaign automation (scraping thousands of followers, filtering, sending DMs) within Server Actions, which would timeout or fail unpredictably.

The Solution: Had to split the architecture into two separate servers:

  • Next.js (Frontend): Handles UI, auth, and simple database queries
  • Express Backend: Handles long-running campaign execution, Twitter API calls, and background task scheduling

The campaign execution now runs asynchronously on the Express server, using MongoDB change streams to monitor for status changes. This taught me the fundamental difference between serverless functions (short-lived, stateless) and traditional servers (long-running, stateful).

// What I tried (doesn't work for long tasks):
// app/actions/runCampaign.js
'use server'
export async function runCampaign(campaignId) {
  // This times out after 60 seconds in serverless
  for (let i = 0; i < 10000; i++) {
    await scrapFollowers();
    await sendDMs();
  }
}

// What actually works:
// Backend/index.js
app.post('/modifycampaign', async (req, res) => {
  res.send({success: true}); // Respond immediately
  
  // Run async in background
  campaignRunner({campaign, campaignId}).catch(console.error);
});

3. Twitter's Proprietary x-client-transaction-id Header

The Problem: Twitter's GraphQL API requires a custom x-client-transaction-id header that changes with every request. Without this header, API calls are rejected. The header generation algorithm was completely undocumented and obfuscated in Twitter's frontend JavaScript.

The Discovery Process:

  1. Noticed API calls failing with 403 errors despite valid auth tokens
  2. Inspected network traffic in browser DevTools and found the x-client-transaction-id header
  3. Realized the header value changed with every single request (not a static token)
  4. Found an existing solution online that had reverse-engineered the algorithm
  5. Needed to adapt it for my Node.js backend

The Solution: Used Claude to port an existing Python implementation to JavaScript. The algorithm involves SVG animation parsing, cubic interpolation, transformation matrices, SHA-256 hashing, and XOR encoding. Honestly, I don't fully understand the math behind it - the code is dense and confusing. But it works, and for an MVP, that's what mattered.

// The actual function - I understand the high-level flow but not the math
async function generateClientTransactionId({ path, method }) {
  // 1. Fetch Twitter's home page to get verification key
  const homePage = await handleXMigration(session);
  
  // 2. Get the obfuscated JavaScript file
  const ondemandFileUrl = getOndemandFileUrl(homePage);
  const ondemandFile = await fetch(ondemandFileUrl);
  
  // 3. Parse animation data (this part is a black box to me)
  const clientTransaction = new ClientTransaction(
    homePage,
    ondemandFile
  );
  
  // 4. Generate the transaction ID (magic happens here)
  const transactionId = await clientTransaction.generateTransactionId(
    method,
    path
  );
  
  return transactionId;
}

What I Actually Learned:

  • You don't need to understand everything to ship: Sometimes it's okay to use code you don't fully understand, especially for an MVP. The perfect can be the enemy of the good.
  • Leverage existing solutions: Someone smarter than me already solved this problem. Rather than spending weeks reverse-engineering it myself, I found their solution and adapted it.
  • AI as a translation tool: Using Claude to port Python to JavaScript was incredibly effective - it handled the syntax conversion while preserving the complex logic I didn't understand.
  • When to dive deep vs. when to move on: I could've spent a month understanding cubic bezier curves and transformation matrices, but that wouldn't have gotten users. Knowing when to treat something as a black box is a valuable skill.

This taught me an important lesson about pragmatism in engineering: shipping a working product is more valuable than deeply understanding every line of code, especially when you're working alone on an MVP, whilst also handling school.

4. Headless Login Reliability Issues

The Problem: When logging into Twitter accounts in headless mode (without a browser UI), sometimes login randomly fails. Even switching to headful mode doesn't help for that account, but a different account logs in fine. When sending DMs at scale, Twitter eventually kicks the account out (not a ban, just forced logout). When trying to log back in, the system struggles.

Current Status: This is still an ongoing challenge. I suspect it's related to Twitter's spam detection algorithms.

Workarounds I'm exploring:

  • Rotating accounts more frequently to avoid detection
  • Adding random delays between actions to mimic human behavior
  • Implementing behavior pattern randomization
  • Using residential proxies instead of datacenter IPs
  • Session persistence improvements

πŸ“š What I Learned

πŸ”§ Technical Skills

  • Pragmatic Problem Solving: When Twitter's API needed a proprietary x-client-transaction-id header, I found an existing Python implementation online and used Claude to port it to JavaScript. I don't fully understand the math (cubic interpolation, transformation matrices), but I learned it's okay to use code as a black box when shipping an MVP. Understanding when to dig deep vs. when to move on is valuable.

  • Real-time Systems Architecture: Implementing WebSockets for live campaign updates taught me about bidirectional communication, state synchronization across clients, and handling concurrent connections at scale.

  • Serverless vs. Traditional Backend: Learning the hard way that Next.js Server Actions can't handle long-running processes forced me to understand the difference between serverless functions (short-lived, stateless) and traditional servers (long-running, stateful). This led to splitting the architecture into Next.js for UI and Express for background processing.

  • API Reverse Engineering: Learned to work with undocumented APIs by inspecting network traffic in DevTools, finding existing solutions online, and adapting them to my stack.

  • Scale Considerations: Managing multiple accounts, rate limits, and concurrent operations taught me about queuing systems, job scheduling, and the importance of retry logic with exponential backoff.

  • Database Modeling: Designing 8 interconnected Mongoose models (Users, Campaigns, Conversations, Accounts, Tasks, Metrics, Proxies, Offersets) taught me about data relationships, indexing for performance, and avoiding N+1 queries.

  • TypeScript Migration Strategy: Learning to gradually migrate a JavaScript codebase to TypeScript showed me the value of types in catching bugs early and improving code maintainability.

🎯 Project Management

  • Solo Development Reality: Building everything alone without AI tools (started before modern AI coding assistants were mature) made the backend unstructured. Now that AI tools are available, restructuring will be easier, but dealing with messy JavaScript code is a challenge.

  • Technical Debt Costs: Starting with JavaScript and later wanting TypeScript/NestJS taught me the importance of choosing the right architecture early, even with a steeper learning curve.

  • MVP vs. Perfect: Learning to focus on core features that prove the concept (DM automation, campaign management) rather than building everything at once.

  • School-Life Balance: Juggling a major project with coursework taught me realistic time management and the importance of sustainable development pace.

πŸ’Ό Business Lessons

  • Platform Risk: Building on unofficial APIs means your platform can break at any time. Always have monitoring, fallback strategies, and be prepared to adapt quickly.

  • Real Users Matter: Solo testing only reveals so much. Planning to onboard test users to validate features and find real-world issues before scaling.

  • Proof of Concept First: Goal is to get paying clients using the MVP to prove the business model works before building advanced features.

🧠 Technical Highlights

image
  • Real-time WebSocket System: Built a scalable Socket.io server that handles multiple concurrent campaigns, broadcasting updates to connected clients with minimal latency

  • Automated Job Scheduling: Implemented node-cron based system for campaign execution, message queuing, and account rotation

  • Multi-Account Orchestration: Created a system that coordinates actions across multiple Twitter accounts while respecting rate limits and mimicking human behavior patterns

  • Campaign Analytics Pipeline: Built visualizations that process real-time metrics from MongoDB and display engagement trends, response rates, and conversion data

πŸ’­ Current State & Future Vision

Where It Is Now

This is currently an active MVP development project. The core automation works, but there's significant work remaining:

  • Backend needs restructuring (unorganized JavaScript β†’ TypeScript/NestJS)
  • Limited testing (personal account only, ~500 DMs sent)
  • No scalability testing with multiple accounts or high volume
  • No real users yet (planning to onboard test users soon)

The Vision

The goal is to launch an MVP, get initial paying clients, and prove the concept works. Once validated with real users making real money, I'll focus on:

  • Restructuring the backend for maintainability
  • AI-powered messaging capabilities
  • Multi-platform support (LinkedIn, Instagram, WhatsApp)
  • Advanced analytics and optimization features
  • Enterprise-grade scalability and reliability

This is a long-term project that I'm committed to seeing through, balancing it with school and other commitments.

πŸ› οΈ Development Tools

  • Cursor AI – AI-powered IDE (adopted later in development)
  • Figma – Complete UI/UX design and prototyping
  • MongoDB Compass – Database management and query optimization
  • Postman/Insomnia – API testing and debugging Twitter endpoints
  • Sentry – Production monitoring and error tracking
  • Chrome DevTools – Reverse engineering Twitter's network requests

Built with ❀️ by Jaedon Farr

Readme created with the help of claude Claude AI

Portfolio β€’ LinkedIn β€’ GitHub

About

Automate Twitter/X outreach at scale. Send personalized DMs, manage multiple accounts, track conversations in real-time, and measure campaign performance from one dashboard.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors