Skip to main content

Quick Start

Get your first VK bot running in just a few minutes. This guide walks you through creating a simple bot that responds to user messages and commands.

Prerequisites

Before you begin, make sure you have:
  • Node.js 12.20.0+ installed
  • VK-IO installed (Installation Guide)
  • A VK Community token with message permissions (Get a token)
  • Long Poll API enabled in your community settings

Your First Bot

Let’s create a simple bot that responds to user messages.
1

Create your project

Create a new directory and initialize your project:
mkdir my-vk-bot
cd my-vk-bot
npm init -y
npm install vk-io
2

Add your token

Create a .env file with your VK token:
TOKEN=your_vk_community_token_here
Never commit your .env file to version control. Add it to .gitignore.
3

Create your bot file

Create bot.js (or bot.mjs for ESM) with the following code:
import { VK } from 'vk-io';

const vk = new VK({
  token: process.env.TOKEN
});

vk.updates.on('message_new', async (context) => {
  await context.send('Hello! You said: ' + context.text);
});

vk.updates.start().then(() => {
  console.log('Bot started!');
});
4

Run your bot

Start your bot:
TOKEN=your_token_here node bot.js
You should see “Bot started!” in the console. Send a message to your community, and the bot will echo it back!

Adding Commands

Let’s make the bot more interactive by adding command support using the @vk-io/hear package.
1

Install @vk-io/hear

npm install @vk-io/hear
2

Create a bot with commands

Update your bot.js:
import { VK } from 'vk-io';
import { HearManager } from '@vk-io/hear';

const vk = new VK({
  token: process.env.TOKEN
});

const hearManager = new HearManager();

// Connect the hear manager to updates
vk.updates.on('message_new', hearManager.middleware);

// Command: /start
hearManager.hear('/start', async (context) => {
  await context.send(`
    Welcome! 🎉
    
    Available commands:
    /start - Show this message
    /time - Get current time
    /cat - Get a random cat photo
    /reverse <text> - Reverse your text
  `);
});

// Command: /time or /date
hearManager.hear(['/time', '/date'], async (context) => {
  await context.send(String(new Date()));
});

// Command: /cat
hearManager.hear('/cat', async (context) => {
  await context.send('Loading your cat... 😺');
  
  await context.sendPhotos({
    value: 'https://loremflickr.com/400/300/cat'
  });
});

// Command: /reverse with regex
hearManager.hear(/^\/reverse (.+)/i, async (context) => {
  const text = context.$match[1];
  const reversed = text.split('').reverse().join('');
  
  await context.send(reversed);
});

// Default handler for unknown messages
vk.updates.on('message_new', async (context) => {
  await context.send('Unknown command. Type /start for help.');
});

vk.updates.start().then(() => {
  console.log('Bot started with commands!');
}).catch(console.error);
3

Test your commands

Run the bot and try these commands:
  • /start - Shows the help message
  • /time - Returns the current date and time
  • /cat - Sends a random cat photo
  • /reverse hello - Returns “olleh”

Adding a Keyboard

Make your bot even more user-friendly by adding interactive keyboards.
import { VK, Keyboard } from 'vk-io';
import { HearManager } from '@vk-io/hear';

const vk = new VK({
  token: process.env.TOKEN
});

const hearManager = new HearManager();

// Handle button payloads
vk.updates.on('message_new', (context, next) => {
  const { messagePayload } = context;
  
  // Set command from button payload
  context.state.command = messagePayload?.command || null;
  
  return next();
});

vk.updates.on('message_new', hearManager.middleware);

// Custom helper for commands that work with both text and buttons
const hearCommand = (name, conditions, handle) => {
  if (typeof handle !== 'function') {
    handle = conditions;
    conditions = [`/${name}`];
  }
  
  if (!Array.isArray(conditions)) {
    conditions = [conditions];
  }
  
  hearManager.hear(
    [(_text, { state }) => state.command === name, ...conditions],
    handle
  );
};

// /start command with keyboard
hearCommand('start', async (context) => {
  await context.send({
    message: `
      Welcome! 👋
      
      Use the buttons below or type commands:
      /help - Show help
      /time - Current time
      /cat - Random cat photo
    `,
    keyboard: Keyboard.builder()
      .textButton({
        label: 'Help',
        payload: { command: 'help' },
        color: Keyboard.SECONDARY_COLOR
      })
      .row()
      .textButton({
        label: 'Current Time',
        payload: { command: 'time' },
        color: Keyboard.PRIMARY_COLOR
      })
      .row()
      .textButton({
        label: 'Cat Photo 😺',
        payload: { command: 'cat' },
        color: Keyboard.POSITIVE_COLOR
      })
  });
});

