Розробка Twitter/X-бота для крипто-проєкту
Ми розробляємо Twitter/X-ботів для крипто-проєктів з перших років розвитку крипто-ринку. За цей час запустили понад 20 рішень для on-chain моніторингу, автоматичних анонсів та дайджестів метрик. Twitter/X залишається головною площадкою крипто-ком'юніті — альфа поширюється тут швидше ніж де-небудь ще. Боти вирішують конкретні завдання: сповіщення про великі транзакції, ліквідації, голосування в DAO, публікація метрик протоколу за розкладом. Telegram-боти простіші в реалізації, але Twitter — це публічна видимість і вплив на наратив.
Обмеження Twitter API v2
З недавніх змін Twitter/X змінив умови API. Важливо розуміти поточні обмеження. Розглянемо тарифні плани:
| Тариф | Запис твітів/міс | Читання | Підходить для |
|---|---|---|---|
| Free | 1 500 | 800 000 | Тільки тестування |
| Basic | 3 000 | 10 000 | Боти з помірною активністю |
| Pro | 300 000 | 1 000 000 | Високочастотні алерт-боти |
Для більшості крипто-проєктів достатньо Basic. Але якщо планується твітити кожну велику транзакцію на популярному протоколі, щомісячний обсяг може сягати сотень твітів на день. Розраховуйте ліміт заздалегідь.
Як ми будуємо архітектуру бота?
Компонент 1: on-chain монітор
Джерело даних — блокчейн-події через WebSocket. Ми не використовуємо сторонні агрегатори — вони додають затримку. Підписка на події в real-time:
const { ethers } = require('ethers') const provider = new ethers.WebSocketProvider(process.env.WSS_RPC_URL) const AAVE_POOL = '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2' const LIQUIDATION_TOPIC = ethers.id('LiquidationCall(address,address,address,uint256,uint256,address,bool)') provider.on({ address: AAVE_POOL, topics: [LIQUIDATION_TOPIC] }, async (log) => { const iface = new ethers.Interface(AAVE_POOL_ABI) const decoded = iface.parseLog(log) const collateralAsset = decoded.args.collateralAsset const debtAsset = decoded.args.debtAsset const liquidatedCollateralAmount = decoded.args.liquidatedCollateralAmount const usdValue = await getUSDValue(collateralAsset, liquidatedCollateralAmount) if (usdValue > MINIMUM_NOTABLE_USD) { await postLiquidationTweet({ collateralAsset, debtAsset, usdValue, txHash: log.transactionHash }) } }) Компонент 2: форматування та публікація
const { TwitterApi } = require('twitter-api-v2') const client = new TwitterApi({ appKey: process.env.TWITTER_APP_KEY, appSecret: process.env.TWITTER_APP_SECRET, accessToken: process.env.TWITTER_ACCESS_TOKEN, accessSecret: process.env.TWITTER_ACCESS_SECRET, }) const rwClient = client.readWrite async function postLiquidationTweet({ collateralAsset, debtAsset, usdValue, txHash }) { const collSymbol = await getTokenSymbol(collateralAsset) const debtSymbol = await getTokenSymbol(debtAsset) const text = [ `🔴 AAVE Liquidation`, ``, `Collateral: ${collSymbol}`, `Debt: ${debtSymbol}`, `Value: $${formatUSD(usdValue)}`, ``, `Tx: https://etherscan.io/tx/${txHash}`, ``, `#DeFi #AAVE #Liquidation` ].join('\n') try { await rwClient.v2.tweet(text) } catch (error) { if (error.code === 403) { // Duplicate tweet — додаємо timestamp або пропускаємо logger.warn('Duplicate tweet prevented', { txHash }) } else { throw error } } } Чому варто використовувати WebSocket замість REST?
REST-запити додають затримку через необхідність постійно опитувати RPC. WebSocket дає підписку на події — дані надходять миттєво. Це критично для ботів, які мають реагувати на ліквідації або великі транзакції за секунди. Плюс WebSocket знижує навантаження на RPC і зменшує витрати на інфраструктуру.
Як захистити бота від бану та rate limit?
Twitter/X активно детектує аномальну поведінку. Наші напрацювання:
- Дедуплікація: зберігаємо txHash опублікованих подій (Redis з TTL 24 год) — ніколи не твітимо одну подію двічі.
- Затримка між твітами: мінімум 30 секунд при серії подій.
- Черга з пріоритетами: якщо подій багато — публікуємо найбільші, дрібні агрегуємо в дайджест.
- Graceful reconnect: WebSocket-з'єднання рвуться, використовуємо exponential backoff.
// Черга з дебаунсом для batch подій class TweetQueue { constructor(client, maxPerHour = 20) { this.queue = [] this.maxPerHour = maxPerHour this.published = [] // Публікуємо кожні 3 хвилини (максимум 20 на годину) setInterval(() => this.flush(), 3 * 60 * 1000) } async add(event) { if (this.queue.some(e => e.txHash === event.txHash)) return this.queue.push({ ...event, addedAt: Date.now() }) this.queue.sort((a, b) => b.usdValue - a.usdValue) } async flush() { if (this.queue.length === 0) return const toPublish = this.queue.shift() await this.client.v2.tweet(formatTweet(toPublish)) const lastHour = this.published.filter(t => Date.now() - t < 3600000) if (lastHour.length >= this.maxPerHour) { logger.info('Rate limit self-imposed, queuing') return } this.published.push(Date.now()) } } Чи можна налаштувати регулярні дайджести?
Так, окрім event-driven публікацій ми налаштовуємо періодичні твіти з метриками протоколу. Наприклад, щоденна статистика о 12:00 UTC:
const cron = require('node-cron') cron.schedule('0 12 * * *', async () => { const stats = await fetchProtocolStats() await rwClient.v2.tweet( `📊 Daily Stats — ${new Date().toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}\n\n` + `TVL: $${formatBigNumber(stats.tvl)}\n` + `24h Volume: $${formatBigNumber(stats.volume24h)}\n` + `Active Users: ${stats.activeUsers.toLocaleString()}\n\n` + `#DeFi` ) }) Порівняння WebSocket vs REST для on-chain моніторингу
| Характеристика | WebSocket | REST |
|---|---|---|
| Затримка | < 1 с (push) | 12-15 с (poll) |
| Навантаження на RPC | Низька | Висока (часті запити) |
| Складність реалізації | Вимагає менеджменту з'єднань | Простіше |
| Підходить для | Real-time алерти | Історичні дані |
Деплой та моніторинг
Мінімальна інфраструктура — Docker-контейнер на VPS з постійним WebSocket-з'єднанням. Використовуємо PM2 або systemd для автоперезапуску. Логи пишемо через Winston у файл, плюс опціонально Telegram-алерти на помилки самого бота. Змінні середовища — тільки .env файл, в production — secrets manager. Ми гарантуємо стабільну роботу бота 24/7.
Що входить у роботу
- Налаштування Twitter Developer App та OAuth 2.0 аутентифікації
- On-chain монітор з WebSocket підпискою на потрібні події
- Форматування твітів з реальними даними з блокчейну
- Дедуплікація, rate limiting, черга з пріоритетами
- Scheduled публікації за розкладом (дайджести, метрики)
- Деплой на VPS з моніторингом процесу
Покрокова інструкція з розгортання бота
- Створіть Twitter Developer App та отримайте ключі API (OAuth 2.0).
- Виберіть RPC-провайдера з WebSocket підтримкою (наприклад, Infura або Alchemy).
- Налаштуйте середовище: помістіть ключі в
.envфайл, встановіть залежності (npm install ethers twitter-api-v2 winston). - Запустіть бота локально:
node bot.jsта перевірте, що твіти публікуються. - Розгорніть на VPS: використовуйте Docker-образ або скопіюйте проєкт, запустіть через
pm2 start bot.js --name cryptobot. - Налаштуйте моніторинг: додайте алерти на помилки через Telegram або Slack.
Приклад дедуплікації з Redis
const redis = require('redis') const client = redis.createClient() async function isDuplicated(txHash) { const exists = await client.exists(txHash) if (exists) return true await client.set(txHash, '1', 'EX', 86400) // TTL 24 год return false } Згідно з офіційною документацією Twitter API v2, ліміти на запис для Basic тарифу становлять 3000 твітів на місяць. Для більшості крипто-проєктів цього достатньо — за умови правильної фільтрації подій. Інвестиції в розробку бота починаються від кількох тисяч доларів, але економія від своєчасних сповіщень про ліквідації або великі транзакції може покрити витрати за тиждень.
Замовте розробку Twitter/X-бота для вашого крипто-проєкту. Зв'яжіться з нами — ми оцінимо завдання і запропонуємо оптимальне рішення. Отримайте консультацію прямо зараз.







