Skip to content

Instantly share code, notes, and snippets.

@dwnste
Last active January 27, 2022 15:40
Show Gist options
  • Save dwnste/c4808faa99421071f83a4f77f64c26e5 to your computer and use it in GitHub Desktop.
Save dwnste/c4808faa99421071f83a4f77f64c26e5 to your computer and use it in GitHub Desktop.
// node ^16.4.2
/**
* npm i node-vk-sdk@1.1.7 node-fetch@2 --save
* GROUP_ACCESS_TOKEN=1234 WIT_AI_CLIENT_TOKEN=4567 GROUP_ID=1234 node wit_ai_vk_group_bot.js
*/
const {
VKApi,
ConsoleLogger,
BotsLongPollUpdatesProvider,
} = require("node-vk-sdk");
const fetch = require("node-fetch");
const WIT_AI_SPEECH_API_URL = "https://api.wit.ai/speech?v=20220126";
const NEW_MESSAGE_TYPE = "message_new";
const AUDIO_MESSAGE_TYPE = "audio_message";
const api = new VKApi({
// https://vk.com/{GROUP_ID}?act=tokens -> Create access token
// https://vk.com/{GROUP_ID}?act=longpoll_api -> API version 5.126 (for node-vk-sdk 1.1.7)
// optional:
// https://vk.com/{GROUP_ID}?act=messages&tab=bots -> "Bot abilities": Enabled, "Ability to add this community to chats" - checked
token: process.env.GROUP_ACCESS_TOKEN,
logger: new ConsoleLogger(),
});
const updatesProvider = new BotsLongPollUpdatesProvider(
api,
process.env.GROUP_ID
);
updatesProvider.getUpdates((updates) => {
if (!updates?.length) {
return;
}
updates.forEach((update) => {
if (update?.type !== NEW_MESSAGE_TYPE) {
return;
}
if (!update?.object?.message?.attachments?.length) {
return;
}
update.object.message.attachments.forEach(async (attachment) => {
if (attachment?.type !== AUDIO_MESSAGE_TYPE) {
return;
}
const link = attachment?.audio_message?.link_mp3;
if (!link) {
return;
}
let blob;
try {
blob = await fetch(link).then((response) => response.blob());
} catch (error) {
api.logger.error("", error);
}
if (!blob) {
return;
}
const response = await fetch(WIT_AI_SPEECH_API_URL, {
method: "POST",
headers: {
// https://wit.ai/apps -> "New app" -> "Client access token"
Authorization: `Bearer ${process.env.WIT_AI_CLIENT_TOKEN}`,
"Content-Type": "audio/mpeg3",
},
body: blob,
})
.then((response) => response.body)
.then(
(res) =>
new Promise((resolve) => {
const chunks = [];
res.on("readable", () => {
let chunk;
while (null !== (chunk = res.read())) {
chunks.push(chunk);
}
});
res.on("end", () => {
resolve(chunks[chunks.length - 1]);
});
})
)
.catch((error) => {
api.logger.log("", error);
});
try {
const message = JSON.parse(response.toString())?.text;
if (!message) {
return;
}
await api.messagesSend({
peer_id: update.object.message.peer_id,
reply_to: update.object.message.id,
message,
random_id: Math.random() * 9999,
});
} catch (error) {
api.logger.error("", error);
}
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment