Цель этой статьи — показать вам, как планировать, разрабатывать и развертывать бота Twitter. Если вы будете следовать дальше, к концу у вас будет развернутый бот Twitter, но его можно использовать в качестве общего шаблона для взаимодействия с API Twitter и знакомства с Heroku. Бот, который мы будем делать, будет твитить изображение спрайта покемона один раз в час с подписью, описывающей его.

Бот Twitter будет использовать несколько технологий, но в основном он будет использовать API Twitter, API Pokémon, Node, JavaScript ES6 Promises и Heroku. К концу статьи у вас будет развернутый Twitter-бот, подобный этому: https://twitter.com/Pokemon_Sprites.

Процесс программирования бота Twitter довольно прост, и как только вы поймете, как его создать, возможности безграничны для того, что вы можете заставить его делать. Твитнуть фотографии из архива? Документировать финансовые изменения на фондовом рынке? Ретвитить изображения фильмов #SpaghettiWestern? Все это выполнимо с помощью Twitter API и технических ноу-хау или любопытства.

Начиная с Twitter API

Для нашего Twitter-бота нам понадобятся две вещи:

  1. Новый аккаунт в Твиттере.
  2. Учетная запись разработчика Twitter с ключами API и доступом для чтения и записи.

Подписываясь

Сначала мы начнем с создания учетной записи Twitter или входа в учетную запись Twitter, которая у вас уже есть (бот будет твитить на временной шкале учетной записи, поэтому лучше создать новую учетную запись). Чтобы создать новую учетную запись, перейдите по этой ссылке в Twitter: https://twitter.com/i/flow/signup.

Если вы зарегистрировались только с номером телефона, вы должны добавить адрес электронной почты в свою учетную запись. Нам понадобится это для привязки к учетной записи разработчика. Создав учетную запись, мы готовы приступить к настройке нашей учетной записи разработчика.

Портал разработчиков Твиттера

Здесь мы можем подать заявку на нашу учетную запись разработчика:

https://developer.twitter.com/en/apply/user.html

В следующих нескольких шагах у нас есть несколько вариантов, но они хорошо объясняются в документации.

  1. Мы хотим подать заявку в категории Hobbyist на создание бота Twitter, после выбора нажмите «Далее».
  2. Заполните свою страну и имя вашего бота, затем нажмите «Далее».
  3. Опишите, что вы собираетесь делать с учетной записью разработчика в Твиттере: создайте бота в Твиттере с помощью Pokémon API. Выберите «нет» для всех вариантов, а затем нажмите «Далее».
  4. Проверьте свою информацию и убедитесь, что она выглядит хорошо.
  5. Примите Условия использования. (Мы приближаемся!)
  6. Нажмите на подтверждение в электронном письме, отправленном вам Twitter.
  7. Назовите своего нового бота!
  8. Перейдите к панели инструментов — нам нужно будет изменить настройку и заново сгенерировать ключи.

9. На странице настроек в разделе «Разрешения приложения» измените разрешения на «Чтение и запись».

10. Теперь прокрутите вверх и измените панели вкладок, чтобы просмотреть ключи и токены API.

11. Нам нужны 4 вещи: ключ API, секрет ключа API, ключ токена доступа и секрет токена доступа.

12. Восстановите их и запишите или скопируйте и вставьте в безопасное место на потом.

13. Время ботов!

Планирование нашей программы

Эта часть статьи будет посвящена фактическому программированию бота Twitter. Однако он предполагает несколько вещей: базовое понимание терминала или командной строки, знание основ JavaScript и общее знакомство или понимание работы с API и JSON. Однако мы не будем углубляться ни в одну из этих тем, и здесь нет ничего особенно сложного для понимания, если рассматривать его по частям.

Прежде чем мы приступим к написанию кода, важно подумать о том, чего мы пытаемся достичь, каков наш MVP (минимально жизнеспособный продукт) для этого проекта? Ничего особенного — бот, который будет твитить спрайт покемона раз в час с простой подписью, описывающей его. Мы знаем, что нам нужно использовать API покемонов, чтобы получить эту информацию, так что давайте начнем с этого.

API покемонов

Pokémon API — один из самых удобных и доступных способов работы с API и JSON. Это RESTful API с простыми для понимания маршрутами для изучения данных. Некоторые конечные точки возвращают разбитые на страницы массивы объектов, представляющих покемонов, детали которых мы можем изучить, но нас интересует конечная точка для одного покемона, которая будет иметь полную информацию.

