Бесплатный self-hosted мост WhatsApp ↔ VK для организации CRM на Node.js и PM2 (без платных API)

21.05.26

Интеграция - Мессенджеры и боты

Готовое open-source решение для интеграции WhatsApp с социальной сетью ВКонтакте (через сообщения сообщества) без использования платных шлюзов (GreenAPI, Wazzup и др.). Решение разворачивается на собственном Linux/Windows сервере, работает через библиотеки baileys и vk-io, поддерживает полноценный двухсторонний обмен текстом, медиафайлами, голосовыми сообщениями и стикерами, а также имеет встроенную систему модерации и команд прямо из чата. Идеально подходит в качестве легковесного бэкенда для последующей интеграции с CRM или базами данных «1С:Предприятие».

1. Какую проблему решаем?

Большинство готовых интеграций WhatsApp с CRM-системами или корпоративными чатами требуют ежемесячной подписки за каждый подключенный номер (от 1500 до 5000 рублей в месяц). При этом бизнес часто хочет аккумулировать сообщения из разных источников в одном месте — например, в группе ВКонтакте, где менеджеры уже привыкли обрабатывать входящие лиды.

Данный проект решает эту задачу полностью бесплатно. Мы создаем независимый мост (Relay), который пересылает сообщения клиентов из WhatsApp в вашу группу ВК. Менеджер отвечает на сообщение в ВК с помощью стандартной функции «Ответить» (Reply), а скрипт автоматически отправляет сообщение обратно конкретному клиенту в WhatsApp.

2. Возможности решения:

  • Двухсторонний обмен: Клиент пишет в WhatsApp ↔ Менеджер отвечает из интерфейса ВК.

  • Поддержка медиафайлов: Корректная пересылка изображений, документов, голосовых сообщений (в WA уходят как PTT/Voice, в ВК приходят как аудиосообщения) и стикеров.

  • Умное определение отправителя: Скрипт парсит pushName (реальное имя пользователя из настроек мессенджера) и отображает его рядом с техническим ID (включая работу со специфическими бизнес-аккаунтами и companion-устройствами @lid).

  • Интерактивное управление из ВК через команды:

    • /help — вывод интерактивной справки по доступным командам.

    • /pause — временная приостановка трансляции всех сообщений (режим «выходной день»).

    • /resume — возобновление работы моста.

    • /block_forwarded — автоматическая фильтрация и бан спам-рассылок (сообщений с пометкой «Пересланное» в WA).

    • /block — блокировка конкретного номера (можно переслать сообщение спамера с командой или указать ID вручную).

    • /unblock — удаление из черного списка.

  • Self-hosted архитектура: Конфигурация (config.json) и черный список (exclude.json) хранятся локально. Сессия авторизации кэшируется — QR-код сканируется только один раз.

3. Архитектура и стек технологий

  • Node.js — среда выполнения.

  • @whiskeysockets/baileys — современная и активно обновляемая библиотека для работы с WhatsApp Web протоколом (с автоматическим маскированием под актуальные версии браузеров для защиты от банов).

  • vk-io — мощный фреймворк для работы с API ВКонтакте через LongPoll.

  • PM2 — менеджер процессов для Linux, обеспечивающий отказоустойчивость, логирование и автоматический перезапуск моста при сбоях сети или перезагрузке VDS.

Техническая реализация (Исходный код relay.js)

Ниже представлен полный листинг скрипта, защищенный от утечек памяти (обработчики событий LongPoll инициализируются строго один раз при старте, исключая дублирование сообщений при переподключениях сокета WhatsApp).

Исходный код relay.js

const { 
    default: makeWASocket, 
    useMultiFileAuthState, 
    DisconnectReason, 
    Browsers, 
    fetchLatestBaileysVersion, 
    downloadMediaMessage 
} = require("@whiskeysockets/baileys");
const { VK } = require("vk-io");
const { Boom } = require("@hapi/boom");
const qrcode = require("qrcode-terminal");
const pino = require("pino");
const fs = require("fs");
const readline = require("readline");

const CONFIG_FILE = "./config.json";
const EXCLUDE_FILE = "./exclude.json";

