Синхронизация чат ↔ страница
Каждый пост существует в двух местах: на странице пользователя/бота и в чате с этим пользователем/ботом. Backend поддерживает связку автоматически.
Связи в БД
posts (id binary_id, external_id bigint, body, media, buttons, ...)
↑
│ FK
│
messages.post_id binary_id NULL → posts.id
post_comments.message_id binary_id NULL → messages.id
messages.post_id— если стоит, сообщение является mirror-постом. На фронте такие сообщения рисуются как post-bubble.post_comments.message_id— если стоит, коммент создан через chat reply (или мы отправили mirror в чат). Используется для идемпотентности.
Что синхронизируется
| Действие | Где запускается | Что происходит |
|---|---|---|
createPost | Bot API | Mirror-сообщение в каждом direct-чате бота. |
editPost | Bot API | Тело и кнопки mirror-сообщений обновляются. |
deletePost | Bot API | Все mirror-сообщения удаляются. |
| Reply на post-bubble в чате | UI / WS / API | Создаётся PostComment (если comments_enabled). |
POST /posts/:id/comments | веб/мобайл | Создаётся коммент + mirror reply в 1-1 чате автор↔коммент-автор. |
| Reaction (emoji) | веб/мобайл | Глобальный счётчик на посте, виден везде. |
Что не синхронизируется
- Реакции на mirror-сообщение в чате (через эмодзи-пикер контекстного меню сообщения) — не отражаются на пост. Это «приватная» реакция в чате.
- Удаление сообщения через UI чата — не удаляет пост. Только
deletePostчерез Bot API влияет на пост. - Edit сообщения через UI — не меняет пост (UI запрещает редактирование mirror-сообщений).
Защита от петли
Когда коммент создаётся через веб → mirror reply отправляется в чат через Chats.send_message(..., skip_post_comment_hook: true). Это говорит hook'у, что не нужно создавать ещё один коммент в обратную сторону.
Дополнительно: hook в Chats.send_message проверяет Repo.exists?(PostComment, message_id == m.id) — если коммент с этим message_id уже есть, повторная запись не делается.
Что отправляется через WebSocket
| Канал | Событие | Когда |
|---|---|---|
chat:<chat_id> | :new_message | Mirror-сообщение появилось в чате. |
chat:<chat_id> | :message_edited | Mirror-сообщение обновлено (editPost). |
chat:<chat_id> | :message_deleted | Mirror-сообщение удалено (deletePost). |
post:<post_id> | :new_comment | Коммент создан (с любой стороны). |
post:<post_id> | :reactions_changed | Кто-то поставил/снял реакцию. |
user_posts:<user_id> | :post_published | Запланированный пост стал опубликованным. |