В этом уроке мы расскажем, как создать трекер хэштегов в реальном времени с помощью Twitter API.
Прежде чем приступить к работе, вы должны иметь утвержденную учетную запись разработчика и активировать новый интерфейс портала для разработчиков.
1- Настройка проекта
Сначала нам нужно инициализировать наш проект
mkdir real-time-tweet-streamer
cd real-time-tweet-streamer
npm init
Далее мы установим некоторые пакеты, также известные как зависимости:
npm install express ejs node-tweet-stream request socket.io dotenv
Express: это серверная веб-инфраструктура, основанная на NodeJS. Express поможет нам создать внутреннюю логику, API.
Socket.io: библиотека JavaScript, которая обеспечивает двустороннюю связь между клиентом и сервером в режиме реального времени.
ejs: механизм шаблонов помогает создавать и генерировать HTML-страницы и вставлять данные в HTML-шаблон с помощью простого JavaScript.
node-tweet-stream: модуль твиттера узла, который подключается к общедоступному потоку твиттера. n.t.s поможет нам отслеживать список ключевых слов.
dotenv: модуль, который позволяет получить доступ к переменным среды в нашем приложении.
2- Учетные данные
Для подключения к потоку твитов необходимо настроить набор учетных данных. Чтобы инициализировать наши ключи, нам нужно сначала создать файл .env
, который должен содержать следующие ключи:
API_KEY="your api key here"
API_SECRET_KEY="your api secret key here"
ACCESS_TOKEN="your access token here"
ACCESS_TOKEN_SECRET="your secret access token here"
3- Создайте код на стороне сервера
Прежде чем погрузиться в редактирование кода, мы сначала структурируем наш проект:
. ├── public │ ├── images │ │ └── Twitter_Logo_Blue.png │ ├── javascripts │ │ └── socket-cli.js │ └── stylesheets │ └── styles.css ├── routes └── index.js ├── views └── index.ejs ├── config-streamer.js ├── server.js ├── package.json └── package-lock.json
Общедоступно: будут содержаться все статические файлы (таблицы стилей, файлы JS, изображения и т. д.).
Маршруты: содержат наши контроллеры приложений, где мы будем отображать HTML-страницу для отображения запрошенных данных.
Представления: где мы собираемся установить шаблоны, которые будут использоваться контроллерами для отображения данных.
touch server.js
Во-первых, нам нужно создать сервер Node. server.js
будет содержать всю внутреннюю логику для подключения и получения твитов от стримера твитов.
- Содержимое
server.js
будет следующим:
Мы собираемся настроить приложение со всеми установленными зависимостями и настроить приложение для использования EJS.
const express = require('express') const path = require('path') const http = require('http') const app = express() const port = process.env.PORT || 9000 const server = http.createServer(app) //setting a socket.io server const { Server } = require('socket.io') const io = new Server(server) //setting static and views paths app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'ejs') app.use(express.json()) app.use(express.urlencoded({extended: true})) app.use(express.static(path.join(__dirname, 'public'))) // use the created index route const indexRouter = require('./routes/index') app.use('/', indexRouter); //setting the tweets streamer event handlers const twitter = require('./config-streamer') const MAX_TWEETS = 10 let tweets = [] twitter.on('tweet', tweet => { io.emit('tweet', tweet); tweets.unshift(tweet); tweets = tweets.slice(0, MAX_TWEETS); }); server.listen(port, () => { console.log(`listening on http://localhost:${port}`) })
Обратите внимание, что вы должны инициализировать новый экземпляр socket.io
, передав объект server
(HTTP-сервер).
4- клиент Twitter
Далее мы создадим файл с именем config-streamer.js
, где у нас есть клиент Twitter, используя настроенные учетные данные в .env
file.
touch config-streamer.js
- Содержимое
config-streamer.js
будет следующим:
const Twitter = require('node-tweet-stream') const dotenv = require('dotenv') dotenv.config() const twitter = new Twitter({ consumer_key: process.env.API_KEY, consumer_secret: process.env.API_SECRET_KEY, token: process.env.ACCESS_TOKEN, token_secret: process.env.ACCESS_TOKEN_SECRET }) // we are tracking the word javascript for now twitter.track('javascript') twitter.on('error', err => { console.error(err); }); module.exports = twitter
5 – Клиентский код
Прежде чем погрузиться в настройку представлений, нам нужно создать файл index.js
, в котором мы настроим маршрут для индексной страницы (мы можем добавить больше маршрутов).
touch routes/index.js
Добавьте следующий код в файл index.js
:
const express = require('express') const router = express.Router() router.get('/', (req, res) => { res.render('../views/index', { title: "Home page" }) }) module.exports = router
Обратите внимание, как код отправляет представление клиенту с помощью res.render()
поэтому этот последний вызов будет искать представление для отображения в каталоге представлений. Итак, нам нужно только определить views/index.ejs
touch views/index.ejs
Добавьте следующий код в index.ejs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><%= title %></title> <link rel="stylesheet" href="/stylesheets/styles.css"> </head> <body> <div class="root"> <div class="App"> <div class="header"> <img class="header-logo" src="/images/Twitter_Logo_Blue.png" > <div class="header-nav"> <div class="header-option"> <span class="header-optionLineOne">GitHub</span> <span class="header-optionLineTwo">account</span> </div> <div class="header-option"> <span class="header-optionLineOne">LinkedIn</span> <span class="header-optionLineTwo">account</span> </div> </div> </div> <div class="home"> <div class="home-container"> <div class="home-row" id="tweets"></div> </div> </div> </div> </div> <script src="/socket.io/socket.io.js"></script> <script src="/javascripts/socket-cli.js"></script> </body> </html>
index.ejs
Будет ли файл содержать представление индексной страницы.
Установите <div class="home-row" id="tweets" >
, где мы будем отображать содержимое твита каждый раз, когда получаем новый твит.
Затем создайте новый файл с именем public/javascripts/socket-cli.js
и добавьте следующий код.
var socket = io(); var tweetsArea = document.getElementById('tweets') socket.on('tweet', function(tweet) { const content = ` <div class="tweet"> <div class="box"> <article class="media"> <div class="media-left"> <figure class="image is-64x64" > <img src=${tweet.user.profile_image_url} alt="Image" /> </figure> </div> <div class="media-content"> <div class="content"> <p> <strong>${tweet.user.name}</strong> <small>@${tweet.user.screen_name}</small><br /> ${tweet.extended_tweet ? tweet.extended_tweet.full_text : tweet.text} </p> </div> <div class="level-left"> <div class="level-item"> <span><small>${ tweet.created_at}</small></span> <button class="btn"> <a href="${getUrlsFromText(tweet.text)[0]}">See TWEET</a> </button> </div> </div> </div> </article> </div> </div> ` tweetsArea.innerHTML += content window.scrollTo(0, document.body.scrollHeight) })
для загрузки socket.io-client
требуется только первая строка var socket = io()
, которая предоставляет глобальную io
(и конечную точку GET
), а затем подключается.
Преимущество socket.io
в том, что мы можем завершать и получать любые события и данные, какие захотим.
Таким образом, каждый раз, когда у нас появляется новый твит, содержащий целевые слова, сервер получает его как событие tweet
. и мы добавляем контент после создания представления твитов в область твитов
Итак, после запуска nodemon server.js
результат должен быть следующим:
не забудьте добавить файл таблицы стилей, поэтому в каталоге public/stylesheets
добавьте файл с именем styles.css
и добавьте следующий код
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen','Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; background: #e6ecf1; } .header { height: 60px; display: flex; align-items: center; background-color: #131921; position: sticky; top: 0; z-index: 100; } .header-logo { width: 100px; object-fit: contain; margin: 0 20px; margin-top: 18px; } .header-optionLineTwo { font-size: 10px; } .header-optionLineOne { font-size: 13px; font-weight: 800; } .header-nav { display: flex; justify-content: space-evenly; } .header-option { display: flex; flex-direction: column; margin-left: 10px; margin-right: 10px; color: white; } .home { display: flex; justify-content: center; margin-left: auto; margin-right: auto; max-width: 1500px; } .tweet { margin: 10px; padding: 20px; width: 100%; max-height: 400px; background-color: white; } .box { margin-bottom: 0; border-radius: 0; } .content small { color: #1da1f2; } .level-item { padding-right: 10px; color: #c3c3c3; } .media-left { margin-right: 1rem; } .media{ display: flex; align-items: flex-start; text-align: left; } .image { display: block; position: relative; } .image > img { display: block; height: auto; width: 100%; border-radius: 30px; } .image.is-64x64 { height: 64px; width: 64px; } .tweet-info { height: 100px; margin-bottom: 15px; } .control { font-size: 1rem; position: relative; text-align: left; } .btn{ border: none; color: white; background-color: #1da1f2; padding: 10px 9px; text-align: center; margin: 16px 16px !important; text-decoration: none; cursor: pointer; font-size: 11px; }
Заключение
В этой статье мы узнали, как использовать Twitter API для потоковой передачи твитов с заданными ключевыми словами.
Использование socket.io
позволяет получать данные в режиме реального времени. Обратитесь к документации socket.io, чтобы получить дополнительную информацию о интересных вещах и функциях.
Код можно найти на GitHub ЗДЕСЬ