GameServer.Chat
(GameServer v1.0.637)
Copy Markdown
Context for chat messaging across lobbies, groups, and friend DMs.
Chat types
"lobby"— messages within a lobby.chat_ref_idis the lobby id."group"— messages within a group.chat_ref_idis the group id."friend"— direct messages between two friends.chat_ref_idis the other user's id (each user stores the other user's id so queries work symmetrically).
PubSub topics
"chat:lobby:<id>"— lobby chat events"chat:group:<id>"— group chat events"chat:friend:<low>:<high>"— friend DM events (sorted pair of user ids)
Hooks
before_chat_message/2— pipeline hook(user, attrs)→{:ok, attrs}|{:error, reason}after_chat_message/1— fire-and-forget after a message is persisted
Summary
Functions
Admin: delete a single message by id.
Delete all chat data (messages + read cursors) for a given conversation.
Delete all friend DM messages and read cursors between two users.
Count all messages matching filters (admin).
Count total friend DM messages between two users.
Count total messages in a chat conversation.
Count messages grouped by chat_type.
Count distinct users who have sent at least one chat message.
Count unread messages for a user in a specific chat conversation.
Count unread friend DMs between two users for a specific user.
Count unread friend DMs for a user across all friends.
Count unread messages for a user in multiple group chats.
Delete all messages for a given chat conversation.
Delete a chat message owned by the given user.
Delete all read cursors for a given chat conversation.
Get a single message by id.
Get the read cursor for a user in a chat conversation.
List all messages (admin). Supports filters: sender_id, chat_type, chat_ref_id, content.
List friend DM messages between two users.
List messages for a chat conversation.
Mark a chat conversation as read up to a given message id.
Send a chat message.
Subscribe to chat events for a friend DM conversation.
Subscribe to chat events for a group.
Subscribe to chat events for a lobby.
Unsubscribe from friend DM chat events.
Unsubscribe from group chat events.
Unsubscribe from lobby chat events.
Update a chat message owned by the given user.
Functions
@spec admin_delete_message(integer()) :: {:ok, GameServer.Chat.Message.t()} | {:error, term()}
Admin: delete a single message by id.
Delete all chat data (messages + read cursors) for a given conversation.
Delete all friend DM messages and read cursors between two users.
Friend messages are stored bidirectionally (each user's messages use the other's id as chat_ref_id), so both directions must be cleaned up.
@spec count_all_messages(map()) :: non_neg_integer()
Count all messages matching filters (admin).
@spec count_friend_messages(integer(), integer()) :: non_neg_integer()
Count total friend DM messages between two users.
@spec count_messages(String.t(), integer()) :: non_neg_integer()
Count total messages in a chat conversation.
@spec count_messages_by_type() :: map()
Count messages grouped by chat_type.
Returns a map like %{"lobby" => 10, "group" => 5, "friend" => 3}.
@spec count_unique_senders() :: non_neg_integer()
Count distinct users who have sent at least one chat message.
@spec count_unread(integer(), String.t(), integer()) :: non_neg_integer()
Count unread messages for a user in a specific chat conversation.
Returns 0 if the user has read all messages or has no cursor (all are unread
in which case count_messages/2 should be used instead).
@spec count_unread_friend(integer(), integer()) :: non_neg_integer()
Count unread friend DMs between two users for a specific user.
@spec count_unread_friends_batch(integer(), [integer()]) :: %{ required(integer()) => non_neg_integer() }
Count unread friend DMs for a user across all friends.
Returns a map of %{friend_id => unread_count} for friends that have
at least one unread message.
@spec count_unread_groups_batch(integer(), [integer()]) :: %{ required(integer()) => non_neg_integer() }
Count unread messages for a user in multiple group chats.
Returns a map of %{group_id => unread_count}.
@spec delete_messages(String.t(), integer()) :: {non_neg_integer(), nil}
Delete all messages for a given chat conversation.
@spec delete_own_message(integer(), integer()) :: {:ok, GameServer.Chat.Message.t()} | {:error, term()}
Delete a chat message owned by the given user.
Returns {:error, :not_found} if the message does not exist or
{:error, :forbidden} if the caller is not the sender.
@spec delete_read_cursors(String.t(), integer()) :: {non_neg_integer(), nil}
Delete all read cursors for a given chat conversation.
@spec get_message(integer()) :: GameServer.Chat.Message.t() | nil
Get a single message by id.
@spec get_read_cursor(integer(), String.t(), integer()) :: GameServer.Chat.ReadCursor.t() | nil
Get the read cursor for a user in a chat conversation.
Returns nil if the user has never opened this conversation.
@spec list_all_messages( map(), keyword() ) :: [GameServer.Chat.Message.t()]
List all messages (admin). Supports filters: sender_id, chat_type, chat_ref_id, content.
@spec list_friend_messages(integer(), integer(), keyword()) :: [ GameServer.Chat.Message.t() ]
List friend DM messages between two users.
Convenience wrapper that queries messages in both directions.
Options
:page— page number (default 1):page_size— items per page (default 25)
@spec list_messages(String.t(), integer(), keyword()) :: [GameServer.Chat.Message.t()]
List messages for a chat conversation.
Options
:page— page number (default 1):page_size— items per page (default 25)
Returns a list of %Message{} structs ordered by inserted_at descending
(newest first).
@spec mark_read(integer(), String.t(), integer(), integer()) :: {:ok, GameServer.Chat.ReadCursor.t()} | {:error, term()}
Mark a chat conversation as read up to a given message id.
Uses an upsert to create or update the read cursor.
@spec send_message(map(), map()) :: {:ok, GameServer.Chat.Message.t()} | {:error, term()}
Send a chat message.
Parameters
scope—%{user: %User{}}(current_scope)attrs— map with"chat_type","chat_ref_id","content", optional"metadata"
Returns
{:ok, %Message{}}on success{:error, reason}on failure
The before_chat_message hook is called before persistence and can modify
attrs or reject the message. The after_chat_message hook fires asynchronously
after the message is persisted.
Subscribe to chat events for a friend DM conversation.
Subscribe to chat events for a group.
Subscribe to chat events for a lobby.
Unsubscribe from friend DM chat events.
@spec unsubscribe_group_chat(integer()) :: :ok
Unsubscribe from group chat events.
@spec unsubscribe_lobby_chat(integer()) :: :ok
Unsubscribe from lobby chat events.
@spec update_message(integer(), integer(), map()) :: {:ok, GameServer.Chat.Message.t()} | {:error, term()}
Update a chat message owned by the given user.
Only the content and metadata fields can be changed. Returns
{:error, :not_found} if the message does not exist or
{:error, :forbidden} if the caller is not the sender.