// Глобальные переменные для правильной работы моста
let vk = null;
let globalSock = null;
let config = null;

const askQuestion = (query) => {
    const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
    return new Promise(resolve => rl.question(query, ans => { rl.close(); resolve(ans.trim()); }));
};

async function initConfig() {
    let cfg = {};
    if (fs.existsSync(CONFIG_FILE)) {
        cfg = JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
    } else {
        console.log("\n=== ПЕРВОНАЧАЛЬНАЯ НАСТРОЙКА МОСТА ===");
        cfg.VK_TOKEN = await askQuestion("Введите VK_TOKEN (токен группы ВК): ");
        cfg.VK_GROUP_ID = Number(await askQuestion("Введите VK_GROUP_ID (ID группы, только цифры): "));
        cfg.MY_VK_ID = Number(await askQuestion("Введите MY_VK_ID (Ваш личный ID в ВК, куда слать сообщения): "));
        cfg.MASTER_WA_PHONE = await askQuestion("Введите MASTER_WA_PHONE (Ваш номер WhatsApp, только цифры без +): ");
        
        fs.writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 4));
        console.log("c89; Настройки успешно сохранены в config.json!\n");
    }
    return cfg;
}

function getExclusions() {
    if (fs.existsSync(EXCLUDE_FILE)) {
        return JSON.parse(fs.readFileSync(EXCLUDE_FILE, "utf8"));
    } else {
        const defaultExclusions = ["status@broadcast"];
        fs.writeFileSync(EXCLUDE_FILE, JSON.stringify(defaultExclusions, null, 4));
        return defaultExclusions;
    }
}

function saveExclusions(exclusions) {
    fs.writeFileSync(EXCLUDE_FILE, JSON.stringify(exclusions, null, 4));
}

