VK bot with an AI model: Bots Long Poll API and Claude in Python

Build a bot for a VK community that answers through Claude: community setup, Bots Long Poll API, cost tracking from usage and complete code.

5 min · · development · автоматизация

A VK bot with an AI model answers community subscribers in private messages: it consults on products, answers typical questions and takes requests. Below is a Python bot that receives messages via the Bots Long Poll API, sends them to Claude through Zukko and makes sure a single user doesn't spend more than a set budget. You don't need an external server or an open port: the bot polls VK itself.

Community setup

All the steps below follow the official VK for developers documentation. VK sometimes renames menu items, so check it if something differs.

  1. Enable messages and bot features. In the community: "Manage" → "Messages", turn messages on; in "Bot settings" in the same section, enable "Bot features".
  2. Create an access key. "Manage" → "Advanced" → "API usage" → "Create key". Grant rights for community messages and community management: groups.getLongPollServer needs the manage right, and messages.send needs messages.
  3. Enable Long Poll. In the same section, on the Long Poll API tab choose "Enabled", and under "Event types" tick "Incoming message" (message_new).
  4. Find the community ID: the number from an address like club123456789 or from the community settings.

Create a Zukko key of the form fetch_... in the dashboard. It's convenient to give the bot a separate key with a daily dollar limit, so even a bug in the code can't spend more than that.

Installation and environment variables

bash
pip install requests openai python-dotenv

The .env file:

VK_GROUP_ID=123456789 VK_TOKEN=vk1.a.your_community_key ZUKKO_API_KEY=fetch_... ZUKKO_MODEL=claude-sonnet-5

How a VK bot with an AI model works

The Bots Long Poll API works in three steps:

  1. The groups.getLongPollServer method returns server, key and ts.
  2. The bot requests {server}?act=a_check&key={key}&ts={ts}&wait=25. The server holds the connection for up to 25 seconds and returns new events in the updates array and a new ts.
  3. The next request uses the new ts.

Each event is an object with type, object and group_id fields. For an incoming message type is message_new, and the message itself is in object.message (since API version 5.103): the text is in text, the conversation address in peer_id. Code from old examples like event[0] == 4 belongs to the User Long Poll and doesn't work for community bots.

The server may reply with an error:

ResponseWhat to do
{"failed": 1, "ts": ...}take the new ts from the response and continue
{"failed": 2}the key expired: call groups.getLongPollServer again
{"failed": 3}information was lost: get a new key and ts

API methods are called on the api.vk.ru domain, with the key passed in the Authorization: Bearer ... header, as the VK documentation currently recommends. messages.send requires random_id: a random int32 that protects against duplicate sends. The maximum text length is 9000 characters, so long answers are split into parts.

Tracking spend per user

The API response contains a usage field with the number of input (prompt_tokens) and output (completion_tokens) tokens. Multiply them by the model price and accumulate the total per user per day:

bash
cost = (usage.prompt_tokens * PRICE_IN + usage.completion_tokens * PRICE_OUT) / 1_000_000

For claude-sonnet-5 the Zukko price is $0.30 per 1M input and $0.30 per 1M output tokens. If a message with history takes 2,000 input tokens and the answer 500 output tokens, the cost is (2,000 × 0.30 + 500 × 0.30) / 1,000,000 = $0.00075. With a budget of $0.05 per user per day, that's about 0.05 / 0.00075 ≈ 66 such messages. Prices of other models are in the table below; if you change the model, change PRICE_IN/PRICE_OUT too.

This is an estimate on the bot side. Exact charges are shown in the dashboard under "Usage", and a hard ceiling for the whole bot is set with key limits.

Full code

bash
import os
import random
import time
from datetime import date

import requests
from dotenv import load_dotenv
from openai import APIConnectionError, APIStatusError, OpenAI

load_dotenv()

VK_API = "https://api.vk.ru/method/"
VK_VERSION = "5.199"
VK_TOKEN = os.environ["VK_TOKEN"]

Run it with python vk_bot.py. Send the community a private message and the bot will answer.

A couple of notes on the code. Messages are processed one at a time: while the model answers one user, the others wait. That's enough for a small community; under heavy load, move handle() into a thread pool or rewrite it with asyncio, AsyncOpenAI and an async HTTP client. History and spend live in memory and are lost on restart; for production, move them to Redis or a database.

Which model to choose

ModelZukko price, input/output per 1M tokensContext
claude-sonnet-5$0.30 / $0.301M
gpt-5.6-sol$0.30 / $0.301M
gpt-5.6-luna$0.10 / $0.101M
glm-5.3-flash$0.04 / $0.04128K

The current list is at GET https://api.zukko.pro/v1/models or on the "Models" page in the dashboard. Test which model answers your subscribers best on your own tasks: collect 20–30 real questions from community messages and compare the answers of two or three models with the same system prompt.

FAQ

The bot doesn't receive messages. What should I check?

Whether the Long Poll API is enabled in the community settings and the "Incoming message" event type is ticked. Whether the key has messages and management rights (without manage, groups.getLongPollServer returns an error). Whether community messages are enabled. The code prints the VK error text, so start there.

Why do answers arrive with a delay?

The model needs time to generate, and messages are processed one by one. Lower max_tokens, ask for shorter answers in the system prompt or parallelize processing.

Can I add the bot to a group chat?

Yes, this is enabled in the community bot settings. By default, in a group chat the bot sees only mentions and replies to its own messages. No code changes are needed: the answer goes to the chat's peer_id, and history is kept per that ID as well.

How do I cap total spend, not just per user?

Set a daily and monthly dollar limit on the Zukko key itself in the dashboard. When the limit is reached, the API returns an error and the bot shows the user a message from ERRORS. More in the key documentation.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

VK bot with an AI model via API in Python · Zukko