Диагностический XMPP-обработчик open_basic_bot
Назначение и канонический контракт
Бот предназначен для минимальной диагностики XMPP:
при запуске вызывает отправку сообщения самому себе;
callback записывает факт получения разрешённых входящих сообщений;
заказ и Ticket этим обработчиком не изменяются;
сбор отчётов других handlers и диалог поддержки здесь не реализованы.
Каноническая цепочка:
Blockly workspace содержит typed root и операцию xmpp_diagnostic_basic.
Из workspace генерируется Python с bind_first_party_handler.
Runtime сверяет program tuple с каталогом builtin handler.
Проверяет runtime module, build_binding и полноту XMPP binding.
Несовпадение контракта отклоняется. Реализацию операции анализируют отдельно от короткого generated wrapper.
Реализация typed operation находится в first_party_operations/open_basic_bot.py и тоже включена в закреплённые источники. Побайтовое совпадение маленького generated wrapper не заменяет анализа этого файла и общего launcher. BPMN описательные, isExecutable=false; Blockly XML/JSON при запуске не интерпретируется.
Запуск и внешнее XMPP-соединение (BPMN)
Схема BPMN Вписать − + На весь экран Скачать исходник Скачать SVG
Загрузка схемы…
Исходник схемы <?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_basic_startup" targetNamespace="urn:sharix:knowledge:handlers">
<bpmn:process id="runtime_Process_runtime" name="open_basic_bot: один диагностический запуск через общий runtime" isExecutable="false">
<bpmn:documentation>{"notes": ["BPMN isExecutable=false; first-party Blockly генерирует Python binding.", "Runtime сверяет operation tuple с каталогом и строит binding; Blockly в runtime не интерпретируется.", "Диагностический send самому себе не проверяет весь бизнес-процесс и не ждёт подтверждения доставки."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_basic_bot.py", "repository": "sharix-open-handlers-examples", "sha256": "5c981c5fbafdf2390816425d987e55310d42135c8ce2f38bbbf18fc050307d06"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_basic_bot.json", "repository": "sharix-open-handlers-examples", "sha256": "c04234ef2ea2ca293f8a60971a1fd7df3289a61a044469249f0c68d77b511e67"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "first_party_operations/open_basic_bot.py", "repository": "sharix-open-handlers-examples", "sha256": "89b14be72b09de5a269109ab1a2ae3f41fc67f3cb26f03e712a041f7770679ea"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "config.py", "repository": "sharix-open-handlers-examples", "sha256": "7b23db9ed283d3bbc3cf2cfbd5d41c629f6be507c3ca38c611572d08a75743a4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "first_party_blockly_codegen.py", "repository": "sharix-open-handlers-backend", "sha256": "7f4dc6607ad62f3150c58de6341b758ebe97f81bd936c9ec033b7d86fed44640"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/first_party_handler_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "fb5ee98561b029de9291e73c2a08205cc9fc2b7b239abffe4a4bb24f56093bdb"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "main.py", "repository": "sharix-open-handlers-backend", "sha256": "66b7df94fedbec931ed4cb2d4e1afd9cf0386e14ed0932e22b15eb301cd792d7"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "runtime_provider.py", "repository": "sharix-open-handlers-backend", "sha256": "c311d3b0721d18d8eccc9cd7fba155108bf285df3002507ee915ee73b797a2f4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/JabberBot.py", "repository": "sharix-open-handlers-backend", "sha256": "7fbd4d1f41bc867109b73dbb632efcfae920269a1aaf6da0e577cc70838820f1"}]}</bpmn:documentation>
<bpmn:laneSet id="runtime_Lanes_runtime">
<bpmn:lane id="runtime_Lane_worker" name="Конкретная выбранная Python version и typed operation xmpp_diagnostic_basic">
<bpmn:flowNodeRef>runtime_start</bpmn:flowNodeRef>
<bpmn:flowNodeRef>runtime_binding</bpmn:flowNodeRef>
<bpmn:flowNodeRef>runtime_connect</bpmn:flowNodeRef>
<bpmn:flowNodeRef>runtime_ok</bpmn:flowNodeRef>
<bpmn:flowNodeRef>runtime_send</bpmn:flowNodeRef>
<bpmn:flowNodeRef>runtime_return</bpmn:flowNodeRef>
<bpmn:flowNodeRef>runtime_end</bpmn:flowNodeRef>
<bpmn:flowNodeRef>runtime_failed</bpmn:flowNodeRef>
</bpmn:lane>
</bpmn:laneSet>
<bpmn:startEvent id="runtime_start" name="Штатный запуск выбранной версии">
<bpmn:outgoing>runtime_Flow_0</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:serviceTask id="runtime_binding" name="Проверить builtin/catalog/operation tuple; build_binding">
<bpmn:incoming>runtime_Flow_0</bpmn:incoming>
<bpmn:outgoing>runtime_Flow_1</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:serviceTask id="runtime_connect" name="Зарегистрировать callback; открыть XMPP и ждать TIME_TO_CONNECT">
<bpmn:incoming>runtime_Flow_1</bpmn:incoming>
<bpmn:outgoing>runtime_Flow_2</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:exclusiveGateway id="runtime_ok" name="Соединение установлено?">
<bpmn:incoming>runtime_Flow_2</bpmn:incoming>
<bpmn:outgoing>runtime_Flow_3</bpmn:outgoing>
<bpmn:outgoing>runtime_Flow_6</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sendTask id="runtime_send" name="Отправить diagnostic message на собственный JID">
<bpmn:incoming>runtime_Flow_3</bpmn:incoming>
<bpmn:outgoing>runtime_Flow_4</bpmn:outgoing>
</bpmn:sendTask>
<bpmn:serviceTask id="runtime_return" name="start_handler возвращает; runtime закрывает XMPP">
<bpmn:incoming>runtime_Flow_4</bpmn:incoming>
<bpmn:outgoing>runtime_Flow_5</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:endEvent id="runtime_end" name="Нормальный выход процесса; receipt не проверен">
<bpmn:incoming>runtime_Flow_5</bpmn:incoming>
</bpmn:endEvent>
<bpmn:endEvent id="runtime_failed" name="Неуспех соединения: общий restart policy">
<bpmn:incoming>runtime_Flow_6</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="runtime_Flow_0" sourceRef="runtime_start" targetRef="runtime_binding" name="" />
<bpmn:sequenceFlow id="runtime_Flow_1" sourceRef="runtime_binding" targetRef="runtime_connect" name="" />
<bpmn:sequenceFlow id="runtime_Flow_2" sourceRef="runtime_connect" targetRef="runtime_ok" name="" />
<bpmn:sequenceFlow id="runtime_Flow_3" sourceRef="runtime_ok" targetRef="runtime_send" name="Да" />
<bpmn:sequenceFlow id="runtime_Flow_4" sourceRef="runtime_send" targetRef="runtime_return" name="" />
<bpmn:sequenceFlow id="runtime_Flow_5" sourceRef="runtime_return" targetRef="runtime_end" name="" />
<bpmn:sequenceFlow id="runtime_Flow_6" sourceRef="runtime_ok" targetRef="runtime_failed" name="Нет" />
</bpmn:process>
<bpmn:collaboration id="Collaboration_basic_startup">
<bpmn:participant id="runtime_Pool_runtime" name="open_basic_bot: один диагностический запуск через общий runtime" processRef="runtime_Process_runtime" />
<bpmn:participant id="xmpp_Participant" name="XMPP server: транспорт сообщения, отдельно от бизнес-API" />
<bpmn:messageFlow id="Message_basic_startup_0" sourceRef="runtime_send" targetRef="xmpp_Participant" name="Сообщение с JID и локальным datetime; без ожидания echo/receipt" />
</bpmn:collaboration>
<bpmndi:BPMNDiagram id="Diagram_basic_startup">
<bpmndi:BPMNPlane id="Plane_basic_startup" bpmnElement="Collaboration_basic_startup">
<bpmndi:BPMNShape id="runtime_DI_Pool_runtime" bpmnElement="runtime_Pool_runtime" isHorizontal="true">
<dc:Bounds x="0.0" y="0.0" width="2150" height="440" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_Lane_worker" bpmnElement="runtime_Lane_worker" isHorizontal="true">
<dc:Bounds x="30.0" y="0.0" width="2120" height="440" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_start" bpmnElement="runtime_start">
<dc:Bounds x="132.0" y="82.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_binding" bpmnElement="runtime_binding">
<dc:Bounds x="365.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_connect" bpmnElement="runtime_connect">
<dc:Bounds x="675.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_ok" bpmnElement="runtime_ok">
<dc:Bounds x="1035.0" y="75.0" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_send" bpmnElement="runtime_send">
<dc:Bounds x="1295.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_return" bpmnElement="runtime_return">
<dc:Bounds x="1605.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_end" bpmnElement="runtime_end">
<dc:Bounds x="1972.0" y="82.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="runtime_DI_failed" bpmnElement="runtime_failed">
<dc:Bounds x="1042.0" y="322.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="runtime_DI_Flow_0" bpmnElement="runtime_Flow_0">
<di:waypoint x="168.0" y="100.0" />
<di:waypoint x="365.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="runtime_DI_Flow_1" bpmnElement="runtime_Flow_1">
<di:waypoint x="515.0" y="100.0" />
<di:waypoint x="675.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="runtime_DI_Flow_2" bpmnElement="runtime_Flow_2">
<di:waypoint x="825.0" y="100.0" />
<di:waypoint x="1035.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="runtime_DI_Flow_3" bpmnElement="runtime_Flow_3">
<di:waypoint x="1085.0" y="100.0" />
<di:waypoint x="1295.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="runtime_DI_Flow_4" bpmnElement="runtime_Flow_4">
<di:waypoint x="1445.0" y="100.0" />
<di:waypoint x="1605.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="runtime_DI_Flow_5" bpmnElement="runtime_Flow_5">
<di:waypoint x="1755.0" y="100.0" />
<di:waypoint x="1972.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="runtime_DI_Flow_6" bpmnElement="runtime_Flow_6">
<di:waypoint x="1060.0" y="125.0" />
<di:waypoint x="1060.0" y="322.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="DI_xmpp_Participant" bpmnElement="xmpp_Participant" isHorizontal="true">
<dc:Bounds x="0" y="650" width="2150" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="DI_Message_basic_startup_0" bpmnElement="Message_basic_startup_0">
<di:waypoint x="1370" y="135" />
<di:waypoint x="1370" y="550" />
<di:waypoint x="1100" y="550" />
<di:waypoint x="1100" y="650" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1150" y="510" width="260" height="42" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions> Для просмотра схемы включите JavaScript. Исходник доступен выше.
Общий launcher:
Загружает выбранную Python version.
Регистрирует message callback и запускает XMPP loop.
Ждёт connected_event не дольше TIME_TO_CONNECT.
Если соединение не установлено — возвращает ненулевой результат; далее действует общая политика внутренних перезапусков.
Успешный import ещё не означает соединение.
После подключения операция:
Записывает диагностические строки в журнал.
Вызывает send_message на собственный JID с JID и локальным datetime в тексте.
Возвращает управление без ожидания echo, receipt или ответа пользователя.
При нормальном возврате launcher останавливает XMPP loop и завершает запуск.
Постоянного listener в этой операции нет. Повтор со стороны внешнего service manager определяется его конфигурацией.
Что подтверждают наблюдаемые признаки:
Строка «Сообщение отправлено»: записана до send_message, поэтому сама не подтверждает даже успешный возврат этого вызова.
Нормальный возврат операции: вызов отправки не бросил исключение; доставка и прочтение этим не доказаны.
Успешное завершение launcher: относится к этому диагностическому запуску, а не к готовности всех бизнес-handler
API .
Отсутствие собственного echo до остановки само по себе не доказывает отказ XMPP.
Что делает входящий callback (BPMN)
Схема BPMN Вписать − + На весь экран Скачать исходник Скачать SVG
Загрузка схемы…
Исходник схемы <?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_basic_filter" targetNamespace="urn:sharix:knowledge:handlers">
<bpmn:process id="callback_Process_callback" name="message_handler: только фильтр и запись факта получения" isExecutable="false">
<bpmn:documentation>{"notes": ["BPMN isExecutable=false; first-party Blockly генерирует Python binding.", "Runtime сверяет operation tuple с каталогом и строит binding; Blockly в runtime не интерпретируется.", "Диагностический send самому себе не проверяет весь бизнес-процесс и не ждёт подтверждения доставки."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_basic_bot.py", "repository": "sharix-open-handlers-examples", "sha256": "5c981c5fbafdf2390816425d987e55310d42135c8ce2f38bbbf18fc050307d06"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_basic_bot.json", "repository": "sharix-open-handlers-examples", "sha256": "c04234ef2ea2ca293f8a60971a1fd7df3289a61a044469249f0c68d77b511e67"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "first_party_operations/open_basic_bot.py", "repository": "sharix-open-handlers-examples", "sha256": "89b14be72b09de5a269109ab1a2ae3f41fc67f3cb26f03e712a041f7770679ea"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "config.py", "repository": "sharix-open-handlers-examples", "sha256": "7b23db9ed283d3bbc3cf2cfbd5d41c629f6be507c3ca38c611572d08a75743a4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "first_party_blockly_codegen.py", "repository": "sharix-open-handlers-backend", "sha256": "7f4dc6607ad62f3150c58de6341b758ebe97f81bd936c9ec033b7d86fed44640"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/first_party_handler_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "fb5ee98561b029de9291e73c2a08205cc9fc2b7b239abffe4a4bb24f56093bdb"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "main.py", "repository": "sharix-open-handlers-backend", "sha256": "66b7df94fedbec931ed4cb2d4e1afd9cf0386e14ed0932e22b15eb301cd792d7"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "runtime_provider.py", "repository": "sharix-open-handlers-backend", "sha256": "c311d3b0721d18d8eccc9cd7fba155108bf285df3002507ee915ee73b797a2f4"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/JabberBot.py", "repository": "sharix-open-handlers-backend", "sha256": "7fbd4d1f41bc867109b73dbb632efcfae920269a1aaf6da0e577cc70838820f1"}]}</bpmn:documentation>
<bpmn:laneSet id="callback_Lanes_callback">
<bpmn:lane id="callback_Lane_worker" name="Пока XMPP callback ещё зарегистрирован">
<bpmn:flowNodeRef>callback_start</bpmn:flowNodeRef>
<bpmn:flowNodeRef>callback_type</bpmn:flowNodeRef>
<bpmn:flowNodeRef>callback_sender</bpmn:flowNodeRef>
<bpmn:flowNodeRef>callback_log</bpmn:flowNodeRef>
<bpmn:flowNodeRef>callback_end</bpmn:flowNodeRef>
<bpmn:flowNodeRef>callback_ignore</bpmn:flowNodeRef>
</bpmn:lane>
</bpmn:laneSet>
<bpmn:startEvent id="callback_start" name="Входящее сообщение">
<bpmn:outgoing>callback_Flow_0</bpmn:outgoing>
<bpmn:messageEventDefinition />
</bpmn:startEvent>
<bpmn:exclusiveGateway id="callback_type" name="type chat или normal?">
<bpmn:incoming>callback_Flow_0</bpmn:incoming>
<bpmn:outgoing>callback_Flow_1</bpmn:outgoing>
<bpmn:outgoing>callback_Flow_2</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:exclusiveGateway id="callback_sender" name="Bare JID из allowlist и body не None?">
<bpmn:incoming>callback_Flow_1</bpmn:incoming>
<bpmn:outgoing>callback_Flow_3</bpmn:outgoing>
<bpmn:outgoing>callback_Flow_4</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:serviceTask id="callback_log" name="Лог: Сообщение получено">
<bpmn:incoming>callback_Flow_3</bpmn:incoming>
<bpmn:outgoing>callback_Flow_5</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:endEvent id="callback_end" name="Без echo/команды/Ticket мутации">
<bpmn:incoming>callback_Flow_5</bpmn:incoming>
</bpmn:endEvent>
<bpmn:endEvent id="callback_ignore" name="Игнорировать">
<bpmn:incoming>callback_Flow_2</bpmn:incoming>
<bpmn:incoming>callback_Flow_4</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="callback_Flow_0" sourceRef="callback_start" targetRef="callback_type" name="" />
<bpmn:sequenceFlow id="callback_Flow_1" sourceRef="callback_type" targetRef="callback_sender" name="Да" />
<bpmn:sequenceFlow id="callback_Flow_2" sourceRef="callback_type" targetRef="callback_ignore" name="Нет" />
<bpmn:sequenceFlow id="callback_Flow_3" sourceRef="callback_sender" targetRef="callback_log" name="Да" />
<bpmn:sequenceFlow id="callback_Flow_4" sourceRef="callback_sender" targetRef="callback_ignore" name="Нет" />
<bpmn:sequenceFlow id="callback_Flow_5" sourceRef="callback_log" targetRef="callback_end" name="" />
</bpmn:process>
<bpmn:collaboration id="Collaboration_basic_filter">
<bpmn:participant id="callback_Pool_callback" name="message_handler: только фильтр и запись факта получения" processRef="callback_Process_callback" />
</bpmn:collaboration>
<bpmndi:BPMNDiagram id="Diagram_basic_filter">
<bpmndi:BPMNPlane id="Plane_basic_filter" bpmnElement="Collaboration_basic_filter">
<bpmndi:BPMNShape id="callback_DI_Pool_callback" bpmnElement="callback_Pool_callback" isHorizontal="true">
<dc:Bounds x="0.0" y="0.0" width="1530" height="440" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="callback_DI_Lane_worker" bpmnElement="callback_Lane_worker" isHorizontal="true">
<dc:Bounds x="30.0" y="0.0" width="1500" height="440" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="callback_DI_start" bpmnElement="callback_start">
<dc:Bounds x="132.0" y="82.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="callback_DI_type" bpmnElement="callback_type">
<dc:Bounds x="415.0" y="75.0" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="callback_DI_sender" bpmnElement="callback_sender">
<dc:Bounds x="725.0" y="75.0" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="callback_DI_log" bpmnElement="callback_log">
<dc:Bounds x="985.0" y="65.0" width="150" height="70" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="callback_DI_end" bpmnElement="callback_end">
<dc:Bounds x="1352.0" y="82.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="callback_DI_ignore" bpmnElement="callback_ignore">
<dc:Bounds x="422.0" y="322.0" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="callback_DI_Flow_0" bpmnElement="callback_Flow_0">
<di:waypoint x="168.0" y="100.0" />
<di:waypoint x="415.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="callback_DI_Flow_1" bpmnElement="callback_Flow_1">
<di:waypoint x="465.0" y="100.0" />
<di:waypoint x="725.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="callback_DI_Flow_2" bpmnElement="callback_Flow_2">
<di:waypoint x="440.0" y="125.0" />
<di:waypoint x="440.0" y="322.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="callback_DI_Flow_3" bpmnElement="callback_Flow_3">
<di:waypoint x="775.0" y="100.0" />
<di:waypoint x="985.0" y="100.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="callback_DI_Flow_4" bpmnElement="callback_Flow_4">
<di:waypoint x="775.0" y="100.0" />
<di:waypoint x="870.0" y="100.0" />
<di:waypoint x="920.0" y="100.0" />
<di:waypoint x="920.0" y="270.0" />
<di:waypoint x="440.0" y="270.0" />
<di:waypoint x="440.0" y="322.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="callback_DI_Flow_5" bpmnElement="callback_Flow_5">
<di:waypoint x="1135.0" y="100.0" />
<di:waypoint x="1352.0" y="100.0" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions> Для просмотра схемы включите JavaScript. Исходник доступен выше.
Входящий callback:
Пропускает только chat и normal.
Отбрасывает resource у JID отправителя.
Проверяет bare sender по allowlist: open_basic_bot или test_user в настроенном EJ_HOST.
Проверяет body is not None, без требования непустой строки.
Записывает только «Сообщение получено».
Callback не выполняет текст как команду и не отправляет echo. Время его работы ограничено жизненным циклом launcher.
Настройка и диагностика
JID строится из botname и EJ_HOST; credentials загружает штатная конфигурация, значения секретов в Wiki не публикуются. Используйте существующий путь управления runtime version/config и штатные журналы. Не подменяйте его отдельным интерпретатором Blockly.
Диагностику разделить на этапы:
Выбранная версия и bootstrap.
Binding contract.
Установление XMPP в пределах TIME_TO_CONNECT.
Вызов send и его ошибка/нормальный возврат.
Фактическое получение: тип, bare JID, allowlist и работающий в этот момент процесс.
У этого бота нет Ticket recheck timer и waiting reason; параметры ожидания SERVICE_REQUEST к нему неприменимы.
Проверенные источники
Git SHA/SHA-256 и модели закреплены в metadata/BPMN, сборщик сверяет источники перед упаковкой. При анализе бот, отправка сообщений и runtime config с секретами не исполнялись/не читались. Общий автоматический hook Wiki пока не завершён.
Связанные материалы