Разработка 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-бота для вашего крипто-проекта. Свяжитесь с нами — мы оценим задачу и предложим оптимальное решение. Получите консультацию прямо сейчас.