// === ИНИЦИАЛИЗАЦИЯ ВКОНТАКТЕ ===
async function initVK() {
    vk = new VK({ token: config.VK_TOKEN, pollingGroupId: config.VK_GROUP_ID });

    vk.updates.on('message_new', async (context) => {
        if (context.isOutbox) return;

        // --- БЛОК ОБРАБОТКИ СЛУЖЕБНЫХ КОМАНД ---
        if (context.text) {
            const textCommand = context.text.trim();
            
            // Справка по командам
            if (textCommand === '/help') {
                const helpText = `🤖 Справка по командам моста:\n\n` +
                    `🔹 /help — Показать это сообщение\n` +
                    `🔹 /pause — Остановить пересылку сообщений из WA в ВК (глобальная пауза)\n` +
                    `🔹 /resume — Возобновить пересылку сообщений\n` +
                    `🔹 /block_forwarded — Игнорировать чужой пересланный спам\n` +
                    `🔹 /block — Внести в черный список (ответьте на сообщение или напишите ID, например: /block 12345)\n` +
                    `🔹 /unblock — Достать из черного списка (аналогично команде /block)`;
                await context.send(helpText);
                return;
            }

            if (textCommand === '/pause') {
                let exclusions = getExclusions();
                if (!exclusions.includes("ALL_MESSAGES")) {
                    exclusions.push("ALL_MESSAGES");
                    saveExclusions(exclusions);
                    await context.send(`\08;A039; ПАУЗА: Пересылка всех входящих сообщений из WhatsApp приостановлена.`);
                } else {
                    await context.send(`b88;A039; Мост уже находится на паузе.`);
                }
                return;
            }

            if (textCommand === '/resume') {
                let exclusions = getExclusions();
                if (exclusions.includes("ALL_MESSAGES")) {
                    exclusions = exclusions.filter(id => id !== "ALL_MESSAGES");
                    saveExclusions(exclusions);
                    await context.send(``54;A039; СТАРТ: Пересылка сообщений из WhatsApp возобновлена.`);
                } else {
                    await context.send(`b88;A039; Мост и так работает.`);
                }
                return;
            }
            
            if (textCommand === '/block_forwarded') {
                let exclusions = getExclusions();
                if (!exclusions.includes("FORWARDED_MESSAGES")) {
                    exclusions.push("FORWARDED_MESSAGES");
                    saveExclusions(exclusions);
                    await context.send(`c89; Блокировка сообщений с пометкой "Пересланное" включена.`);
                }
                return;
            }

            const isBlockCmd = textCommand.startsWith('/block');
            const isUnblockCmd = textCommand.startsWith('/unblock');

            if (isBlockCmd || isUnblockCmd) {
                let targetId = textCommand.split(' ')[1]; 
                
                if (!targetId && context.replyMessage && context.replyMessage.text) {
                    const match = context.replyMessage.text.match(/WA \[(.+?)\]/);
                    if (match && match[1]) targetId = match[1];
                }

                if (targetId) {
                    targetId = targetId.replace(/["']/g, ''); 
                    let exclusions = getExclusions();

                    if (isBlockCmd) {
                        if (!exclusions.includes(targetId)) {
                            exclusions.push(targetId);
                            saveExclusions(exclusions);
                            await context.send(`c89; Контакт [${targetId}] успешно добавлен в черный список.`);
                        } else {
                            await context.send(`b88;A039; Контакт [${targetId}] уже находится в черном списке.`);
                        }
                    } else if (isUnblockCmd) {
                        if (exclusions.includes(targetId)) {
                            exclusions = exclusions.filter(id => id !== targetId);
                            saveExclusions(exclusions);
                            await context.send(`c89; Контакт [${targetId}] удален из черного списка.`);
                        } else {
                            await context.send(`b88;A039; Контакта [${targetId}] нет в черном списке.`);
                        }
                    }
                } else {
                    await context.send(`d60; Ошибка! Укажите ID: "/block 12345" или ответьте командой /block на сообщение.`);
                }
                return; 
            }
        }
        // --- КОНЕЦ БЛОКА КОМАНД ---

        let targetWaId = config.MASTER_WA_PHONE + "@s.whatsapp.net"; 

        if (context.replyMessage && context.replyMessage.text) {
            const match = context.replyMessage.text.match(/WA \[(.+?)\]/);
            if (match && match[1]) {
                targetWaId = match[1];
                if (!targetWaId.includes('@')) targetWaId += '@s.whatsapp.net';
            }
        }

        let waPayload = {};
        const prefix = ''; 
        const captionText = ''; 
        const messageText = context.text ? prefix + context.text : prefix;

        if (context.hasAttachments()) {
            const attachment = context.attachments[0]; 

            if (attachment.type === 'photo') {
                waPayload = { image: { url: attachment.largeSizeUrl }, caption: messageText };
            } else if (attachment.type === 'doc') {
                waPayload = { document: { url: attachment.url }, fileName: attachment.title || 'file', mimetype: 'application/octet-stream', caption: messageText };
            } else if (attachment.type === 'audio_message') {
                waPayload = { audio: { url: attachment.url }, mimetype: 'audio/ogg; codecs=opus', ptt: true }; 
            } else if (attachment.type === 'sticker') {
                const stickerImages = attachment.images || attachment.imagesWithBackground;
                const bestStickerUrl = stickerImages[stickerImages.length - 1].url;
                waPayload = { image: { url: bestStickerUrl }, caption: captionText }; 
            } else {
                waPayload = { text: messageText + `\n[Неподдерживаемый медиафайл: ${attachment.type}]` };
            }
        } else {
            if (!context.text) return; 
            waPayload = { text: messageText };
        }

        try {
            if (globalSock) {
                await globalSock.sendMessage(targetWaId, waPayload);
                console.log(`[VK -> WA] Ответ успешно отправлен: ${targetWaId}`);
            } else {
                console.error('[VK -> WA] Сокет WA еще не готов!');
            }
        } catch (e) {
            console.error('[VK -> WA] Ошибка отправки:', e.message);
        }
    });

    vk.updates.start().catch(console.error);
    console.log("ВКонтакте: Бот успешно запущен!");
}

// === ИНИЦИАЛИЗАЦИЯ WHATSAPP ===
async function startRelay() {
    if (!config) {
        config = await initConfig();
        getExclusions();
        await initVK(); 
    }

    const { version } = await fetchLatestBaileysVersion();
    console.log(`[WA] Маскируемся под версию: ${version.join('.')}`);

    const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys');
    
    const sock = makeWASocket({
        version, 
        auth: state,
        logger: pino({ level: 'silent' }),
        browser: Browsers.macOS('Desktop'),
        connectTimeoutMs: 60000,
        keepAliveIntervalMs: 25000,
        markOnlineOnConnect: true
    });

    globalSock = sock; 

    sock.ev.on('creds.update', saveCreds);

    sock.ev.on('connection.update', (update) => {
        const { connection, lastDisconnect, qr } = update;

        if (qr) qrcode.generate(qr, { small: true });

        if (connection === 'open') console.log('WhatsApp Мост: СОЕДИНЕНИЕ УСТАНОВЛЕНО!');

        if (connection === 'close') {
            const errorObject = lastDisconnect?.error;
            const statusCode = (errorObject instanceof Boom)?.output?.statusCode || errorObject?.code;
            console.log(`Разрыв! Код: ${statusCode}. Ошибка: ${errorObject?.message}`);
            
            const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
            if (shouldReconnect) {
                setTimeout(() => startRelay(), 5000);
            }
        }
    });

    sock.ev.on('messages.upsert', async ({ messages }) => {
        const m = messages[0];
        
        if (!m.key.fromMe && m.message) {
            const remoteJid = m.key.remoteJid;
            const senderId = remoteJid.replace('@s.whatsapp.net', '');
            
            const messageType = Object.keys(m.message)[0];
            const isForwarded = m.message[messageType]?.contextInfo?.isForwarded === true;
            
            const currentExclusions = getExclusions(); 
            
            if (currentExclusions.includes("ALL_MESSAGES")) return; 
            if (isForwarded && currentExclusions.includes("FORWARDED_MESSAGES")) return;
            if (currentExclusions.includes(remoteJid) || currentExclusions.includes(senderId)) return; 

            const senderName = m.pushName || "Имя не указано";
            let text = m.message.conversation || m.message.extendedTextMessage?.text || "";
            let vkAttachment = null;

            const isMedia = ['imageMessage', 'videoMessage', 'audioMessage', 'documentMessage', 'stickerMessage'].includes(messageType);

            if (isMedia) {
                try {
                    const buffer = await downloadMediaMessage(m, 'buffer', {}, { logger: pino({ level: 'silent' }) });

                    if (messageType === 'imageMessage') {
                        vkAttachment = await vk.upload.messagePhoto({ source: { value: buffer }, peer_id: config.MY_VK_ID });
                    } else if (messageType === 'audioMessage') {
                        vkAttachment = await vk.upload.audioMessage({ source: { value: buffer }, peer_id: config.MY_VK_ID });
                    } else if (messageType === 'stickerMessage') {
                        vkAttachment = await vk.upload.messageDocument({ source: { value: buffer, filename: 'sticker.webp' }, peer_id: config.MY_VK_ID });
                        text = `[Прислан стикер 👾]\n${text}`;
                    } else {
                        const fileName = m.message[messageType].fileName || 'document.file';
                        vkAttachment = await vk.upload.messageDocument({ source: { value: buffer, filename: fileName }, peer_id: config.MY_VK_ID });
                    }
                    
                    const caption = m.message[messageType]?.caption || "";
                    if (caption) text += `\n${caption}`;
                    
                } catch (e) {
                    console.error("[WA -> VK] Ошибка медиа:", e.message);
                    text = `[Ошибка загрузки файла]\n${text}`;
                }
            }

            if (text || vkAttachment) {
                await vk.api.messages.send({
                    peer_id: config.MY_VK_ID,
                    message: `📩 WA [${senderId}] (${senderName}):\n${text}`,
                    attachment: vkAttachment,
                    random_id: Math.floor(Math.random() * 1000000)
                });
            }
        }
    });
}

// Запуск приложения
startRelay();


Руководство по развертыванию на Linux (Ubuntu 22.04 / 24.04 VDS)

Размещение моста на зарубежном VDS (например, Казахстан, Нидерланды) снимает необходимость в использовании локальных прокси-агентов (Proxifier/Netch) — сервер общается с серверами WhatsApp напрямую.

Шаг 1. Установка Node.js через Node Version Manager (NVM): Для стабильной работы и поддержки современных операторов требуется версия Node.js не ниже 18.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 20

Шаг 2. Загрузка проекта и чистая установка зависимостей: Создайте рабочую директорию и инициализируйте модули:

 

mkdir /root/wa-bridge && cd /root/wa-bridge
# (Перенесите файл relay.js в эту папку)
npm install @whiskeysockets/baileys vk-io @hapi/boom qrcode-terminal pino

Шаг 3. Первоначальный интерактивный запуск: Запустите скрипт вручную в терминале для генерации конфигурации и сканирования QR-кода:

node relay.js

Скрипт поочередно запросит в консоли: VK_TOKEN (токен группы с правами на сообщения), VK_GROUP_ID, MY_VK_ID (ваш ID аккаунта для получения уведомлений) и MASTER_WA_PHONE. Будет сгенерирован файл config.json. Отсканируйте появившийся в консоли QR-код вашим смартфоном. После успешной авторизации остановите процесс через Ctrl + C.

Шаг 4. Демонизация и обеспечение "неубиваемости" через PM2:

npm install -g pm2
pm2 start relay.js --name "wa-bridge"
pm2 save
pm2 startup

(Скопируйте и выполните команду, которую сгенерирует pm2 startup для прописи в системный автозапуск systemd).

Для мониторинга состояния моста используйте команды pm2 status и просмотр логов в реальном времени pm2 logs wa-bridge.


Руководство по развертыванию на Windows (Локальный ПК или Сервер)

Шаг 1. Подготовка окружения (Портативный Node.js)

Чтобы не засорять систему установщиками, мы соберем «портативную» сборку, которую можно переносить на флешке или копировать на любой сервер.

  1. Перейдите на официальный сайт nodejs.org в раздел Download -> Prebuilt Binaries.

  2. Выберите Windows (x64) и обязательно скачайте формат ZIP (не .msi).

  3. Распакуйте архив. Из всей папки нам нужен только один файл — node.exe.

  4. Создайте рабочую папку проекта (например, C:\wa-bridge) и положите node.exe туда.

Шаг 2. Перенос файлов и установка зависимостей

  1. Положите ваш скрипт relay.js в папку C:\wa-bridge.

  2. Откройте командную строку (cmd) в этой папке и установите модули одной командой:

     
    npm install @whiskeysockets/baileys vk-io @hapi/boom qrcode-terminal pino
    

Шаг 3. Первоначальный интерактивный запуск

Запустите скрипт через командную строку:

node.exe relay.js
  1. Введите в консоли запрашиваемые токены и ID для формирования файла config.json.

  2. Отсканируйте появившийся QR-код вашим телефоном.

  3. Убедившись, что в консоли загорелось WhatsApp Мост: СОЕДИНЕНИЕ УСТАНОВЛЕНО УСПЕШНО!, закройте окно командной строки.

Шаг 4. Настройка скрытого автозапуска (без висящих окон)

Чтобы черное окно консоли не висело на рабочем столе сервера и его случайно не закрыли менеджеры, мы настроим запуск в скрытом режиме Windows.

  1. В папке проекта (C:\wa-bridge) создайте текстовый файл и переименуйте его в start.vbs (расширение должно быть строго .vbs).

  2. Откройте его через Блокнот, вставьте следующий код и сохраните:

Set WshShell = CreateObject("WScript.Shell")
' Запускаем локальный node.exe со скриптом в невидимом режиме (аргумент 0)
WshShell.Run "node.exe relay.js", 0, False

Теперь для старта моста достаточно дважды кликнуть по файлу start.vbs. Процесс тихо запустится в оперативной памяти.

  • Как остановить мост на Windows? Откройте Диспетчер задач (Ctrl+Shift+Esc) -> вкладка «Подробности» (Details) -> найдите процесс node.exe и нажмите «Снять задачу».

  • Как настроить автозапуск при старте ПК? Просто нажмите комбинацию Win + R, введите shell:startup и перетащите ярлык файла start.vbs в открывшуюся системную папку «Автозагрузка».


Перспективы интеграции с 1С:Предприятие

Данный скрипт является идеальной "прослойкой". Так как он написан на Node.js, его можно легко расширить:

  1. Добавить отправку HTTP-запросов (fetch/axios) в сторону HTTP-сервиса вашей 1С, передавая туда senderId, text и ссылки на вложения при каждом событии messages.upsert.

  2. Поднять внутри скрипта легковесный Express.js веб-сервер, чтобы сама 1С могла слать POST-запросы на http://localhost:port/send, а скрипт мгновенно пересылал сообщения клиентам в WhatsApp (через globalSock.sendMessage).

Это превращает бесплатный мост в полноценный корпоративный шлюз бизнес-уведомлений.

Вступайте в нашу телеграмм-группу Инфостарт

Системное администрирование Интеграция с мессенджерами Node.js WhatsApp VK Linux Open Source

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

SALE! 50%

Мессенджеры и боты SMS рассылки Email рассылки Пользователь 1С:Предприятие 8 1C:Бухгалтерия 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Управленческий учет Платные (руб)

Расширение 1С с полным набором инструментов для качественных транзакционных, триггерных и маркетинговых рассылок Email, SMS, MAX, WhatsApp, Telegram. Даже простые уведомления об оплате счетов способны существенно упростить сбор дебиторской задолженности. Применение всех возможностей прямого маркетинга выводит коммуникацию с клиентами, уровень сервиса и лояльность на новый уровень.

6100 3050 руб.

07.04.2014    96322    83    200    

164

Мессенджеры и боты Учет документов 1С:Предприятие 8 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление холдингом 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Платные (руб)

Расширение для согласования справочников и документов в основных типовых конфигурациях. Ролевая адресация, условная маршрутизация, чат-бот telegram/max, интеграция с n8n, последовательное и параллельное согласование, уведомление о новых задачах на почту, блокировка объектов в зависимости от статуса, запрет проведения в зависимости от статуса, автозапуск процессов согласования, отчеты по исполнительской дисциплине. Не требуется снятие конфигурации с поддержки. Настройка без программирования. Сертификат 1С-Совместимо.

14900 руб.

15.11.2018    42148    55    60    

86

Мессенджеры и боты 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Интеграция мессенджеров Max, WhatsApp и 1С: УНФ, УТ, КА, ERP - отправка и получение сообщений, картинок, файлов и видео прямо в 1С. Расширение работает с сервисом GreenApi.

30500 руб.

23.06.2023    17208    56    27    

60

Мессенджеры и боты Системный администратор Программист Бизнес-аналитик Пользователь Руководитель проекта 1С:Предприятие 8 Платные (руб)

Развитие популярного решения для интеграции мессенджера Telegram с нашей любимой 1С - конструктор чат-ботов в Телеграм.

15250 руб.

18.06.2021    84521    330    279    

404

Мессенджеры и боты 1С 8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Готовый чат-бот MAX для 1С виде расширения. Клиенты проверяют остатки и заказы прямо в мессенджере. Ролевая модель, гибкое меню, отправка файлов, диалоги. Подключайте свою логику через внешние обработки.

14640 руб.

26.03.2026    1322    2    0    

4

Мобильная разработка Мессенджеры и боты 1С:Предприятие 8 Платные (руб)

Теперь создать telegram-бота - элементарно. Достаточно просто нарисовать блок-схему телеграм-бота, и он сразу заработает. Это возможно при использовании Графического конструктора телеграм-ботов. Это единственный конструктор ботов для telegram, чье качество и функционал подтверждены фирмой 1С, есть сертификат 1С:Совместимо. Расширение в интерактивном режиме, с помощью блок-схем, позволяет с минимальными трудозатратами создать телеграм-ботов в любой конфигурации, работающей на платформе «1С:Предприятие 8.3».

13420 руб.

27.12.2021    52324    130    182    

228

Мессенджеры и боты SMS рассылки 1С:Предприятие 8 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Решение реализовано в виде расширения. Заменяет отправку смс на отправку в WhatsApp через Green-api. Отправка чека картинкой.

7930 руб.

15.05.2024    3823    4    11    

7
Для отправки сообщения требуется регистрация/авторизация