### Basic VK-IO Hear Usage Example Source: https://github.com/negezor/vk-io/blob/master/packages/hear/README.md Set up a VK bot with VK-IO Hear to listen for messages. This example demonstrates how to initialize the VK instance, the HearManager, and register a listener for messages starting with 'hello'. ```javascript import { VK, MessageContext } from 'vk-io'; import { HearManager } from '@vk-io/hear'; const vk = new VK({ token: process.env.TOKEN }); const hearManager = new HearManager(); vk.updates.on('message_new', hearManager.middleware); hearManager.hear(/^hello$/, async (context) => { await context.send('Hello!'); }); vk.updates.start().catch(console.error); ``` -------------------------------- ### VK API Users Get Example Source: https://github.com/negezor/vk-io/blob/master/packages/vk-io/README.md Demonstrates how to call the users.get method of the VK API. ```javascript vk.api.users.get({...}) ``` -------------------------------- ### Install @vk-io/stateless-prompt Source: https://context7.com/negezor/vk-io/llms.txt Install the stateless prompt module using npm. ```bash npm install @vk-io/stateless-prompt ``` -------------------------------- ### Install @vk-io/streaming Source: https://context7.com/negezor/vk-io/llms.txt Install the package for connecting to VK's Streaming API. ```bash npm install @vk-io/streaming ``` -------------------------------- ### Install @vk-io/authorization Source: https://context7.com/negezor/vk-io/llms.txt Install the package for direct login and password authorization. ```bash npm install @vk-io/authorization ``` -------------------------------- ### Install @vk-io/scenes and @vk-io/session Source: https://context7.com/negezor/vk-io/llms.txt Install the necessary packages for multi-step conversation flows and session management. ```bash npm install @vk-io/scenes @vk-io/session ``` -------------------------------- ### Initialize and use Streaming API Source: https://github.com/negezor/vk-io/blob/master/packages/streaming/README.md Initialize the VK instance and StreamingAPI, then start the WebSocket connection and add a rule for receiving publications. This example listens for 'publication' events and logs the context. ```javascript import { VK } from 'vk-io'; import { StreamingAPI } from '@vk-io/streaming'; const vk = new VK({ token: process.env.TOKEN }); const streaming = new StreamingAPI({ api: vk.api, updates: vk.updates }); vk.updates.on('publication', (context) => { console.log('Streaming context', context); }); async function run() { await streaming.startWebSocket(); await streaming.addRule({ tag: 'halloween', value: 'тыква' }); } run().catch(console.error); ``` -------------------------------- ### Install @vk-io/stateless-prompt with npm Source: https://github.com/negezor/vk-io/blob/master/packages/stateless-prompt/README.md Use this command to install the package using npm. Node.js 12.20.0 or newer is required. ```shell npm i @vk-io/stateless-prompt ``` -------------------------------- ### Install @vk-io/session with Yarn Source: https://github.com/negezor/vk-io/blob/master/packages/session/README.md Use this command to install the session package using Yarn. ```shell yarn add @vk-io/session ``` -------------------------------- ### Install VK-IO Core Package Source: https://context7.com/negezor/vk-io/llms.txt Install the core vk-io package using npm, Yarn, or pnpm. ```bash # npm npm install vk-io # Yarn yarn add vk-io # pnpm pnpm add vk-io ``` -------------------------------- ### Install @vk-io/session with npm Source: https://github.com/negezor/vk-io/blob/master/packages/session/README.md Use this command to install the session package using npm. ```shell npm i @vk-io/session ``` -------------------------------- ### Install @vk-io/session with pnpm Source: https://github.com/negezor/vk-io/blob/master/packages/session/README.md Use this command to install the session package using pnpm. ```shell pnpm add @vk-io/session ``` -------------------------------- ### Install @vk-io/stateless-prompt with Yarn Source: https://github.com/negezor/vk-io/blob/master/packages/stateless-prompt/README.md Use this command to install the package using Yarn. Node.js 12.20.0 or newer is required. ```shell yarn add @vk-io/stateless-prompt ``` -------------------------------- ### Install @vk-io/stateless-prompt with pnpm Source: https://github.com/negezor/vk-io/blob/master/packages/stateless-prompt/README.md Use this command to install the package using pnpm. Node.js 12.20.0 or newer is required. ```shell pnpm add @vk-io/stateless-prompt ``` -------------------------------- ### Basic Stateless Prompt Usage Example Source: https://github.com/negezor/vk-io/blob/master/packages/stateless-prompt/README.md This example demonstrates how to set up a stateless prompt for collecting user names. It initializes the VK bot, configures a prompt manager for 'name' slugs, and uses middleware to intercept messages. When a user types '/signup', the bot asks for their name and appends the prompt suffix. User replies containing the suffix are handled by the prompt manager. ```javascript import { VK } from 'vk-io'; import { StatelessPromptManager } from '@vk-io/stateless-prompt'; const vk = new VK({ token: process.env.TOKEN }); const namePrompt = new StatelessPromptManager({ slug: 'name', handler: (context, next) => { if (!context.text) { return context.send('Please reply your name with text to previous message'); } return context.send(`Your name is ${context.text}`); } }); vk.updates.on('message_new', namePrompt.middlewareIntercept); vk.updates.on('message_new', (context, next) => { if (context.text === '/signup') { return context.send('What\'s your name? Please reply to this message. ' + namePrompt.suffix); } return next(); }); vk.updates.start().catch(console.error); ``` -------------------------------- ### Install VK-IO Hear with pnpm Source: https://github.com/negezor/vk-io/blob/master/packages/hear/README.md Install the VK-IO Hear package using pnpm. Node.js 12.20.0 or newer is required. ```shell pnpm add @vk-io/hear ``` -------------------------------- ### Install VK-IO Hear with Yarn Source: https://github.com/negezor/vk-io/blob/master/packages/hear/README.md Install the VK-IO Hear package using Yarn. Node.js 12.20.0 or newer is required. ```shell yarn add @vk-io/hear ``` -------------------------------- ### VK-IO Scenes Example Usage Source: https://github.com/negezor/vk-io/blob/master/packages/scenes/README.md This example demonstrates how to integrate VK-IO Scenes with VK-IO and SessionManager for managing conversational flows. It includes setting up middleware, defining a multi-step signup scene, and handling user input within scenes. ```javascript import { VK } from 'vk-io'; // Session implementation can be any import { SessionManager } from '@vk-io/session'; import { SceneManager, StepScene } from '@vk-io/scenes'; const vk = new VK({ token: process.env.TOKEN }); const sessionManager = new SessionManager(); const sceneManager = new SceneManager(); vk.updates.on('message_new', sessionManager.middleware); vk.updates.on('message_new', sceneManager.middleware); vk.updates.on('message_new', sceneManager.middlewareIntercept); // Default scene entry handler vk.updates.on('message_new', (context, next) => { if (context.text === '/signup') { return context.scene.enter('signup'); } return next(); }); sceneManager.addScenes([ new StepScene('signup', [ (context) => { if (context.scene.step.firstTime || !context.text) { return context.send('What\'s your name?'); } context.scene.state.firstName = context.text; return context.scene.step.next(); }, (context) => { if (context.scene.step.firstTime || !context.text) { return context.send('How old are you?'); } context.scene.state.age = Number(context.text); return context.scene.step.next(); }, async (context) => { const { firstName, age } = context.scene.state; await context.send(`👤 ${firstName} ${age} ages`); return context.scene.step.next(); // Automatic exit, since this is the last scene } ]) ]); vk.updates.start().catch(console.error); ``` -------------------------------- ### VK API Method Example Source: https://github.com/negezor/vk-io/blob/master/README.md Illustrates a direct mapping to a VK API method for fetching user data. ```javascript vk.api.users.get({ ... }); ``` -------------------------------- ### Install VK-IO Authorization with npm Source: https://github.com/negezor/vk-io/blob/master/packages/authorization/README.md Install the VK-IO Authorization module using npm. Node.js 12.20.0 or newer is required. ```shell npm i @vk-io/authorization ``` -------------------------------- ### Install VK-IO Hear with npm Source: https://github.com/negezor/vk-io/blob/master/packages/hear/README.md Install the VK-IO Hear package using npm. Node.js 12.20.0 or newer is required. ```shell npm i @vk-io/hear ``` -------------------------------- ### Install @vk-io/streaming Source: https://github.com/negezor/vk-io/blob/master/packages/streaming/README.md Install the VK-IO Streaming module using npm, Yarn, or pnpm. Node.js 12.20.0 or newer is required. ```shell npm i @vk-io/streaming ``` ```shell yarn add @vk-io/streaming ``` ```shell pnpm add @vk-io/streaming ``` -------------------------------- ### Install vk-io with pnpm Source: https://github.com/negezor/vk-io/blob/master/README.md Use this command to install the vk-io package using pnpm. Node.js 12.20.0 or newer is required. ```shell pnpm add vk-io ``` -------------------------------- ### Example Usage of VK-IO Session Source: https://github.com/negezor/vk-io/blob/master/packages/session/README.md This example demonstrates how to integrate the SessionManager into a VK-IO bot to handle user messages and manage session data, such as a counter. ```javascript import { VK } from 'vk-io'; import { SessionManager } from '@vk-io/session'; const vk = new VK({ token: process.env.TOKEN }); const sessionManager = new SessionManager(); vk.updates.on('message_new', sessionManager.middleware); vk.updates.on('message_new', async (context, next) => { if (context.text !== '/counter') { return next(); } const { session } = context; if (!session.counter) { session.counter = 0; } session.counter += 1; await context.send(`You turned to the bot (${session.counter}) times`); }); vk.updates.start().catch(console.error); ``` -------------------------------- ### Install vk-io with Yarn Source: https://github.com/negezor/vk-io/blob/master/README.md Use this command to install the vk-io package using Yarn. Node.js 12.20.0 or newer is required. ```shell yarn add vk-io ``` -------------------------------- ### Install @vk-io/scenes with npm Source: https://github.com/negezor/vk-io/blob/master/packages/scenes/README.md Use this command to add the @vk-io/scenes package to your project using npm. ```shell npm i @vk-io/scenes ``` -------------------------------- ### Install vk-io with npm Source: https://github.com/negezor/vk-io/blob/master/README.md Use this command to install the vk-io package using npm. Node.js 12.20.0 or newer is required. ```shell npm i vk-io ``` -------------------------------- ### Install VK-IO Authorization with pnpm Source: https://github.com/negezor/vk-io/blob/master/packages/authorization/README.md Install the VK-IO Authorization module using pnpm. Node.js 12.20.0 or newer is required. ```shell pnpm add @vk-io/authorization ``` -------------------------------- ### Implement Stateless Prompt for User Input Source: https://context7.com/negezor/vk-io/llms.txt This example demonstrates how to create a stateless prompt to ask for user input, such as a name. Ensure the prompt middleware is registered before general message handlers. The prompt suffix is automatically appended to the bot's message to detect replies. ```typescript import { VK } from 'vk-io'; import { StatelessPromptManager } from '@vk-io/stateless-prompt'; const vk = new VK({ token: process.env.TOKEN }); const namePrompt = new StatelessPromptManager({ slug: 'get-name', handler: async (context, next) => { if (!context.text) { return context.send('Please reply with text.'); } await context.send(`Your name is: ${context.text}`); } }); // Must come before general message handlers vk.updates.on('message_new', namePrompt.middlewareIntercept); vk.updates.on('message_new', (context, next) => { if (context.text === '/signup') { // namePrompt.suffix is appended so replies are detected return context.send(`What's your name? Reply to this message. ${namePrompt.suffix}`); } return next(); }); vk.updates.start().catch(console.error); ``` -------------------------------- ### Direct Authorization Example Source: https://github.com/negezor/vk-io/blob/master/packages/authorization/README.md Example of using DirectAuthorization for obtaining a token. Ensure you have the necessary credentials and environment variables set for login, password, client ID, and client secret. This method is only available for official applications. ```javascript import { CallbackService } from 'vk-io'; import { DirectAuthorization, officialAppCredentials } from '@vk-io/authorization'; const callbackService = new CallbackService(); const direct = new DirectAuthorization({ callbackService, scope: 'all', // Direct authorization is only available for official applications ...officialAppCredentials.android, // { clientId: string; clientSecret: string; } // Or manually provide app credentials // clientId: process.env.CLIENT_ID, // clientSecret: process.env.CLIENT_SECRET, login: process.env.LOGIN, password: process.env.PASSWORD, apiVersion: '5.199' }); async function run() { const response = await direct.run(); console.log('Token:', response.token); console.log('Expires:', response.expires); console.log('Email:', response.email); console.log('User ID:', response.userId); } run().catch(console.error); ``` -------------------------------- ### Install @vk-io/scenes with pnpm Source: https://github.com/negezor/vk-io/blob/master/packages/scenes/README.md Use this command to add the @vk-io/scenes package to your project using pnpm. ```shell pnpm add @vk-io/scenes ``` -------------------------------- ### Install VK-IO Authorization with Yarn Source: https://github.com/negezor/vk-io/blob/master/packages/authorization/README.md Install the VK-IO Authorization module using Yarn. Node.js 12.20.0 or newer is required. ```shell yarn add @vk-io/authorization ``` -------------------------------- ### Install @vk-io/scenes with Yarn Source: https://github.com/negezor/vk-io/blob/master/packages/scenes/README.md Use this command to add the @vk-io/scenes package to your project using Yarn. ```shell yarn add @vk-io/scenes ``` -------------------------------- ### Per-User Session Storage with SessionManager Source: https://context7.com/negezor/vk-io/llms.txt SessionManager adds a persistent `session` object to each message context. It defaults to an in-memory store but can be configured with custom storage like Redis. The example demonstrates incrementing a counter stored in the session. ```bash npm install @vk-io/session ``` ```typescript import { VK } from 'vk-io'; import { SessionManager } from '@vk-io/session'; const vk = new VK({ token: process.env.TOKEN }); // Custom storage adapter (optional — defaults to in-memory Map) const sessionManager = new SessionManager({ storage: myRedisStorage // must implement get/set/delete }); vk.updates.on('message_new', sessionManager.middleware); vk.updates.on('message_new', async (context, next) => { if (context.text !== '/counter') { return next(); } const { session } = context; session.counter = (session.counter ?? 0) + 1; await context.send(`You have called /counter ${session.counter} time(s)`); }); vk.updates.start().catch(console.error); ``` -------------------------------- ### Basic VK API Call with vk-io Source: https://github.com/negezor/vk-io/blob/master/README.md This snippet demonstrates how to initialize the VK class with a token and make a basic API call to fetch wall posts. Ensure your VK API token is set in the environment variable `TOKEN`. ```javascript import { VK } from 'vk-io'; const vk = new VK({ token: process.env.TOKEN }); async function run() { const response = await vk.api.wall.get({ owner_id: 1 }); console.log(response); } run().catch(console.log); ``` -------------------------------- ### Initialize VK Facade Class Source: https://context7.com/negezor/vk-io/llms.txt Initialize the VK facade class with a token to access API, upload, and updates sub-modules. Listen for new messages and send replies. ```typescript import { VK } from 'vk-io'; const vk = new VK({ token: process.env.TOKEN // group, user, or service token }); // Access sub-modules directly async function run() { // Call any API method const users = await vk.api.users.get({ user_ids: 1 }); console.log(users); // => [{ id: 1, first_name: 'Pavel', last_name: 'Durov' }] // Listen for incoming messages vk.updates.on('message_new', async (context) => { if (context.text === 'Hello') { await context.send('Hello!'); } }); await vk.updates.start(); } run().catch(console.error); ``` -------------------------------- ### VK Facade Class Source: https://context7.com/negezor/vk-io/llms.txt The VK facade class is the recommended entry point for most applications, bundling api, upload, and updates sub-modules. ```APIDOC ## VK Facade Class ### Description The `VK` class is the top-level convenience class that bundles `api`, `upload`, and `updates` sub-modules under a single instance, making it the recommended entry point for most applications. ### Usage ```typescript import { VK } from 'vk-io'; const vk = new VK({ token: process.env.TOKEN // group, user, or service token }); // Access sub-modules directly async function run() { // Call any API method const users = await vk.api.users.get({ user_ids: 1 }); console.log(users); // => [{ id: 1, first_name: 'Pavel', last_name: 'Durov' }] // Listen for incoming messages vk.updates.on('message_new', async (context) => { if (context.text === 'Hello') { await context.send('Hello!'); } }); await vk.updates.start(); } run().catch(console.error); ``` ``` -------------------------------- ### Implement Multi-Step Conversations with SceneManager Source: https://context7.com/negezor/vk-io/llms.txt Set up VK bot with session and scene management. Handles incoming messages and routes them to the appropriate scene. Requires session middleware. ```typescript import { VK } from 'vk-io'; import { SessionManager } from '@vk-io/session'; import { SceneManager, StepScene } from '@vk-io/scenes'; const vk = new VK({ token: process.env.TOKEN }); const sessionManager = new SessionManager(); const sceneManager = new SceneManager(); vk.updates.on('message_new', sessionManager.middleware); vk.updates.on('message_new', sceneManager.middleware); vk.updates.on('message_new', sceneManager.middlewareIntercept); // handles active scene routing // Entry point vk.updates.on('message_new', (context, next) => { if (context.text === '/signup') { return context.scene.enter('signup'); } return next(); }); // Define a step-based scene sceneManager.addScenes([ new StepScene('signup', [ // Step 0: ask name (context) => { if (context.scene.step.firstTime || !context.text) { return context.send("What's your name?"); } context.scene.state.firstName = context.text; return context.scene.step.next(); }, // Step 1: ask age (context) => { if (context.scene.step.firstTime || !context.text) { return context.send('How old are you?'); } context.scene.state.age = Number(context.text); return context.scene.step.next(); }, // Step 2: confirm and exit async (context) => { const { firstName, age } = context.scene.state; await context.send(`Registered: ${firstName}, ${age} years old.`); return context.scene.step.next(); // last step → auto-exits scene } ]) ]); vk.updates.start().catch(console.error); ``` -------------------------------- ### Build VK Keyboards with Keyboard Builder Source: https://context7.com/negezor/vk-io/llms.txt Use the Keyboard builder pattern for a fluent way to construct keyboards with various button types. Supports chaining and row separation. Use .oneTime() to hide the keyboard after the first interaction. ```typescript import { VK, Keyboard } from 'vk-io'; const vk = new VK({ token: process.env.TOKEN }); // --- Builder pattern (recommended) --- const builder = Keyboard.builder() .textButton({ label: 'Go back', payload: { command: 'back' } }) .row() .textButton({ label: 'Buy a tea', payload: { command: 'buy', item: 'tea' }, color: Keyboard.POSITIVE_COLOR // green }) .textButton({ label: 'Buy a coffee', payload: { command: 'buy', item: 'coffee' }, color: Keyboard.POSITIVE_COLOR }) .row() .urlButton({ label: 'Visit store', url: 'https://coffee.mania/buy' }) .row() .callbackButton({ label: 'Inline action', payload: { command: 'inline_action' } }) .row() .textButton({ label: 'Cancel', payload: { command: 'cancel' }, color: Keyboard.NEGATIVE_COLOR // red }) .oneTime(); // hide after first press await vk.api.messages.send({ peer_id: 12345678, message: 'Choose an option:', keyboard: builder, random_id: 0 }); ``` -------------------------------- ### HearManager Source: https://context7.com/negezor/vk-io/llms.txt Adds command/pattern routing on top of Updates, similar to router middleware. ```APIDOC ## @vk-io/hear — Pattern-Based Message Routing `HearManager` adds command/pattern routing on top of `Updates`, similar to a router middleware. ```bash npm install @vk-io/hear ``` ```typescript import { VK, MessageContext } from 'vk-io'; import { HearManager } from '@vk-io/hear'; const vk = new VK({ token: process.env.TOKEN }); const hearManager = new HearManager(); vk.updates.on('message_new', hearManager.middleware); // Match exact string hearManager.hear('/start', async (context) => { await context.send('Welcome! Use /help for commands.'); }); // Match multiple strings hearManager.hear(['/time', '/date'], async (context) => { await context.send(String(new Date())); }); // Match regular expression — capture groups available via context.$match hearManager.hear(/^\/reverse (.+)/i, async (context) => { const reversed = context.$match[1].split('').reverse().join(''); await context.send(reversed); }); // Match by payload command (keyboard button press) hearManager.hear( [(_text, ctx) => ctx.state.command === 'cat'], async (context) => { await context.sendPhotos({ value: 'https://loremflickr.com/400/300/' }); } ); vk.updates.start().catch(console.error); ``` ``` -------------------------------- ### Connect to VK Streaming API and Manage Rules Source: https://context7.com/negezor/vk-io/llms.txt Establishes a WebSocket connection to the VK Streaming API to receive real-time public content. Allows adding, listing, and deleting keyword-based rules. ```typescript import { VK } from 'vk-io'; import { StreamingAPI } from '@vk-io/streaming'; const vk = new VK({ token: process.env.TOKEN }); const streaming = new StreamingAPI({ api: vk.api, updates: vk.updates }); // Handle incoming streaming events vk.updates.on('publication', (context) => { console.log('New publication:', context); }); async function run() { await streaming.startWebSocket(); // Add a keyword rule await streaming.addRule({ tag: 'pumpkins', value: 'тыква' }); await streaming.addRule({ tag: 'cats', value: 'кот' }); // List active rules const rules = await streaming.getRules(); console.log(rules); // Remove a rule by tag await streaming.deleteRule('cats'); } run().catch(console.error); ``` -------------------------------- ### Create VK Keyboards with Array Pattern Source: https://context7.com/negezor/vk-io/llms.txt Construct keyboards using a nested array structure. The .inline() method attaches the keyboard directly to the message. ```typescript // --- Array pattern --- const arrayKeyboard = Keyboard.keyboard([ [ Keyboard.textButton({ label: 'Option A', payload: { cmd: 'a' } }), Keyboard.textButton({ label: 'Option B', payload: { cmd: 'b' } }) ], Keyboard.textButton({ label: 'Back', payload: { cmd: 'back' } }) ]).inline(); // attach to message ``` -------------------------------- ### Upload Files with Upload Class Source: https://context7.com/negezor/vk-io/llms.txt The Upload class handles various file types for VK. Supports uploading from URLs, file paths, Buffers, and ReadableStreams. Ensure contentLength is provided for streams. ```typescript import { API, Upload } from 'vk-io'; import fs from 'fs'; const api = new API({ token: process.env.TOKEN }); const upload = new Upload({ api }); async function run() { // Upload from URL const photoFromUrl = await upload.messagePhoto({ source: { value: 'https://placekitten.com/400/300' } }); // Upload from file path const photoFromFile = await upload.messagePhoto({ source: { value: './cat.jpg' } }); // Upload from Buffer const photoFromBuffer = await upload.messagePhoto({ source: { value: fs.readFileSync('./cat.jpg') } }); // Upload from ReadableStream (contentLength required) const stream = fs.createReadStream('./cat.jpg'); const photoFromStream = await upload.messagePhoto({ source: { value: stream, contentLength: fs.statSync('./cat.jpg').size } }); // The returned attachment auto-serializes to "photo{ownerId}_{id}" await api.messages.send({ peer_id: 12345678, attachment: photoFromUrl, // => "photo100_1" random_id: 0 }); // Upload a document graffiti const graffiti = await upload.messageGraffiti({ source: { value: './graffiti.png' } }); // Upload voice message const voice = await upload.audioMessage({ source: { value: fs.createReadStream('./voice.ogg'), contentLength: fs.statSync('./voice.ogg').size } }); console.log(String(voice)); // => "doc{ownerId}_{id}" } run().catch(console.error); ``` -------------------------------- ### Pattern-Based Message Routing with HearManager Source: https://context7.com/negezor/vk-io/llms.txt HearManager provides command and pattern routing for message events, similar to a router middleware. It can match exact strings, multiple strings, regular expressions (with capture groups), and payload commands. ```bash npm install @vk-io/hear ``` ```typescript import { VK, MessageContext } from 'vk-io'; import { HearManager } from '@vk-io/hear'; const vk = new VK({ token: process.env.TOKEN }); const hearManager = new HearManager(); vk.updates.on('message_new', hearManager.middleware); // Match exact string hearManager.hear('/start', async (context) => { await context.send('Welcome! Use /help for commands.'); }); // Match multiple strings hearManager.hear(['/time', '/date'], async (context) => { await context.send(String(new Date())); }); // Match regular expression — capture groups available via context.$match hearManager.hear(/^ egex (.+)/i, async (context) => { const reversed = context.$match[1].split('').reverse().join(''); await context.send(reversed); }); // Match by payload command (keyboard button press) hearManager.hear( [(_text, ctx) => ctx.state.command === 'cat'], async (context) => { await context.sendPhotos({ value: 'https://loremflickr.com/400/300/' }); } ); vk.updates.start().catch(console.error); ``` -------------------------------- ### Configure API Requests with HTTPS Proxy Source: https://context7.com/negezor/vk-io/llms.txt Route all API requests through an HTTPS proxy by providing a custom agent during API class initialization. ```typescript import { API } from 'vk-io'; import HttpsProxyAgent from 'https-proxy-agent'; const agent = new HttpsProxyAgent(process.env.HTTP_PROXY); // e.g., process.env.HTTP_PROXY = 'https://168.63.76.32:3128' const api = new API({ token: process.env.TOKEN, agent }); const groups = await api.groups.getById({ group_ids: ['vk'] }); console.log(groups); ``` -------------------------------- ### resolveResource Source: https://context7.com/negezor/vk-io/llms.txt Normalizes VK URLs, mentions, slugs, and numeric IDs into typed resource objects. ```APIDOC ## resolveResource — Resolve VK Resource Identifiers `resolveResource` normalizes VK URLs, mentions, slugs, and numeric IDs into typed resource objects. ```typescript import { API, resolveResource } from 'vk-io'; const api = new API({ token: process.env.TOKEN }); // From URL console.log(await resolveResource({ api, resource: 'https://vk.ru/id1' })); // => { id: 1, type: 'user' } console.log(await resolveResource({ api, resource: 'https://vk.ru/durov' })); // => { id: 1, type: 'user' } console.log(await resolveResource({ api, resource: 'https://vk.ru/wall1_2442097' })); // => { id: 2442097, ownerId: 1, type: 'wall' } console.log(await resolveResource({ api, resource: 'https://vk.ru/club1' })); // => { id: 1, type: 'group' } // From mention console.log(await resolveResource({ api, resource: '[id1|Durov]' })); // => { id: 1, type: 'user' } // From numeric ID (positive = user, negative = group) console.log(await resolveResource({ api, resource: -1 })); // => { id: 1, type: 'group' } // From slug (requires api to call utils.resolveScreenName) console.log(await resolveResource({ api, resource: 'durov' })); // => { id: 1, type: 'user' } ``` ``` -------------------------------- ### Handle VK Captcha Challenges Source: https://context7.com/negezor/vk-io/llms.txt Implement CAPTCHA handling using CallbackService to solve challenges and retry API calls with a success token. ```typescript import { API, CallbackService } from 'vk-io'; const callbackService = new CallbackService(); const api = new API({ token: process.env.TOKEN, callbackService }); callbackService.onCaptcha(async (payload, retry) => { // payload.redirectUri — URL of captcha image (load only once) const { successToken } = await myExternalCaptchaSolver(payload.redirectUri); try { await retry(successToken); console.log('Captcha solved successfully'); } catch (error) { console.error('Captcha solution failed', error); } }); await api.messages.send({ peer_id: 123, message: 'Hello', random_id: 0 }); ``` -------------------------------- ### API - Direct VK API Calls Source: https://context7.com/negezor/vk-io/llms.txt The API class provides proxy-based access to every VK API method using dot-notation that mirrors the official VK API method names exactly. ```APIDOC ## API — Direct VK API Calls ### Description The `API` class provides proxy-based access to every VK API method using dot-notation that mirrors the official VK API method names exactly. ### Configuration Options - `token`: (string) - VK API token. - `apiLimit`: (number) - Rate limit for API requests (default: 3 req/s for user/service tokens, 20 for group tokens). - `apiMode`: (string) - API request mode: 'sequential' (default), 'parallel', or 'parallel_selected'. - `apiRequestMode`: (string) - API request execution mode: 'sequential' (default) or 'burst'. - `agent`: (HttpsProxyAgent) - HTTPS proxy agent for routing API requests. - `callbackService`: (CallbackService) - Service for handling CAPTCHA challenges. ### Usage ```typescript import { API } from 'vk-io'; const api = new API({ token: process.env.TOKEN, apiLimit: 20, apiMode: 'parallel', apiRequestMode: 'sequential' }); async function run() { // Proxy call: api..(params) const users = await api.users.get({ user_ids: [1, 2, 3] }); console.log(users); // => [{ id: 1, ... }, { id: 2, ... }, { id: 3, ... }] // Equivalent low-level call const wall = await api.call('wall.get', { owner_id: -1 }); // Execute stored procedure await api.procedure('myStoredProc', { arg1: 'value' }); // Execute method — returns { response, errors } const result = await api.execute({ code: 'return API.users.get({ user_ids: 1 });' }); console.log(result.response, result.errors); } run().catch(console.error); ``` ### API — Proxy Configuration Route all API requests through an HTTPS proxy by passing a custom agent. ```typescript import { API } from 'vk-io'; import HttpsProxyAgent from 'https-proxy-agent'; const agent = new HttpsProxyAgent(process.env.HTTP_PROXY); // e.g., process.env.HTTP_PROXY = 'https://168.63.76.32:3128' const api = new API({ token: process.env.TOKEN, agent }); const groups = await api.groups.getById({ group_ids: ['vk'] }); console.log(groups); ``` ### API — Captcha Handling Handle CAPTCHA challenges that VK may return during API calls using `CallbackService`. ```typescript import { API, CallbackService } from 'vk-io'; const callbackService = new CallbackService(); const api = new API({ token: process.env.TOKEN, callbackService }); callbackService.onCaptcha(async (payload, retry) => { // payload.redirectUri — URL of captcha image (load only once) const { successToken } = await myExternalCaptchaSolver(payload.redirectUri); try { await retry(successToken); console.log('Captcha solved successfully'); } catch (error) { console.error('Captcha solution failed', error); } }); await api.messages.send({ peer_id: 123, message: 'Hello', random_id: 0 }); ``` ``` -------------------------------- ### Perform Direct Authorization with User Credentials Source: https://context7.com/negezor/vk-io/llms.txt Obtain a VK access token using user login and password. Handles two-factor authentication if required. Requires official VK app credentials. ```typescript import { CallbackService } from 'vk-io'; import { DirectAuthorization, officialAppCredentials } from '@vk-io/authorization'; const callbackService = new CallbackService(); // Handle 2FA if required callbackService.onTwoFactor(async (payload, retry) => { const code = await promptUser('Enter 2FA code:'); await retry(code); }); const direct = new DirectAuthorization({ callbackService, scope: 'all', ...officialAppCredentials.android, // { clientId, clientSecret } login: process.env.LOGIN, password: process.env.PASSWORD, apiVersion: '5.199' }); async function run() { const result = await direct.run(); console.log('Token:', result.token); console.log('User ID:', result.userId); console.log('Expires:', result.expires); // Use result.token with VK or API class } run().catch(console.error); // Also available: ImplicitFlowUser, ImplicitFlowGroup, AccountVerification ``` -------------------------------- ### Upload - File Uploads Source: https://context7.com/negezor/vk-io/llms.txt The Upload class simplifies the process of uploading various file types such as photos, videos, documents, audio messages, graffiti, and stories to VK servers. It returns typed Attachment instances, making it easier to integrate uploaded media into your application. ```APIDOC ## Upload — File Uploads The `Upload` class handles uploading photos, videos, documents, audio messages, graffiti, and stories to VK servers, returning typed `Attachment` instances. ```typescript import { API, Upload } from 'vk-io'; import fs from 'fs'; const api = new API({ token: process.env.TOKEN }); const upload = new Upload({ api }); async function run() { // Upload from URL const photoFromUrl = await upload.messagePhoto({ source: { value: 'https://placekitten.com/400/300' } }); // Upload from file path const photoFromFile = await upload.messagePhoto({ source: { value: './cat.jpg' } }); // Upload from Buffer const photoFromBuffer = await upload.messagePhoto({ source: { value: fs.readFileSync('./cat.jpg') } }); // Upload from ReadableStream (contentLength required) const stream = fs.createReadStream('./cat.jpg'); const photoFromStream = await upload.messagePhoto({ source: { value: stream, contentLength: fs.statSync('./cat.jpg').size } }); // The returned attachment auto-serializes to "photo{ownerId}_{id}" await api.messages.send({ peer_id: 12345678, attachment: photoFromUrl, // => "photo100_1" random_id: 0 }); // Upload a document graffiti const graffiti = await upload.messageGraffiti({ source: { value: './graffiti.png' } }); // Upload voice message const voice = await upload.audioMessage({ source: { value: fs.createReadStream('./voice.ogg'), contentLength: fs.statSync('./voice.ogg').size } }); console.log(String(voice)); // => "doc{ownerId}_{id}" } run().catch(console.error); ``` ``` -------------------------------- ### Work with VK Attachments Source: https://context7.com/negezor/vk-io/llms.txt Use the Attachment class to wrap and manage VK attachment objects. Attachments auto-serialize to the 'type{ownerId}_{id}' format. Parse attachments from strings or construct them manually. ```typescript import { Attachment } from 'vk-io'; // Construct manually const photo = new Attachment({ type: 'photo', payload: { id: 1, owner_id: 100 } }); photo.toString(); // => 'photo100_1' String(photo); // => 'photo100_1' // Parse from string const parsed = Attachment.fromString('photo100_1'); // => Attachment // Send mixed attachments — auto-serializes via toString await api.messages.send({ peer_id: 12345678, attachment: [photo, 'doc100_5'], // => 'photo100_1,doc100_5' random_id: 0 }); // Utility methods photo.canBeAttached(); // => true photo.isFilled(); // => false (payload incomplete until fully loaded) photo.equals('photo100_1'); // => true photo.equals(Attachment.fromString('photo100_1')); // => true ``` -------------------------------- ### Direct VK API Calls with API Class Source: https://context7.com/negezor/vk-io/llms.txt Use the API class for direct VK API calls via proxy or low-level methods. Configure rate limits and request modes. ```typescript import { API } from 'vk-io'; const api = new API({ token: process.env.TOKEN, // Rate limit: 3 req/s for user/service tokens (default), 20 for group tokens apiLimit: 20, // 'sequential' (default) | 'parallel' | 'parallel_selected' apiMode: 'parallel', // 'sequential' (default) | 'burst' apiRequestMode: 'sequential' }); async function run() { // Proxy call: api..(params) const users = await api.users.get({ user_ids: [1, 2, 3] }); console.log(users); // => [{ id: 1, ... }, { id: 2, ... }, { id: 3, ... }] // Equivalent low-level call const wall = await api.call('wall.get', { owner_id: -1 }); // Execute stored procedure await api.procedure('myStoredProc', { arg1: 'value' }); // Execute method — returns { response, errors } const result = await api.execute({ code: 'return API.users.get({ user_ids: 1 });' }); console.log(result.response, result.errors); } run().catch(console.error); ``` -------------------------------- ### Control API Requests with APIRequest Source: https://context7.com/negezor/vk-io/llms.txt Use APIRequest for manual dispatch of API calls or serialization into the execute format. Requires an initialized API instance. ```typescript import { API, APIRequest } from 'vk-io'; const api = new API({ token: process.env.TOKEN }); const request = new APIRequest({ api, method: 'users.get', params: { user_ids: 1 } }); // Manually dispatch const response = await api.make(request); console.log(response); // Serialize to execute sub-call string const executeSnippet = String(request); console.log(executeSnippet); // => API.users.get({"user_ids":1}) ``` -------------------------------- ### createCollectIterator Source: https://context7.com/negezor/vk-io/llms.txt Handles paginated data collection for VK API methods, supporting parallel batching with execute. ```APIDOC ## createCollectIterator — Paginated Data Collection `createCollectIterator` transparently handles `limit/offset` pagination for any VK API method that supports it, with optional parallel batching via `execute`. ```typescript import { API, createCollectIterator } from 'vk-io'; const api = new API({ token: process.env.TOKEN }); const iterator = createCollectIterator({ api, method: 'messages.getConversations', params: { extended: 1 }, // also fetches profiles and groups countPerRequest: 200, // Optional: cap total results (e.g., for users.search which limits to 1000) // maxCount: 1000, // Optional: retry on error // retryLimit: 3, // Optional: parallel execute batches // parallelRequests: 25 }); for await (const chunk of iterator) { console.log(`Progress: ${chunk.percent.toFixed(1)}% (${chunk.received}/${chunk.total})`); // chunk.items — array of conversations // chunk.profiles — user profiles (if extended: 1) // chunk.groups — group objects (if extended: 1) for (const conversation of chunk.items) { console.log(conversation.conversation.peer.id); } } ``` ``` -------------------------------- ### Updates - Receiving Events (Polling & Webhook) Source: https://context7.com/negezor/vk-io/llms.txt The Updates class provides a unified middleware-based event pipeline for receiving events from VK. It supports Bots Long Poll, User Long Poll, and Callback API (Webhook), allowing you to handle various event types and sub-types efficiently. ```APIDOC ## Updates — Receiving Events (Polling & Webhook) `Updates` unifies Bots Long Poll, User Long Poll, and Callback API (Webhook) into a single middleware-based event pipeline. ```typescript import { API, Upload, Updates } from 'vk-io'; import http from 'http'; const api = new API({ token: process.env.TOKEN }); const upload = new Upload({ api }); const updates = new Updates({ api, upload }); // --- Middleware (runs for all events) --- updates.use((context, next) => { console.log('Incoming event type:', context.type); return next(); }); // --- Listen by event type --- updates.on('message', (context) => { console.log('Any message event. subTypes:', context.subTypes); }); // --- Listen by event sub-type --- updates.on('message_new', async (context, next) => { // Attach data to context state for downstream handlers context.state.receivedAt = Date.now(); return next(); }); updates.on('message_new', async (context) => { if (context.text === 'Hi') { await context.send('Hey there!'); } }); // --- Bots Long Poll (group token) --- await updates.start(); // auto-detects pollingGroupId // --- User Long Poll (user token) --- // await updates.startPolling(); // --- Webhook: built-in server --- // updates.start({ webhook: { path: '/my-webhook', port: 3000 } }); // --- Webhook: Express middleware --- // app.post('/my-webhook', updates.getWebhookCallback()); // --- Webhook: Koa middleware --- // router.post('/my-webhook', updates.getKoaWebhookMiddleware()); // --- Webhook: native http.Server --- // http.createServer(updates.getWebhookCallback('/my-webhook')).listen(3000); ``` ``` -------------------------------- ### Handle VK Message Events and Context Source: https://context7.com/negezor/vk-io/llms.txt Process incoming messages using context objects. Check message types, access sender information, store per-request state, and send replies. Supports various context types like MessageContext, WallPostContext, etc. ```typescript import { VK } from 'vk-io'; const vk = new VK({ token: process.env.TOKEN }); vk.updates.on('message_new', async (context, next) => { // Check type and sub-type console.log(context.type); // 'message' console.log(context.subTypes); // ['message_new'] // context.is() searches both type and subTypes context.is(['message']); // true context.is(['chat_invite_user_by_link']); // true if matching subtype // Per-request state bag (shared across middleware chain) context.state.user = await fetchUser(context.senderId); // Serialize context to plain object const plain = JSON.stringify(context); return next(); }); vk.updates.on('message_new', async (context) => { const { text = '' } = context; if (text === 'ping') { // context.send() returns a new MessageContext const sentCtx = await context.send('pong'); } if (context.hasAttachments('photo')) { const photos = context.getAttachments('photo'); console.log(photos.map(String)); // ['photo100_1', ...] } }); // Available context types include: // MessageContext, CommentContext, WallPostContext, LikeContext, // VoteContext, TypingContext, GroupUserContext, GroupMemberContext, // MessageEventContext, MessagesReadContext, DonutSubscriptionContext, // VKPayTransactionContext, FriendActivityContext, and more. vk.updates.start().catch(console.error); ``` -------------------------------- ### Paginated Data Collection with createCollectIterator Source: https://context7.com/negezor/vk-io/llms.txt Use createCollectIterator to handle `limit/offset` pagination for VK API methods. It supports optional parallel batching via `execute` and allows capping total results. Configure `countPerRequest`, `maxCount`, `retryLimit`, and `parallelRequests` for customization. ```typescript import { API, createCollectIterator } from 'vk-io'; const api = new API({ token: process.env.TOKEN }); const iterator = createCollectIterator({ api, method: 'messages.getConversations', params: { extended: 1 }, // also fetches profiles and groups countPerRequest: 200, // Optional: cap total results (e.g., for users.search which limits to 1000) // maxCount: 1000, // Optional: retry on error // retryLimit: 3, // Optional: parallel execute batches // parallelRequests: 25 }); for await (const chunk of iterator) { console.log(`Progress: ${chunk.percent.toFixed(1)}% (${chunk.received}/${chunk.total})`); // chunk.items — array of conversations // chunk.profiles — user profiles (if extended: 1) // chunk.groups — group objects (if extended: 1) for (const conversation of chunk.items) { console.log(conversation.conversation.peer.id); } } ```