Создание Twitter‑бота на Raspberry Pi с Node.js
Зачем нужен Twitter‑бот
Если вы когда‑либо видели аккаунты в Twitter, которые регулярно публикуют фотографии, факты или карикатуры, велика вероятность, что это автоматизированные боты. Они помогают поддерживать регулярный поток контента и привлекать аудиторию. Кроме того, создание бота — отличный обучающий проект: вы освоите Node.js, работу с API, загрузку медиа и базовые приёмы DevOps.
Важно: используйте только свои изображения или материалы с подходящей лицензией (например, Creative Commons) и всегда указывайте источники.
Что вы получите к концу инструкции
- Рабочий Node.js‑скрипт, который публикует изображения в Twitter
- Локальную «базу данных» изображений (файл images.js)
- Настройки Twitter App и пример конфигурации config.js
- Рекомендации по безопасному хранению ключей, автоматическому запуску, логированию и обработке ошибок
Требования и подготовка
- Raspberry Pi 2 или новее с Raspbian (Raspberry Pi OS)
- Доступ к терминалу или SSH
- Аккаунт разработчика Twitter (developer.twitter.com) и созданное приложение
- Node.js (рекомендую LTS — Node 18+ или новее)
- Набор изображений с подходящими лицензиями
Краткое определение: LTS — Long Term Support, стабильная версия Node.js с длительной поддержкой.
Сбор изображений и метаданных
- Соберите изображения в локальную папку проекта (обычно folder images/).
- Для каждого изображения храните имя файла и строку атрибуции (URL или текст). Это можно сделать простым массивом в файле images.js.
- Советы по именованию файлов: используйте латиницу, цифры, дефисы или подчёркивания, избегайте пробелов и специальных символов.
- Оптимизируйте размеры: Twitter автоматически сжимает изображения, но заранее уменьшённые и оптимизированные файлы ускоряют загрузку и экономят дисковую систему Pi.
Подсказка: инструменты для пакетной оптимизации — jpegoptim, pngquant или библиотека sharp в Node.js.
Установка Node.js на Raspbian
Приведённые в исходной инструкции команды использовали setup_8.x. Node 8 устарел: лучше установить актуальную LTS (например, 18.x) или воспользоваться nvm. Ниже — несколько рабочих вариантов.
Вариант A — NodeSource (быстро)
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v
npm -vВариант B — nvm (гибко, несколько версий рядом)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
# Перезапустите shell или выполните команды, которые вывел установщик
nvm install --lts
node -v
npm -vОбновление системы перед установкой:
sudo apt-get update
sudo apt-get dist-upgrade
sudo rebootПояснение: dist‑upgrade обновляет пакеты с учётом зависимостей, reboot применяет изменения.
Создаём структуру проекта
В терминале:
mkdir ~/twitterbot
cd ~/twitterbot
npm init -y
npm install twit --saveСтруктура каталога будет примерно такой:
- twitterbot/
- server.js
- config.js (или используйте ENV-переменные)
- images.js
- images/ (папка с файлами изображений)
- node_modules/
- package.json
Настройка приложения Twitter и ключей API
- Зарегистрируйте отдельный аккаунт для бота и подтвердите телефон, если требуется.
- На developer.twitter.com создайте приложение (Create an App) и дождитесь одобрения, если нужно.
- В секции Keys and Tokens установите Access permission: Read and Write.
- Создайте и сохраните: Consumer Key, Consumer Secret, Access Token, Access Token Secret.
Варианты хранения ключей:
- config.js (как в исходной инструкции) — удобно, но не безопасно для публичных репозиториев
- Переменные окружения (RECOMMENDED) — безопаснее для продакшена
- Файл .env с библиотекой dotenv (удобно локально, добавьте .env в .gitignore)
Пример безопасного варианта с переменными окружения (рекомендуется):
// config.js (без ключей в репо; конфиг читает из ENV)
module.exports = {
consumer_key: process.env.TW_CONSUMER_KEY,
consumer_secret: process.env.TW_CONSUMER_SECRET,
access_token: process.env.TW_ACCESS_TOKEN,
access_token_secret: process.env.TW_ACCESS_TOKEN_SECRET
};Запуск с передачей переменных:
export TW_CONSUMER_KEY='...'
export TW_CONSUMER_SECRET='...'
export TW_ACCESS_TOKEN='...'
export TW_ACCESS_TOKEN_SECRET='...'
node server.jsИли сохранить в ~/.profile для автоматической загрузки при входе в систему.
Важно: никогда не добавляйте реальные ключи в публичные репозитории. Используйте .gitignore.
Минимальный test: отправка первого твита
Создайте server.js с первой строкой для теста:
console.log('I am a Twitter bot!');Запустите:
node server.jsПоявление строки в консоли подтверждает, что Node.js и окружение работают.
Далее установите библиотеку twit (npm install twit) и в server.js создайте клиента Twit:
var fs = require('fs'),
path = require('path'),
Twit = require('twit'),
config = require(path.join(__dirname, 'config.js'));
var T = new Twit(config);
T.post('statuses/update', { status: 'My first tweet!' }, function(err, data, response) {
console.log(data)
});Запуск node server.js должен отправить тестовый твит.
Подготовка папки с изображениями
- Создайте папку images/ и скопируйте туда начальный набор изображений (10–20 файлов).
- Поддерживаемые форматы: JPG, PNG, GIF. Для анимации дополнительных настроек не требуется, но имейте в виду размеры и продолжительность.
Пример команды копирования с компьютера по SCP:
scp image001.jpg pi@raspberrypi.local:~/twitterbot/images/Код: случайный выбор изображения и загрузка в Twitter
В server.js добавим вспомогательную функцию:
function random_from_array(images){
return images[Math.floor(Math.random() * images.length)];
}Функция загрузки изображения и публикации:
function upload_random_image(images){
console.log('Opening an image...');
var image_path = path.join(__dirname, '/images/' + random_from_array(images)),
b64content = fs.readFileSync(image_path, { encoding: 'base64' });
console.log('Uploading an image...');
T.post('media/upload', { media_data: b64content }, function (err, data, response) {
if (err){
console.log('ERROR:');
console.log(err);
}
else{
console.log('Image uploaded!');
console.log('Now tweeting it...');
T.post('statuses/update', {
media_ids: new Array(data.media_id_string)
},
function(err, data, response) {
if (err){
console.log('ERROR:');
console.log(err);
}
else{
console.log('Posted an image!');
}
});
}
});
}Далее — код, который считывает список файлов в папке images и запускает публикацию по таймеру:
fs.readdir(path.join(__dirname, 'images'), function(err, files){
if (err) return console.log('Unable to read images folder: ' + err);
var images = files.filter(function(file){
return file.match(/\.(jpe?g|png|gif)$/i);
});
// Публикуем случайное изображение каждые 60 секунд (60000 ms)
setInterval(function(){
upload_random_image(images);
}, 60000);
});Примечание: для реального аккаунта лучше увеличить интервал (например, от 1 часа и больше), чтобы не нарушать нормы использования и не выглядеть как спам.
Добавление текста и атрибуции к каждому изображению
Создайте файл images.js с массивом объектов, которые содержат имя файла и поле source (атрибуция или подпись):
var images = [
{
file: 'image0001.png',
source: 'http://www.example.com/image0001.png'
},
{
file: 'image0002.png',
source: 'http://www.example.com/image0002.png'
}
];
module.exports = images;В server.js импортируйте массив:
images = require(path.join(__dirname, 'images.js'));Обновите upload_random_image, чтобы брать объект и добавлять текст к твиту:
function random_from_array(images){
return images[Math.floor(Math.random() * images.length)];
}
function upload_random_image(images){
var item = random_from_array(images);
var image_path = path.join(__dirname, '/images/' + item.file);
var b64content = fs.readFileSync(image_path, { encoding: 'base64' });
T.post('media/upload', { media_data: b64content }, function (err, data, response) {
if (err){
console.log(err);
return;
}
var statusText = item.source || '';
T.post('statuses/update', {
status: statusText,
media_ids: [data.media_id_string]
}, function(err, data, response) {
if (err) console.log(err);
else console.log('Posted:', item.file);
});
});
}Теперь каждый твит будет содержать текст из поля source и загруженную картинку.
Автоматический запуск и мониторинг
Для постоянной работы на Raspberry Pi рекомендуются способы демонизации:
- pm2 — простой процессный менеджер для Node.js
- systemd — системный менеджер служб на Linux
- cron (для одиночных запусков)
Пример с pm2:
sudo npm install -g pm2
pm2 start server.js --name twitterbot
pm2 save
pm2 startup # чтобы pm2 запускался после перезагрузкиsystemd пример (файл /etc/systemd/system/twitterbot.service):
[Unit]
Description=Twitter bot
After=network.target
[Service]
ExecStart=/usr/bin/node /home/pi/twitterbot/server.js
Restart=always
User=pi
Environment=TW_CONSUMER_KEY=... TW_CONSUMER_SECRET=...
[Install]
WantedBy=multi-user.targetПосле создания файла:
sudo systemctl daemon-reload
sudo systemctl enable twitterbot
sudo systemctl start twitterbot
sudo journalctl -u twitterbot -fРекомендация: используйте systemd с переменными окружения или pm2 с файлом ecosystem.config.js, где ключи не хранятся в репозитории.
Обработка ошибок и устойчивость
- Логируйте ошибки в файл (winston или простой fs.appendFile)
- Добавьте повторы при временных сетевых ошибках (retry с экспоненциальной задержкой)
- Обрабатывайте лимиты API: в случае 429 (Too Many Requests) увеличивайте интервал
- Для крупных объёмов планируйте очередь и дедупликацию сообщений
Безопасность и конфиденциальность
- Не храните ключи в публичных репозиториях
- Не собирайте личные данные целевой аудитории
- Удаляйте метаданные (EXIF) из фотографий, если не хотите раскрывать местоположение
- Следите за правами на изображение: если лицензия требует указания атрибуции, добавляйте её в текст твита
Примечание по GDPR: если вы обрабатываете персональные данные граждан ЕС (например, изображения людей, идентифицируемые лица), изучите требования к согласиям и правам субъектов данных.
Советы по улучшению контента изображений
- Добавляйте альтернативный текст (alt) для изображений при публикации — Twitter поддерживает отдельные описания для доступности (media/metadata/create API). Это улучшает доступность для людей с нарушениями зрения.
- Используйте библиотеку sharp или canvas для наложения текста/атрибуции прямо на изображение, если нужно, чтобы подпись всегда была видна.
Пример добавления alt (метаданные) — псевдокод:
T.post('media/metadata/create', { media_id: data.media_id_string, alt_text: { text: 'Описание изображения для пользователей с экранными чтителями' } }, function(err, result){
if (!err) {
T.post('statuses/update', { status: statusText, media_ids: [data.media_id_string] }, ...);
}
});Тестирование и критерии приёмки
Критерии приёмки (что должно работать):
- Бот успешно публикует изображение в Twitter при ручном запуске
- Бот добавляет корректную подпись/атрибуцию из images.js
- При отсутствии сети бот логирует ошибку и повторяет попытку
- При превышении лимитов бот увеличивает интервал публикации и информирует логом
- Ключи API не присутствуют в публичных репозиториях
Тестовые сценарии:
- Тест публикации одного изображения
- Тест публикации очереди из 10 изображений
- Повторная публикация того же изображения — ожидаемое поведение (он случайный; можно добавить дедупликацию)
- Симуляция ошибки сети: убедиться, что логируется и происходит повтор
Роль‑ориентированные чеклисты
Разработчик:
- Написать и протестировать server.js
- Настроить обработку ошибок и логи
Контент‑куратор:
- Проверить лицензии изображений
- Подготовить images.js с корректной атрибуцией
- Оптимизировать изображения
Администратор/OPS:
- Настроить автоматический запуск (pm2/systemd)
- Настроить мониторинг и бэкапы
- Обеспечить безопасное хранение ключей
Мини‑методология работы с ботом
- Собирать и проверять изображения в отдельной ветке.
- Обновлять images.js и тестировать локально на dev‑аккаунте Twitter.
- После проверки деплоить на Pi и наблюдать первые 24–48 часов.
- Анализировать логи и метрики, корректировать интервалы.
Чеклист безопасности и соответствия
- Ключи в ENV или защищённом хранилище
- .gitignore содержит config.js и .env
- Удаление EXIF для приватности
- Проверка лицензий и указание источников в каждом твите
Шаблоны команд и сниппеты (cheat sheet)
- Инициализация проекта:
mkdir twitterbot && cd twitterbot
npm init -y
npm install twit --save- Копирование изображения на Pi:
scp image001.jpg pi@raspberrypi.local:~/twitterbot/images/- Запуск с pm2:
pm2 start server.js --name twitterbot
pm2 save
pm2 logs twitterbotАльтернативные подходы
- Python: библиотеки tweepy или python-twitter — если вы предпочитаете Python
- Хостинг в облаке: если Pi ненадёжен, можно разместить бота на VPS или Heroku
- Использование очередей: RabbitMQ/Redis для управления частыми публикациями
Когда этот подход не подойдёт
- Если вам нужно строгое соблюдение расписания в рамках временных зон — лучше планировать публикации через cron или сервисы планирования
- Если требуется сложная обработка изображений в реальном времени — Pi может быть медленным; лучше использовать более мощный сервер
Примеры ошибок и пути их устранения
- Ошибка: 401 Unauthorized — проверьте ключи API и права доступа (Read and Write).
- Ошибка: EACCES при доступе к файлам — проверьте права на каталог и пользователя, от которого запускается сервис.
- Ошибка: 429 Too Many Requests — уменьшите частоту публикаций и добавьте backoff.
Планы развития и миграция
- Добавить очередь и веб‑интерфейс для ручного утверждения твитов
- Использовать CDN для хранения изображений и ссылки в атрибуции
- Миграция в облако при увеличении нагрузки
Краткая сводка и рекомендации
- Начните с малого: 1‑2 твита в день для реальных аккаунтов
- Храните ключи в ENV и не выкладывайте в общедоступные репозитории
- Проверьте лицензии изображений и всегда указывайте источники
- Используйте pm2 или systemd для устойчивой работы
Important: если аккаунт бота начнёт публиковать слишком часто или содержать повторяющийся спам, Twitter может ограничить доступ. Поддерживайте умеренную частоту публикаций и разнообразие контента.

Изображение Raspberry Pi, на котором работает Twitter‑бот (вид платы и подключённых кабелей).
Скриншот: пример аккаунта, который автоматически публикует фотографии.
Скриншот интерфейса создания приложения на платформе разработчика Twitter.
Иллюстрация: вставка ключей API в локальный конфигурационный файл (примеры скрыты).
Иллюстрация: окно терминала с кодом, который инициирует отправку твита через API.
Скриншот: тестовый твит, отправленный через Node.js скрипт.
Иллюстрация: пример твита, где картинка сопровождается текстом и ссылкой на источник.
Ключевые выводы:
- Бот на Node.js и Raspberry Pi — простой и гибкий способ автоматизировать публикации.
- Безопасно храните ключи, оптимизируйте изображения и соблюдайте лицензионные требования.
- Для долгой и корректной работы настройте мониторинг и стратегии повторных попыток при ошибках.
Похожие материалы
Email при входе в Windows 11
Как использовать группы вкладок в Safari
Shortcuts на Apple Watch — как запускать с запястья
Установка и использование расширений Safari на Mac
Подключиться к Windows с Raspberry Pi