hearCommand('help', async (context) => {
  await context.send('Type /start to see the menu!');
});

hearCommand('time', ['/time', '/date'], async (context) => {
  await context.send(`Current time: ${new Date().toLocaleString()}`);
});

hearCommand('cat', async (context) => {
  await context.send('Loading... 😺');
  
  await context.sendPhotos({
    value: 'https://loremflickr.com/400/300/cat'
  });
});

vk.updates.start().then(() => {
  console.log('Bot started with keyboard!');
}).catch(console.error);
Keyboards in VK can be persistent (always shown) or inline (one-time use). Use .inline() when building the keyboard for one-time buttons.

Understanding the Code

Let’s break down the key components:

VK Instance

const vk = new VK({
  token: process.env.TOKEN
});
The VK class is your main entry point. It provides three key properties:
  • vk.api - Make direct API calls to any VK method
  • vk.updates - Handle incoming events (messages, posts, etc.)
  • vk.upload - Upload photos, documents, and other files

Updates & Events

vk.updates.on('message_new', async (context) => {
  // Handle new messages
});

vk.updates.start();
The updates module listens for events from VK using Long Poll API. Common events:
  • message_new - New message received
  • message_reply - Message reply from community
  • wall_post_new - New wall post
  • group_join - User joined the community

Message Context

The context object provides everything you need to interact with messages:
context.text        // Message text
context.senderId    // User who sent the message
context.peerId      // Chat or user ID
context.send()      // Send a message
context.reply()     // Reply to the message
context.sendPhotos() // Send photos
context.messagePayload // Button payload data

Keyboard Builder

Keyboard.builder()
  .textButton({ label: 'Click me', payload: { action: 'click' } })
  .row()  // Start a new row
  .textButton({ label: 'Another button', color: Keyboard.PRIMARY_COLOR })
Keyboard colors:
  • Keyboard.PRIMARY_COLOR - Blue (main action)
  • Keyboard.SECONDARY_COLOR - White (secondary action)
  • Keyboard.POSITIVE_COLOR - Green (confirm, agree)
  • Keyboard.NEGATIVE_COLOR - Red (delete, reject)

Making API Calls

You can call any VK API method directly:
// Get user information
const users = await vk.api.users.get({
  user_ids: [1, 2, 3],
  fields: ['photo_100', 'city']
});

// Post to wall
await vk.api.wall.post({
  owner_id: -123456, // Your community ID (negative for communities)
  message: 'Hello from VK-IO!',
  attachments: 'photo-123456_789'
});

// Send a message
await vk.api.messages.send({
  peer_id: 123456,
  message: 'Hello!',
  random_id: 0
});
VK-IO automatically handles rate limits and request parallelization for you. Make as many API calls as you need!

Next Steps

You now have a working VK bot! Here’s what to explore next:

Updates Guide

Learn about all available events and how to handle them

Keyboard Guide

Master keyboard creation with buttons and layouts

Uploads

Upload photos, documents, audio, and videos

Sessions & Scenes

Build conversational flows with state management

API Reference

Explore the complete API documentation

Examples

See real-world bot implementations

Common Issues

Make sure:
  • Long Poll API is enabled in your community settings
  • Messages are enabled for the community
  • Your token has the messages permission
  • The bot is running without errors (console.log the context to debug)
Your environment variable isn’t set. Either:
  • Use TOKEN=your_token node bot.js when running
  • Or install dotenv and load it: require('dotenv').config()
Keyboards only appear in private messages and community chats. Make sure:
  • You’re testing in a private message to your community
  • The keyboard is properly built with .builder()
  • You’re passing it in the options: { keyboard: Keyboard.builder()... }
Check that:
  • The URL is publicly accessible
  • You’re using context.sendPhotos() or context.sendDocuments()
  • Your token has the necessary permissions
  • The file format is supported (JPG, PNG, GIF for photos)
Need help? Check out the examples directory for more real-world code samples!

Build docs developers (and LLMs) love