Когда мы делаем запросы API к базе данных, чтобы получить подробную информацию о покемонах, мы будем использовать эти маршруты конечных точек, перечисленные кнопкой отправить на изображении выше. Просматривая информацию о Bulbasaur, покемоне номер 1 в Pokédex, мы можем увидеть для него множество различных типов данных. У нас есть пары ключ/значение для доступа к данным в возвращаемом JSON, которые мы хотим использовать. Мы можем сузить значения, перемещаясь по массивам и объектам, чтобы найти то, что нам нужно. Просмотреть необработанный JSON для Bulbasaur.

Наиболее важным здесь для конечной точки API является то, что мы можем получить к ней доступ либо через имя покемона, либо через его идентификатор. Идя по маршруту идентификатора, мы можем использовать стандартную функциональность JavaScript для создания случайного числа, которое будет добавлено к этому маршруту, поэтому наш твит будет рандомизироваться каждый час.

https://pokeapi.co/api/v2/pokemon/811
Here '811' represents the unique endpoint for a Pokemon. We can append numbers onto this to randomize the Pokemon encountered.

Знание конечных точек API и формы данных помогает нам принимать важные дизайнерские решения, когда мы начинаем писать код, чтобы собрать всю эту информацию воедино. Например, мы могли бы использовать маршрут, который заканчивается именем покемона, для создания функции поиска! Зная все это, пришло время заняться программированием.

Кодирование нашей программы

В терминале

Для начала нам нужно открыть терминал или командную строку и перейти туда, где мы хотим начать наш проект. Там мы создадим новую папку и несколько файлов. В командной строке введите:

mkdir pokemon-bot && cd pokemon-bot

Это создаст каталог с именем «pokemon-bot» и войдет в него из командной строки. Теперь запустите:

npm init -y

Это инициализирует пакет узлов для вашего приложения.

Прежде чем мы покинем терминал, нам нужно еще несколько вещей:

npm i twitter node-fetch

Это установит два пакета, которые нам нужны для использования нашего бота — twitter и node-fetch. Это позволяет нам использовать Twitter API и делать запросы на выборку к Pokémon API в нашей среде Node/JavaScript.

Наконец, нам нужны три файла:

touch Procfile .gitignore bot.js

Кроме того, мы хотим инициализировать наш проект:

git init

Touch создает файлы, поэтому мы используем его для создания Procfile для Heroku (что будет похоже на то, как мы запускаем нашего бота локально), gitignore, поэтому мы не отправляйте на Github то, что нам не нужно, и bot.js, фактический файл JavaScript, который будет запускать нашу программу. Запуск git init инициализирует наш репозиторий для использования с программным обеспечением Git’s version control. Теперь мы можем ввести код. или атом. чтобы открыть наш проект в выбранном нами редакторе (или откройте свой редактор, а затем откройте папку pokemon-bot).

В нашем редакторе

  1. В наш файл .gitignore нам нужно добавить:
node_modules 
image.png

При фиксации на Github будут игнорироваться наши node_modules и образ, который мы будем создавать.

2. В наш Procfile мы добавим:

worker: node bot.js

Это все, что нам нужно для запуска нашего файла bot.js после его развертывания в Heroku. На этом этапе мы можем написать функциональность бота.

В нашем файле bot.js, чтобы проверить, все ли работает, добавьте:

console.log(‘Hello, world’);

В терминале запустить:

node bot.js

Вы должны увидеть «Hello, world», напечатанное в терминале. Если это так, продолжайте и удалите оператор консоли — это просто для проверки того, что наши файлы связаны.

3. В нашем файле bot.js у нас есть импорт, который нужно добавить, и две переменные, которые нам понадобятся для Pokémon API:

const Twitter = require(‘twitter’);
const fs = require(‘fs’);
const fetch = require(‘node-fetch’);
const request = require(‘request’);
const baseURL = “https://pokeapi.co/api/v2/pokemon/";
const pokemonCountURL = “https://pokeapi.co/api/v2/pokemon-species/?limit=0";

Twitter позволяет нам использовать их API, fs позволяет нам использовать FileSystem, а fetch ​​и request будут использоваться в наших вызовах API. baseURL и pokemonCountURL также будут использоваться для связи с Pokémon API, когда мы создадим нашу уникальную конечную точку URL для доступа к данным Pokemon.

4. Далее мы объявим наш объект конфигурации с ранее сохраненными ключами API и передаем его в новый экземпляр Twitter API. Эта созданная переменная «PokemonBot» — это то, что мы будем использовать для публикации нашего изображения и твита.

