Как создать бота для анализа сообщений на Node.js и GigaChat
Рассказываем, как с помощью нейросети создать Telegram-бота, который собирает и обрабатывает информацию с сообщений.
Введение
Есть Telegram-каналы, которые отслеживают определенные события в мире, например, перемещение криптовалют. Если собирать и анализировать данные вручную, процесс будет отнимать много времени и требовать высокой концентрации от человека. Чтобы решить эту проблему, мы решили создать Telegram-бота, который автоматизирует процесс и выдает резюме по собранной информации.
Пример работы Telegram-бота:
/sum whale_alert_io Ты - опытный криптоинвестор. Просуммируй мне результат этих сообщений и выдай общую динамику по тому, что происходит
/sum — команда обращения к боту, whale_alert_io — ID канала (можно подставить любой), остальной текст — произвольная команда для робота.
Авторизация
Первым делом нужно авторизовать аккаунт, чтобы получить доступ к сообщениям бота. Через бота такой функционал недоступен, поэтому будем использовать библиотеку GramJS.
Заходим на my.telegram.org, открываем API development tools и создаем приложение.
В ответе получаем параметры apiId и apiHash. Подставляем данные в код авторизации:
const { TelegramClient } = require('telegram')
const input = require('input')
const { StringSession } = require('telegram/sessions')
const session = new StringSession('')
const apiId = 123 // подставляем данные из Telegram
const apiHash = 'abc' // подставляем данные из Telegram
;(async () => {
console.log('Loading interactive example...')
const client = new TelegramClient(session, apiId, apiHash, {
connectionRetries: 5,
})
await client.start({
phoneNumber: async () => await input.text('Please enter your number: '),
password: async () => await input.text('Please enter your password: '),
phoneCode: async () =>
await input.text('Please enter the code you received: '),
onError: (err) => console.log(err),
})
console.log('You should now be connected.')
console.log(client.session.save()) // в консоли получим строчку, которую нужно будет сохранить
})()
auth.js.
Консоль попросит номер телефона, пароль и код подтверждения — заполняем данные и получаем строку сессии. Ее нужно сохранить, чтобы не авторизироваться каждый раз.
Запускаем на Node.js функцию node auth, чтобы получить ключ авторизации и продолжить работу с запросами к Telegram.
Реализация функционала
Добавим в Telegram-бот функцию поиска непрочитанных сообщений. Для этого инициализируем client с уже сохраненной сессей. После — используем метод getUnreadMessages:
const { TelegramClient } = require('telegram')
const { NewMessage } = require('telegram/events')
const { session, apiId, apiHash} = require('./config')
const client = new TelegramClient(session, apiId, apiHash, {})
async function getUnreadMessages(channelId, limit = 10) {
const dialogs = await client.getDialogs({}) // получаем все чаты
const channel = dialogs.find((d) => d.entity.username === channelId) // находим нужный по ID
if (channel) { // если канал найдет
const messages = await client.getMessages(channel.entity, { // получаем список сообщений
// limit: channel.unreadCount, // можем прочесть количество непрочитанных сообщений
limit, // сколько сообщений получаем
})
console.log(messages.map((m) => m.message).join(' ')) // выводим в консоль
} else {
console.log('Канал не найден')
}
}
;(async function run() {
// const channel = 'whale_alert_io'
// watchNewMessages(channel) // важно, чтоб метод был до client.connect
await client.connect()
await getUnreadMessages(channelId, 10)
})()
Чтобы бот анализировал не только непрочитанные, но и новые сообщения в чатах, можно использовать метод watchNewMessages:
function watchNewMessages(channelId) {
client.addEventHandler((event) => {
console.log('new message', event.message.message)
}, new NewMessage({ fromUsers: [channelId] }))
}
Пропускаем сообщения через нейросеть
Мы будем использовать GPT-модель GigaChat, которая предоставляет бесплатно до 1 млн токенов. Чтобы начать работу с API, нужно узнать значения clientID и clientSecret.
- Регистрируемся на сайте GigaChat API и создаем проект.
- В панели справа находится поле Client ID — копируем значение.
- Нажимаем Получить Client Secret, чтобы сгенерировать новый секрет.
Алгоритм работы модели простой. Сначала отправляем запрос на получение токена. Затем делаем запрос к чату с имеющимся токенов. Ниже — пример, как реализован функционал в нашем боте:
const { gigaAuth } = require('./config')
const { v4: uuidv4 } = require('uuid')
const axios = require('axios')
const qs = require('qs')
// метод для получение токена
async function getToken() {
// конфиг запроса
const config = {
method: 'post',
maxBodyLength: Infinity,
url: '<https://ngw.devices.sberbank.ru:9443/api/v2/oauth>',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
RqUID: uuidv4(),
Authorization: `Basic ${gigaAuth}`,
},
data: qs.stringify({
scope: 'GIGACHAT_API_PERS'
}),
}
try {
const response = await axios(config)
const { access_token: accessToken, expires_at: expiresAt } = response.data
return { accessToken, expiresAt }
} catch (error) {
console.log(error)
}
}
// выполняем запрос к модели уже с токеном
async function giga(content = '', system = '') {
if (!content) return
// получаем токен
const token = await getToken()
const messages = []
// если передавали контекст, то добавляем его как системное сообщение.
// здесь мы говорим как чату себя вести
if (system) {
messages.push({ role: 'system', content: system })
}
// формируем данные для обращения
const data = JSON.stringify({
model: 'GigaChat',
messages: messages.concat([
{
role: 'user',
content,
},
]),
temperature: 1,
top_p: 0.1,
n: 1,
stream: false,
max_tokens: 512,
repetition_penalty: 1,
update_interval: 0,
})
// настраиваем запрос
const config = {
method: 'post',
maxBodyLength: Infinity,
url: '<https://gigachat.devices.sberbank.ru/api/v1/chat/completions>',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${token.accessToken}`,
},
data,
}
// выполняем запрос возвращая ответ самого чата
try {
const response = await axios(config)
const message = response.data.choices[0].message
return message.content
} catch (e) {
console.log(e)
}
}
module.exports = { giga }
giga.js.
Устанавливаем Telegraf, чтобы добавить интерфейс программы в Telegram-бот:
npm i telegraf
Далее получаем токен для @BotFather и создаем Telegram-бота. Вот пример финального файла функционала:
const { TelegramClient } = require('telegram')
const { Telegraf } = require('telegraf')
const { NewMessage } = require('telegram/events')
const { session, apiId, apiHash, botToken } = require('./config')
const { giga } = require('./giga')
// создаем бота
const bot = new Telegraf(botToken)
const client = new TelegramClient(session, apiId, apiHash)
async function getUnreadMessages(channelId, limit = 10) {
const dialogs = await client.getDialogs({})
const channel = dialogs.find((d) => d.entity.username === channelId)
if (channel) {
const messages = await client.getMessages(channel.entity, {
limit,
})
return messages.map((m) => m.message).join(' ')
} else {
console.log('Канал не найден')
}
}
;(async function run() {
await client.connect()
// слушаем команду sum
bot.command('sum', async (ctx) => {
// получаем как параметры ID-канала и сообщение для GPT
const [, channelId, ...task] = ctx.message.text.split(' ')
if (!channelId) {
return ctx.reply(`Вы не указали канал`)
}
// получаем строку из сообщений в канале
const messagesString = await getUnreadMessages(channelId, 10)
// передаем роль и сообщения из канала в GigaChat
const gigaResponse = await giga(messagesString, task.join(' '))
// отправляем пользователю ответ от GigaChat с анализом
await ctx.reply(gigaResponse)
})
bot.launch()
})()
Деплой
Чтобы Telegram-бот был всегда под рукой, задеплоим его в облако Selectel. Для этого переносим шаблон кода в Git:
git init
git add .
git commit -m “init”
git push -u origin master
Далее заходим в панель управления my.selectel.ru. Переходим из Облачной платформы в Серверы и нажимаем Создать сервер.
Далее настраиваем параметры сервера.
- Источник: Ubuntu 22.04 LTS 64-bit.
- Конфигурация: фиксированная, Shared.
- Доля vCPU: 20% (4 vCPU, 8 ГБ RAM).
После инициализации сервера нужно его настроить. Устанавливаем Git и загружаем репозиторий.
apt update
apt install git
git clone REPO_NAME
После устанавливаем Node.js и NPM через NVM. Подробнее об этом рассказывали в предыдущей статье.
Чтобы запустить программу, устанавливаем Node.js на Ubuntu 20.04:
nvm install 20
nvm use 20
cd REPO_NAME
npm install
Далее устанавливаем PM2 для работы бота в фоновом режиме:
npm install pm2 -g
pm2 start main
Готово. Теперь бот работает и вы можете анализировать Telegram-каналы и переписки!
Автор: Владилен Минин, создатель YouTube-канала.