feat(emojis): кастомные эмодзи сервера и системные сообщения
AGENT.md 7.6, 7.12:
- таблица `guild_emojis` (миграция 00008), загрузка PNG/JPEG/WebP/GIF до 512 КБ
с правом MANAGE_EMOJIS, имя `[a-zA-Z0-9_]{2,32}`, лимит 100 на сервер;
- ручки: список эмодзи сервера, переименование, удаление (с удалением файла),
загрузка multipart; аудит emoji.create/update/delete и событие
GUILD_EMOJIS_UPDATE всем участникам сервера;
- кастомные эмодзи в READY (`guilds[].emojis` с токеном `<:name:id>`), реакции
кастомными эмодзи проверяются по файлу, неизвестный эмодзи — 422;
- файлы эмодзи доступны авторизованным (используются в чужих сообщениях);
- системные сообщения: создание комнаты, вход участника (по приглашению и в
публичный сервер) и исключение участника пишутся в ленту типом `system`;
- тесты: права на загрузку, список, реакция кастомным эмодзи, переименование и
удаление, фильтрация системных записей в проверках истории.
This commit is contained in:
@@ -77,6 +77,17 @@ type ReadyGuild struct {
|
||||
MyRoles []string `json:"my_role_ids"`
|
||||
MyNickname string `json:"my_nickname,omitempty"`
|
||||
MyPerms []string `json:"my_permissions"`
|
||||
// Emojis — кастомные эмодзи сервера (AGENT.md 7.12).
|
||||
Emojis []ReadyEmoji `json:"emojis"`
|
||||
}
|
||||
|
||||
// ReadyEmoji — эмодзи сервера в снапшоте: имя, файл и токен для вставки.
|
||||
type ReadyEmoji struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
FileID string `json:"file_id"`
|
||||
Animated bool `json:"animated"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type ReadyChannel struct {
|
||||
|
||||
@@ -137,6 +137,26 @@ func (s *Snapshot) buildGuild(ctx context.Context, guild store.Guild, user *stor
|
||||
MemberIDs: []string{},
|
||||
MyRoles: []string{},
|
||||
MyPerms: []string{},
|
||||
Emojis: []ReadyEmoji{},
|
||||
}
|
||||
|
||||
// Кастомные эмодзи сервера: клиент показывает их в пикере и в тексте.
|
||||
emojis, err := s.store.ListGuildEmojis(ctx, guild.ID, 200)
|
||||
if err != nil {
|
||||
return readyGuild, err
|
||||
}
|
||||
for _, emoji := range emojis {
|
||||
token := "<:" + emoji.Name + ":" + formatID(emoji.FileID) + ">"
|
||||
if emoji.Animated {
|
||||
token = "<a:" + emoji.Name + ":" + formatID(emoji.FileID) + ">"
|
||||
}
|
||||
readyGuild.Emojis = append(readyGuild.Emojis, ReadyEmoji{
|
||||
ID: formatID(emoji.ID),
|
||||
Name: emoji.Name,
|
||||
FileID: formatID(emoji.FileID),
|
||||
Animated: emoji.Animated,
|
||||
Token: token,
|
||||
})
|
||||
}
|
||||
|
||||
roles, err := s.store.ListGuildRoles(ctx, guild.ID)
|
||||
|
||||
Reference in New Issue
Block a user