Как отправить сообщение через API ВК на Node.js Редактировано: 28.08.2020 в 04:45
Структура статьи
- Знакомство с методом messages.send
- Отправка сообщения от лица пользователя
- Отправка сообщения от лица сообщества
- Отправка сообщения в беседу
- Отправка сообщения в беседу от имени сообщества
- Как отправлять сообщение от имени сообщества после приглашения в беседу
- Как отправить стикер
- Отправляем стикер в виде граффити
- Как отправить голосовое сообщение
- Как отправить изображение
Знакомство с методом messages.send
Если вы уже знакомы с тем, как использовать API ВКонтакте, то скорее всего вы захотели сделать первый шаг в работе с ним. Лично я начал свое погружение в VK API именно с секции сообщений. Сначала это была просто тестовая отправка сообщения.
И так, для того, чтобы отправлять сообщения, в VK API есть метод messages.send
Минимальные параметры для отправки
- peer_id - ID отправителя: беседа, или человек, или сообщество
- message - Текст сообщения, если не указан параметр attachment или sticker_id
- attachment - Массив с прикреплениями (точнее, строка, разделяющая прикрепления через запятую)
- sticker_id - ID стикера
- random_id - Случайное число, для предотвращения дубликатов сообщений. Для простоты генерации, привязывайте его к текущей дате
Чтобы обращаться к VK API на Node.js, я всегда использую модуль easyvk. Есть и другие варианты, например, vk-io или node-vk-bot-api. Что использовать, решать вам. Но писать статьи я решил с примерами использования easyvk, так как эта библиотека мне знакома больше, чем любая другая, хотябы потому что я ее автор :)
На сайте-документации модуля написано подробно о том, как его установить и использовать.
Примеры
Чтобы эта и другие мои статьи о VK API не получились как все типичные статьи из интернета, я буду меньше говорить, и больше показывать.
Отправка сообщения от лица пользователя
Чтобы отправить сообщение от лица пользователя, вам понадобится:
- Токен пользователя
- Доступ к секции messages
Хотелось бы напомнить, что Messages API официально закрыт для аккаунтов ВКонтакте, но это не значит, что им нельзя пользоваться. В библиотеке easyvk, для получения доступа, авторизация происходит по данным официальных клиентов ВКонтакте (Приложение для Android, например), которые уже имеют доступ к секции Messages API. Вам почти ничего не надо делать для успешной отправки первого сообщения.
Теперь сам пример
const easyvk = require('easyvk') // Подключаем easyvk
easyvk({ /** Авторизуемся */
username: 'ВАШ_ЛОГИН',
password: 'ВАШ_ПАРОЛЬ'
}).then(async (vk) => {
/** Отправляем сообщение */
let response = await vk.call('messages.send', {
/** Отправляем самому себе */
peer_id: vk.session.user_id,
message: "Привет!",
/** Получаем случайное число с привязкой к дате*/
random_id: easyvk.randomId()
})
console.log(response) // Выводим ID отправленного сообщения
})
Если все получилось, вам придет сообщение с текстом Привет!
Отправка сообщения от лица сообщества
Чтобы отправить сообщение от лица сообщества, вам понадобится:
- Токен сообщества
- Доступ к секции messages
- Доступ к диалогку с пользователем, которому хотите отправить сообщение
Как получить токен сообщества самым простым методом, я описал в этой статье
Чтобы получить доступ к диалогу с пользователем, он должен отправить вам любое сообщение
Параметры все те же.
const easyvk = require('easyvk')
easyvk({
token: 'ВАШ ТОКЕН СООБЩЕСТВА'
}).then(async vk => {
let peerId = 1 // ID получателя
/** Отправляем сообщение */
let response = await vk.call('messages.send', {
peer_id: peerId,
message: "Привет!",
/** Получаем случайное число с привязкой к дате*/
random_id: easyvk.randomId()
})
console.log(response) // Выводим ID отправленного сообщения
})
Если все получилось, сообщество отправило сообщение с текстом Привет!
Отправка сообщения в беседу
Для отправки сообщения в беседу в параметре peer_id нужно указать число 2000000000 + ID беседы
. ID беседы вы можете получить любым удобным способом: через метод messages.getConversations или по ссылке ВКонтакте
const easyvk = require('easyvk') // Подключаем easyvk
easyvk({
username: 'ВАШ_ЛОГИН',
password: 'ВАШ_ПАРОЛЬ'
}).then(async vk => {
/** Получаем список бесед */
let conversations = await vk.call('messages.getConversations')
conversations = conversations.items.filter(a =>
a.conversation && a.conversation.peer.type === "chat"
)
if (conversations.length) {
let response = await vk.call('messages.send', {
peer_id: conversations[0].conversation.peer.id,
message: "Всем привет!"
})
console.log(response)
}
})
Отправка сообщения в беседу от имени сообщества
Чтобы сообщество могло отправлять сообщения в беседу, сначала необходимо это сообщество пригласить в эту самую беседу. Для этого в настройках сообщества надо включить возможности для чат-ботов и открыть специальный сервис для приглашений.
Сервис можно будет найти в меню сообщества
Пишем код
const easyvk = require('easyvk') // Подключаем easyvk
easyvk({
token: 'ТОКЕН СООБЩЕСТВА'
}).then(async vk => {
let response = await vk.call('messages.send', {
/**
ID беседы для сообщества.
Как его получить, читайте ниже
*/
peer_id: 2000000009,
message: "Всем привет!"
})
console.log(response) // Всегда 0
})
Как отправлять сообщение от имени сообщества после приглашения в беседу
Это мы уже переходим к разработке мини-чат-бота. Но, конечно, это не он.
Сначала включаем Bots LongPoll (пример будет описан на нем, так как его сможет запустить каждый желающий, позже я буду показывать примеры создания чат-ботов с помощью Callback API тоже)
Для этого заходим в настройки сообщества. И включаем все, что касается LongPoll. А именно:
Мы будем отправлять сообщение сразу после того, как сообщество пригласили в беседу. Включим поддержку события входящего сообщения в настройках, так как информация о приглашении придет именно как сообщение.
Теперь подключим Bots LongPoll в easyvk. Не забываем, что приглашение - это обычное входящее сообщение.
const easyvk = require('easyvk')
easyvk({
token: 'ТОКЕН СООБЩЕСТВА',
reauth: true,
v: '5.103' // Обязательно используем новейшую версию ВКонтакте
}).then(async vk => {
/** Подключаемся к LongPoll */
let connection = await vk.bots.longpoll.connect();
/** Выставляем прослушивание сообщений */
connection.on("message_new", async (msg) => {
/** Проверяем, что это приглашение в беседу */
if (
msg.message &&
msg.message.action &&
msg.message.action.type === "chat_invite_user" &&
/** Проверка, что пригласили именно наше сообщество */
msg.message.action.member_id === -vk.session.group_id) {
/** Отправляем приветственное сообщение */
let res = await sendHelloMessage(msg.message.peer_id)
console.log(res) // Всегда 0
}
})
async function sendHelloMessage (peerId) {
return vk.call('messages.send', {
peer_id: peerId,
random_id: easyvk.randomId(),
message: "Всем привет!"
})
}
})
Теперь сообщество будет кидать всем беседам приветственное сообщение сразу после приглашения.
Отправка стикера
ВКонтакте позволяет отправлять стикеры в сообщениях. Честно говоря, мне доводилось только один раз прибегать к отправке стикера. Это было, когда я писал чат-бота для глобальных бесед. Там надо было как-то реализовать пересылку любого стикера, который бы отправил пользователь. По-моему, у меня не получилось. Точнее, это работало только с бесплатными стикерами. Самое время разобраться в этом вопросе поглубже.
Все тот же messages.send
easyvk({
username: 'ВАШ_ЛОГИН',
password: 'ВАШ_ПАРОЛЬ'
}).then(async vk => {
/** Получаем недавно использованные стикеры */
let response = await vk.call('messages.getRecentStickers')
let recentStickers = response.items;
/** Отправляем самому себе стикер */
await vk.call('messages.send', {
peer_id: vk.session.user_id,
sticker_id: recentStickers[0].sticker_id,
random_id: easyvk.randomId()
})
})
Если все получилось, то стикер отправился.
Отправка стикера как граффити
Да-да. И такое бывает. Особенно в последнее время. На сколько мне известно, на данный момент ВКонтакте хранит у себя на серверах 19к стикеров (там почти 20). И все они очень разные, прикольные. Некоторые уже нигде не найти. Но они все равно хранятся. Как в общем-то и любая другая информация в ВК. И это если не считать кастомных стикеров, которые люди загружают как граффити. Разберемся, как они это делают.
Граффити - это обычный документ, загруженный как png изображение. В ВК граффити отображается почти также, как стикер. В некоторых местах, разве что, он бывает в разы больше стикера. А значит и загружать мы его будем как документ.
Для примера возьмем вот такой прикольный стикер https://vk.com/sticker/1-5041-352
Воспользуемся компонентом uploader
для загрузки файла.
easyvk({
username: 'ВАШ_ЛОГИН',
password: 'ВАШ_ПАРОЛЬ'
}).then(async vk => {
let {graffiti} = await vk.uploader.upload({
getUrlMethod: 'docs.getUploadServer', // Метод получения URL
getUrlParams: {
type: 'graffiti' // Отправляем как граффити
},
file: 'https://vk.com/sticker/1-162-256', // Что загружаем
isWeb: true, // Просим скачать файл с удаленного сервера
saveMethod: 'docs.save' // Сохраняем этим методом
})
/** Отправляем самому себе */
await vk.call('messages.send', {
peer_id: vk.session.user_id,
attachment: `graffiti${graffiti.owner_id}_${graffiti.id}`,
random_id: easyvk.randomId()
})
})
Вот есть еще такие стикосы
Отправка голосового сообщения
Происходит таким же образом, как и отправка любого документа.
Чтобы отправить голосовое сообщене, вам необходимо его записать в формате Ogg Opus (.ogg). Вы можете записать его в любом другом формате, а затем воспользоваться ffmpeg
для форматирования его уже в .ogg, но главное, чтобы в итоге у вас получился файл ogg
!
ffmpeg -i audio.wav -acodec libvorbis audio.ogg
Если вам интересна тема работы с аудио и тем, как я сделал наложение эффектов на голосовое сообщение (реверберация, дисторшн и другие), то можете почитать эту статью
А пока что я покажу простейший пример отправки голосового сообщения
const easyvk = require('easyvk')
easyvk({
username: 'ВАШ_ЛОГИН',
password: 'ВАШ_ПАРОЛЬ'
}).then(async vk => {
let peerId = vk.session.user_id
let fileName = 'file.ogg'
/** Получаем URL для загрузки */
let {upload_url: uploadUrl} = await vk.call('docs.getMessagesUploadServer', {
peer_id: peerId,
type: "audio_message"
})
/** Загружаем файл */
let file = await vk.uploader.uploadFile(uploadUrl, fileName)
let doc = await vk.post('docs.save', file)
doc = doc.audio_message;
await vk.call('messages.send', {
peer_id: peerId,
/** Прикрепляем файл как обычный документ */
attachment: `doc${doc.owner_id}_${doc.id}_${doc.access_key}`,
random_id: easyvk.randomId()
})
})
Кстати говоря, отправка аудио сообщений работает и для сообществ! Просто используйте access_token
сообщества для настройки под вас.
Отправляем изображение
Вообще, есть два варианта отправки изображения.
- Изображение с жесткого диска
- Изображение с удаленного сервера (по URL)
Оба способа поддерживаются в easyvk, поэтому я покажу оба варианта загрузки.
Возьмем какую-нибудь забугорную картинку, почему - не знаю. Просто так. Загрузим ее куда-нибудь в личные сообщения.
Для загрузки файла с другого сервера в easyvk есть метод vk.uploader.uploadFetchedFile()
Для загрузки файла с жесткого диска в easyvk есть метод vk.uploader.uploadFile()
Напишем код
const easyvk = require('easyvk')
easyvk({
username: 'ВАШ_ЛОГИН',
password: 'ВАШ_ПАРОЛЬ'
}).then(async vk => {
let peerId = vk.session.user_id
let fileName = 'https://i.imgur.com/PXajpyw.jpg'
/** Локальная картинка */
let localFileName = './img.png'
/** Получаем URL для загрузки */
let {upload_url: uploadUrl} = await vk.call('photos.getMessagesUploadServer', {
peer_id: peerId
})
/** Загружаем файл (url, file, field - photo, как в документации) */
let file = await vk.uploader.uploadFetchedFile(uploadUrl, fileName, 'photo')
let localFile = await vk.uploader.uploadFile(uploadUrl, localFileName, 'photo')
/** Сохряняем оба изображения */
let photo = await vk.post('photos.saveMessagesPhoto', file)
let localPhoto = await vk.post('photos.saveMessagesPhoto', localFile)
photo = photo[0]
localPhoto = localPhoto[0]
/** Отправляем сообщение */
await vk.call('messages.send', {
peer_id: peerId,
/** Прикрепляем файл как обычный документ */
attachment: [
`photo${photo.owner_id}_${photo.id}_${photo.access_key}`,
`photo${localPhoto.owner_id}_${localPhoto.id}_${localPhoto.access_key}`
],
random_id: easyvk.randomId()
})
})
На этом все! Спасибо, что дочитали до конца. Надеюсь, что эта статья вам хоть чем-то помогла и вы научились чему-то новому :)
Ссылки
Комментарии к статье