Developing a bot to automatically respond to Bitrix24 FAQs

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    745
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

FAQ Auto-Reply Bot Development for Bitrix24

Half of the incoming support chat requests are the same questions: "How do I return an item?", "Where is my order?", "What are the delivery terms?" An operator spends time on them that is worth more on non-standard problems. An FAQ bot automatically handles typical questions and forwards non-standard ones to a live operator.

Where the Bot Works

Bitrix24 Open Channels — the main entry point. The bot connects to an open channel as the first operator. When a client writes in an online chat on the website, in Telegram or VK, the request reaches the bot. If the bot answers — the operator is not disturbed. If not — it transfers to a person.

Bot registration in open channels:

POST /rest/imopenlines.bot.register
{
  "CODE": "faq_bot",
  "EVENT_HANDLER": "https://your-server.com/openline/event",
  "OPENLINE": "Y"  // Bot for open channels
}

Two Approaches to Question Matching

Approach 1: Keyword search. Questions and keywords are stored in the database; the bot searches for matches in the message text. Simple to implement, easy to maintain.

CREATE TABLE custom_faq_entries (
    id          SERIAL PRIMARY KEY,
    question    TEXT NOT NULL,
    answer      TEXT NOT NULL,
    keywords    TEXT NOT NULL,  -- comma-separated
    category    VARCHAR(100),
    hits        INT DEFAULT 0,
    is_active   TINYINT DEFAULT 1
);
function findFaqAnswer(string $userMessage): ?array {
    $words = array_filter(explode(' ', mb_strtolower($userMessage)));
    $results = [];

    $faqs = getFaqEntries(); // from cache
    foreach ($faqs as $faq) {
        $keywords = explode(',', mb_strtolower($faq['keywords']));
        $score = 0;
        foreach ($keywords as $kw) {
            $kw = trim($kw);
            if ($kw && (mb_stripos($userMessage, $kw) !== false)) {
                $score += mb_strlen($kw); // longer keywords carry more weight
            }
        }
        if ($score > 0) {
            $results[] = ['faq' => $faq, 'score' => $score];
        }
    }

    if (empty($results)) return null;
    usort($results, fn($a, $b) => $b['score'] <=> $a['score']);
    return $results[0]['faq'];
}

Approach 2: Vector search (RAG). Questions are indexed as embeddings (OpenAI text-embedding-3-small, Yandex GPT Embeddings). For a new question — nearest-neighbour search in a vector database (pgvector, Qdrant). Works on semantically similar phrasings without exact word matches.

Choice: for 50–200 FAQ entries keywords are sufficient. For a large knowledge base with variable phrasings — RAG.

Processing an Event in an Open Channel

// Incoming event from B24
$event = json_decode(file_get_contents('php://input'), true);

if ($event['event'] === 'ONIMBOTMESSAGEADD') {
    $sessionId = $event['data']['PARAMS']['SESSION_ID'];
    $dialogId  = $event['data']['PARAMS']['DIALOG_ID'];
    $text      = $event['data']['PARAMS']['MESSAGE'];
    $chatId    = $event['data']['PARAMS']['CHAT_ID'];

    $faq = findFaqAnswer($text);

    if ($faq) {
        // Reply and close the session
        $b24->callMethod('imopenlines.session.message.send', [
            'SESSION_ID' => $sessionId,
            'MESSAGE'    => $faq['answer'],
        ]);
        // Increment hits counter
        incrementFaqHits($faq['id']);
        // Close session — operator receives no notification
        $b24->callMethod('imopenlines.session.close', ['SESSION_ID' => $sessionId]);
    } else {
        // Transfer to operator
        $b24->callMethod('imopenlines.session.transfer', [
            'SESSION_ID' => $sessionId,
            'QUEUE_ID'   => 1,
        ]);
        $b24->callMethod('imopenlines.session.message.send', [
            'SESSION_ID' => $sessionId,
            'MESSAGE'    => 'Connecting you to a manager, please wait...',
        ]);
    }
}

Clarifying Questions

If there are multiple matches — the bot shows options:

if (count($topResults) > 1 && $topResults[0]['score'] < 10) {
    $options = array_slice($topResults, 0, 3);
    $message = "Please clarify what you are interested in:\n";
    foreach ($options as $i => $r) {
        $message .= ($i + 1) . ". {$r['faq']['question']}\n";
    }
    $message .= "0. Other (connect to manager)";
    // Save selection context in Redis
    $redis->set("faq_choice:{$sessionId}", json_encode($options), 300);
}

Admin Interface for the FAQ Database

A content manager must be able to manage the FAQ without editing code. We develop an admin section in /bitrix/admin/ or as an app in B24:

  • CRUD for questions and answers.
  • Categories (Delivery, Payment, Returns, Technical questions).
  • Statistics: how many times a question was closed by the bot (hits), how many were transferred to operators.
  • View sessions where the bot did not find an answer — this is the priority for expanding the database.

Effectiveness Analytics

-- Percentage of automatically closed sessions
SELECT
    DATE(created_at) AS day,
    COUNT(*) AS total,
    SUM(CASE WHEN closed_by = 'bot' THEN 1 ELSE 0 END) AS auto_closed,
    ROUND(SUM(CASE WHEN closed_by = 'bot' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 1) AS autoclose_pct
FROM custom_faq_sessions
GROUP BY DATE(created_at)
ORDER BY day DESC;

The target auto-close rate for a mature FAQ database is 60–70%.

Timelines

Stage Timeline
Bot registration in open channels, basic integration 1–2 days
FAQ database structure, keyword search 2–3 days
Operator transfer logic, clarifying questions 2–3 days
Admin interface (FAQ CRUD) 2–3 days
Analytics and reports 1–2 days
Database population + testing 2–3 days

Total: 1.5–2.5 weeks excluding database population. Population is separate work that depends on the volume of documentation.