const config = {
     consumer_key: ‘123YourKey’,
     consumer_secret: ‘456YourOtherKey’,
     access_token_key: ‘123AnotherKey’,
     access_token_secret: ‘456TheLastOne’
};
const PokemonBot = new Twitter(config);

На этом этапе ваш файл bot.js должен выглядеть так и содержать вашиключи API.

Сервисные и вспомогательные функции

Теперь мы можем написать четыре вспомогательные/служебные функции, которые мы будем использовать для 1) получения количества покедексов, 2) создания случайного числа в пределах диапазона количества покедексов, 3) получения сведений о покемонах и 4) загрузки изображение на основе URL-адреса спрайта этого покемона.

  1. получить количество покемонов ()

Это относительно обобщенная функция, которую мы будем использовать для получения текущего количества покедексов (оно всегда растет, поэтому наш бот таким образом будет защищен от будущего). Он принимает конечную точку «URL» для API Pokémon и отправляет ответ, который мы конвертируем в JSON и возвращаем как «данные». Мы будем использовать этот JSON, чтобы получить текущее количество покедексов, и с этим числом мы можем создать новое случайное число. Этот номер будет идентификатором, переданным в конечную точку RESTful для Pokémon API, который будет возвращать подробную информацию о данном покемоне.

Эта и некоторые другие функции будут использовать JavaScript Promises. Когда мы запускаем наш код вместе, его нужно будет запускать асинхронно, чтобы мы могли дождаться результатов вызова, чтобы сделать другой вызов — у нас не будет доступа к подробному URL-адресу Pokemon при нашем втором вызове API для например, поэтому нам нужно сначала получить наш счет, чтобы построить нашу ссылку.

2. случайноеЧислоВ пределахДиапазона()

Еще одна обобщенная функция, использующая общий метод Math.random() для получения случайного числа в диапазоне количества покедексов.

3. получить сведения о покемонах ()

Подобно getPokemonCount(), getPokemonDetails() вернет Promise и примет «url» — URL будет тот, который мы создадим с помощью переменной «baseURL» и результата randomNumberWithinRange().

4. загрузить изображение ()

Эта функция примет uri (идентификатор конкретного ресурса, URL-адрес нашего изображения), имя файла и функцию обратного вызова. В сочетании с обещанием это запросит ресурс из URI, запишет его в файл через файловую систему и разрешит обещание в функции обратного вызова, которая передается в него.

Объединение всех этих функций вместе приведет к загрузке всех данных, которые наш бот должен отправить в Твиттер: количество покедексов, новый случайный идентификатор, представляющий покемона, детали этого покемона и их спрайт.

Наконец, нам нужно написать логику, чтобы алхимизировать все наши элементы вместе и опубликовать твит.

Создание мозга нашего бота

Сначала нам нужно будет объявить асинхронную стрелочную функцию:

const encounterAndTweetPokemon = async () => {
};

Нам нужно, чтобы наша функция была асинхронной, чтобы использовать ожидающую природу промисов.

Нашей первой задачей является объявление «заголовка» для последующего использования и запуск нашей первой сервисной функции API «getPokemonCount()». Мы передадим pokemonCountURL, который мы определили ранее, и привяжем к нему новое обещание с помощью ‘.then(response)’. Это возвращает разрешенные данные из вызова API, и с этими данными мы можем получить доступ к значению счетчика, используя точечную запись с «response.count».

Теперь мы добавим еще один ‘.then()’, на этот раз с pokedexCount, который мы возвращаем из промиса getPokemonCount(). С этим значением мы можем передать в getPokemonDetails литерал шаблона, объединяющий baseURL и результат нашей вспомогательной функции с pokedexCount.

getPokemonDetails(`${baseURL}${randomNumberWithinRange(1, pokedexCount)}`)

В конечном итоге это будет выглядеть примерно так: https://pokeapi.co/api/v2/pokemon/549 и будет URL-адресом, переданным в функцию.

Внутри этого ‘.then(pokemon)’ у нас есть JSON случайного покемона! Мы можем перейти к свойствам объекта этого покемона, чтобы получить такие значения, как его номер, имя, тип и URI для вида спереди покемона. Например, у покемонов может быть несколько типов, поэтому для доступа к первому типу мы объявим:

const type = pokemon.types[0].type.name;

Это позволит получить доступ к первому объекту в массиве типов, в этом объекте первого типа мы получим доступ к свойству «имя». Мы можем назначить литерал шаблона переменной заголовка, объявленной в верхней области видимости, используя эту переменную type и другие объявленные нами переменные. Это будет наша простая, но эффективная подпись к твиту.

