Комментарии и двусторонняя синхронизация
Комментарии под постом и сообщения в чате с автором — это одно и то же. Backend поддерживает связку автоматически, чтобы:
- Юзер мог комментировать пост из любого места — со страницы или из чата с автором.
- Автор видел все комментарии в одном чате как разговор.
Включение/выключение
При createPost / editPost укажите comments_enabled: bool. По умолчанию — true.
{"text": "Тихий пост", "comments_enabled": false}
Когда comments_enabled: false:
- Кнопка «Комментировать» не отображается на post-bubble в чате.
- Reply на post-bubble не создаёт коммент (и не синхронизируется на страницу).
- API
POST /posts/:id/commentsотклоняется.
Из веба → в чат
Когда юзер пишет коммент через POST /api/posts/{external_id}/comments:
- Создаётся
PostComment{post_id, user_id, body}. - Backend находит direct-чат
commenter ↔ автор поста. Если чата нет — создаётся. - В этот чат отправляется сообщение от имени
commenterсreply_to = mirror post message. - Связка
comment.message_id = новое сообщение.idсохраняется.
Автор видит коммент как обычный chat reply от пользователя, и может на него ответить из чата.
Из чата → на страницу
Когда юзер свайпает влево на post-bubble и пишет reply:
Chats.send_messageсоздаёт обычное сообщение сreply_to_id = post_mirror_id.- Hook детектит, что
reply_to.post_id != nil, и асинхронно создаётPostComment{post_id, user_id, body, message_id = новое сообщение.id}. - Идемпотентно: если коммент уже создан с таким
message_id— повторная запись не делается.
Коммент мгновенно появляется на странице поста. Через WebSocket-канал post:<post_id> отправляется :new_comment — открытые страницы постов обновляются в реальном времени.
API
Список комментариев
GET /api/posts/{external_id}/comments
{
"ok": true,
"comments": [
{
"id": "uuid",
"external_id": 1234567890,
"author": {"id": "...", "username": "denis", "first_name": "Денис", "avatar_url": "..."},
"body": "Отличный анонс!",
"parent_id": null,
"inserted_at": "2026-05-01T10:42:00Z"
}
]
}
Добавить коммент
POST /api/posts/{external_id}/comments
{"body": "Спасибо за анонс!"}
Удалить свой коммент
DELETE /api/posts/comments/{comment_id}
Защита от петли
Backend использует флаг skip_post_comment_hook при отправке mirror-сообщения из коммента, чтобы не создавать дубль через hook в Chats.send_message. Дополнительная страховка — проверка Repo.exists?(PostComment, message_id == m.id) перед созданием.