Skip to main content

Синхронизация чат ↔ страница

Каждый пост существует в двух местах: на странице пользователя/бота и в чате с этим пользователем/ботом. 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 в чат). Используется для идемпотентности.

Что синхронизируется​

ДействиеГде запускаетсяЧто происходит
createPostBot APIMirror-сообщение в каждом direct-чате бота.
editPostBot APIТело и кнопки mirror-сообщений обновляются.
deletePostBot 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_messageMirror-сообщение появилось в чате.
chat:<chat_id>:message_editedMirror-сообщение обновлено (editPost).
chat:<chat_id>:message_deletedMirror-сообщение удалено (deletePost).
post:<post_id>:new_commentКоммент создан (с любой стороны).
post:<post_id>:reactions_changedКто-то поставил/снял реакцию.
user_posts:<user_id>:post_publishedЗапланированный пост стал опубликованным.