(no. 658) — greninja — water

Наконец, мы возвращаем другое обещание для загрузки изображения покемона — мы передаем наш photoURL, имя файла и функцию обратного вызова, разрешающую обещание. В этот момент наша функция получает случайного покемона из Pokédex, создает для него заголовок и загружает его изображение! Мы обязательно туда попадем.

Мы можем использовать FileSystem для чтения из файла, который мы создали в функции downloadImage. Данные принимают __dirname, ссылаясь на каталог проекта, и помогают нам создать путь к файлу изображения. Теперь мы взаимодействуем с API Twitter, загружая изображение, хранящееся в переменных данных. Мы ОТПРАВЛЯЕМ в Twitter, используя параметры media/upload с нашим медиа-объектом data.

Наконец-то мы можем вернуть медиа и опубликовать его в Твиттере. Возвращая «медиа» из нашего последнего обещания, мы регистрируем успешное обновление для наших журналов Heroku. Мы объявляем «статус», объект, который содержит нашу подпись и уникальный идентификатор мультимедиа, который мы получаем при загрузке нашего изображения в возвращенном промисе. Все, что нужно сейчас, — это добавить этот объект статуса к PokemonBot, который накапливал данные по мере разрешения нашей функции. Просто мы просто регистрируем твит и фиксируем любую ошибку, если она возникает — все это для Heroku после развертывания. Чтобы запустить нашу функцию, мы должны вызвать ее с помощью «encounterAndTweetPokemon()» в строке 98. На этом этапе мы можем запустить «node bot.js» в терминале, и мы должны увидеть журналы консоли в терминале, а также твит на нашем Лента новостей!

Если все работает, мы можем подготовиться к развертыванию нашего бота в Heroku, чтобы он запускался автоматически в установленное время.

Код для справки

Подготовьтесь к развертыванию

Мы начнем с редактирования нашего объекта конфигурации Twitter, чтобы наши переменные не были видны публично, если у нас есть репозиторий Github. Heroku умен и может считывать эти значения с помощью нескольких настроек, которые мы изменим.

Собственно, это все, что касается нашего кода — теперь мы можем подготовиться к развертыванию на Heroku и размещению нашего бота в сети.

Настройка и развертывание

  1. Создайте учетную запись Heroku или войдите
  2. Скачать и установить интерфейс командной строки Heroku
  3. В терминале с учетной записью Heroku и настройкой CLI запустите:
heroku create

Это создаст новый репозиторий Heroku, который мы будем использовать при развертывании нашего приложения в Интернете. Heroku рандомизирует ваш репозиторий и имя приложения, поэтому для удобства вы можете при желании запустить следующее:

heroku apps:rename newname

С «новым именем» будет «pokemon-bot5000» или любое другое имя, которое вы хотите.

Когда наш репозиторий инициализирован, мы можем запускать следующие команды по одной:

git add .
git commit -m “prepare files to deploy to heroku”
git push heroku master

Это добавляет все наши файлы, за исключением того, что находится в нашем .gitignore, делает «фиксацию» в нашей истории Git с указанным нами сообщением и отправляет этот код в Heroku. Если все пойдет хорошо, мы должны увидеть наше приложение на панели инструментов!

Нажав на наше приложение, мы перейдем к другой панели инструментов, характерной для нашего приложения; здесь мы добавим надстройку Heroku Scheduler и установим наши ключи API для чтения Heroku.

Как только мы окажемся на странице надстроек, мы найдем планировщик Heroku, добавим его (бесплатно) и щелкнем надстройку, чтобы настроить нашу работу Dyno.

Наша задача достаточно проста — мы можем выбрать, когда она запускается и что делает задача. Планировщик Heroku будет использовать встроенную командную строку для запуска «node bot.js», который запустит созданный нами ранее рабочий процесс Procfile.

На панели инструментов приложения мы хотим перейти в «Настройки» и отредактировать переменные среды приложения. Чтобы установить их:

Когда все наши ключи настроены, а задача запланирована, мы можем самостоятельно искать бота для твита. Надстройка планировщика Heroku будет отображаться, когда задача будет запущена в следующий раз. Когда все настроено, наш Twitter-бот готов к работе! Он построен!

Если у вас есть какие-либо вопросы или предложения, оставьте комментарий!

Код: https://github.com/sanchito59/Pokemon_Twitter_Bot

Бот: https://twitter.com/Pokemon_Sprites

Другие боты: https://twitter.com/i/lists/1316210473084219393