The Architecture of Local-First Message Scheduling
Cloud-based marketing platforms require you to upload your entire customer database, copy, and credentials to their servers. This introduces massive privacy risks, especially when dealing with direct outreach on Telegram.
AutoPROMO solves this by utilizing **SQLite**—a lightweight, serverless database engine that runs entirely inside your application process. Your session credentials and message queues are stored locally, encrypted, and run offline.
1. The Local Database Schema
To understand how message scheduling works under the hood, let's examine the SQLite table structure used to manage campaigns and queued messages:
CREATE TABLE scheduled_actions (
id TEXT PRIMARY KEY,
platform TEXT CHECK(platform IN ('twitter', 'telegram')),
target_recipient TEXT NOT NULL,
message_content TEXT NOT NULL,
scheduled_time INTEGER NOT NULL, -- Epoch timestamp
status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'processing', 'sent', 'failed')),
attempts INTEGER DEFAULT 0,
error_log TEXT,
created_at INTEGER DEFAULT (strftime('%s', 'now'))
);This table tracks what message to send, who gets it, when it should be sent, and its current transmission status.
2. Queueing Scheduled Messages
When you design a campaign in the UI, the desktop client inserts records into this SQLite database. For example, if you schedule a sequence of follow-ups to contacts who opted in, the system writes separate rows for each contact with a progressively staggered `scheduled_time`.
Because the database is local, these writes are atomic, concurrent-safe, and happen in milliseconds with zero network latency.
3. Pacing and Platform Safety
Telegram's anti-spam algorithms quickly flag accounts that send bulk messages in bursts. To operate safely, the local campaign runner implements a polling loop that behaves like a human:
- Query Scheduled Actions: The runner queries the local database:
SELECT * FROM scheduled_actions WHERE status = 'pending' AND scheduled_time <= ? - Staggered Execution: Instead of executing all matching rows at once, the engine picks the first action, executes it, updates the row to `sent`, and sleeps for a randomized period (e.g. 120 to 300 seconds).
- Failure Resilience: If a message fails to send due to a temporary network issue, the attempt count is incremented and rescheduled, keeping detailed error logs locally.
4. Maintaining Audit and Consent Logs
Running your campaigns via local SQLite also makes compliance reporting straightforward. Under privacy standards like GDPR, you must maintain records of your processing activities (Article 30).
Because all actions are logged locally in SQLite, you can export your campaign history directly from the app as a CSV at any time, proving that every message was sent to an authorized contact within agreed pacing guidelines.