feat: sync built-in sticker bot
This commit is contained in:
parent
7096625e13
commit
6867d201ed
60 changed files with 7063 additions and 144 deletions
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
// BotStore 是 store.BotStore 的内存实现。bot 的 users 行经注入的 UserStore 创建,
|
||||
// 与 postgres 实现(单事务建 users+bots 两行)保持可见性一致。
|
||||
// 内置 BotFather 的 bots 行预置(token 为空 = 不可登录),对齐迁移 0090 种子。
|
||||
// 内置 service bots 的 bots 行预置(token 为空 = 不可登录),对齐迁移种子。
|
||||
type BotStore struct {
|
||||
mu sync.RWMutex
|
||||
users *UserStore
|
||||
|
|
@ -59,7 +59,13 @@ func NewBotStore(users *UserStore) *BotStore {
|
|||
emojiPerms: make(map[[2]int64]bool),
|
||||
customMethod: make(map[string]domain.BotWebViewCustomMethodQuery),
|
||||
}
|
||||
s.byID[domain.BotFatherUserID] = domain.BotProfile{
|
||||
s.byID[domain.BotFatherUserID] = botFatherSeedProfile()
|
||||
s.byID[domain.StickersBotUserID] = stickersSeedProfile()
|
||||
return s
|
||||
}
|
||||
|
||||
func botFatherSeedProfile() domain.BotProfile {
|
||||
return domain.BotProfile{
|
||||
BotUserID: domain.BotFatherUserID,
|
||||
OwnerUserID: domain.BotFatherUserID,
|
||||
Description: "BotFather is the one bot to rule them all. Use it to create new bot accounts and manage your existing bots.",
|
||||
|
|
@ -72,7 +78,25 @@ func NewBotStore(users *UserStore) *BotStore {
|
|||
{Command: "help", Description: "show help"},
|
||||
},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func stickersSeedProfile() domain.BotProfile {
|
||||
return domain.BotProfile{
|
||||
BotUserID: domain.StickersBotUserID,
|
||||
OwnerUserID: domain.StickersBotUserID,
|
||||
Description: "Create custom sticker and emoji packs for telesrv.",
|
||||
Commands: []domain.BotCommand{
|
||||
{Command: "start", Description: "start the sticker pack assistant"},
|
||||
{Command: "help", Description: "show help"},
|
||||
{Command: "newpack", Description: "create a sticker pack"},
|
||||
{Command: "newemoji", Description: "create a custom emoji pack"},
|
||||
{Command: "addsticker", Description: "add to one of your packs"},
|
||||
{Command: "delsticker", Description: "remove one item from a pack"},
|
||||
{Command: "publish", Description: "publish the current pack"},
|
||||
{Command: "cancel", Description: "cancel the current operation"},
|
||||
{Command: "packs", Description: "list your created packs"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BotStore) CreateBotAccount(ctx context.Context, user domain.User, profile domain.BotProfile) (domain.User, domain.BotProfile, error) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package memory
|
|||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"sync"
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
|
@ -14,6 +15,7 @@ type PasswordStore struct {
|
|||
accountSettings map[int64]domain.AccountSettings
|
||||
notifySettings map[notifySettingsKey]domain.PeerNotifySettings
|
||||
stickerCollections map[stickerCollectionKey][]domain.StickerCollectionItem
|
||||
userStickerSets map[int64]map[int64]domain.UserStickerSet
|
||||
savedMusic map[int64][]domain.Document
|
||||
businessProfiles map[int64]domain.BusinessProfile
|
||||
businessChatLinks map[string]domain.BusinessChatLink
|
||||
|
|
@ -48,6 +50,7 @@ func NewPasswordStore() *PasswordStore {
|
|||
accountSettings: make(map[int64]domain.AccountSettings),
|
||||
notifySettings: make(map[notifySettingsKey]domain.PeerNotifySettings),
|
||||
stickerCollections: make(map[stickerCollectionKey][]domain.StickerCollectionItem),
|
||||
userStickerSets: make(map[int64]map[int64]domain.UserStickerSet),
|
||||
savedMusic: make(map[int64][]domain.Document),
|
||||
businessProfiles: make(map[int64]domain.BusinessProfile),
|
||||
businessChatLinks: make(map[string]domain.BusinessChatLink),
|
||||
|
|
@ -234,6 +237,113 @@ func (s *PasswordStore) ClearStickerCollection(_ context.Context, userID int64,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *PasswordStore) InstallUserStickerSet(_ context.Context, userID int64, setID int64, kind domain.StickerSetKind, archived bool, installedDate int) error {
|
||||
if userID == 0 || setID == 0 {
|
||||
return domain.ErrStickerInvalid
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
sets := s.userStickerSets[userID]
|
||||
if sets == nil {
|
||||
sets = make(map[int64]domain.UserStickerSet)
|
||||
s.userStickerSets[userID] = sets
|
||||
}
|
||||
order := int64(installedDate) << 32
|
||||
sets[setID] = domain.UserStickerSet{
|
||||
OwnerUserID: userID,
|
||||
StickerSetID: setID,
|
||||
Kind: kind,
|
||||
Archived: archived,
|
||||
InstalledDate: installedDate,
|
||||
OrderValue: order,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PasswordStore) UninstallUserStickerSet(_ context.Context, userID int64, setID int64) error {
|
||||
s.mu.Lock()
|
||||
if sets := s.userStickerSets[userID]; sets != nil {
|
||||
delete(sets, setID)
|
||||
}
|
||||
s.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PasswordStore) SetUserStickerSetArchived(_ context.Context, userID int64, setID int64, archived bool, now int) error {
|
||||
s.mu.Lock()
|
||||
if sets := s.userStickerSets[userID]; sets != nil {
|
||||
if item, ok := sets[setID]; ok {
|
||||
item.Archived = archived
|
||||
if !archived && now > 0 {
|
||||
item.OrderValue = int64(now) << 32
|
||||
}
|
||||
sets[setID] = item
|
||||
}
|
||||
}
|
||||
s.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PasswordStore) ReorderUserStickerSets(_ context.Context, userID int64, kind domain.StickerSetKind, order []int64, now int) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
sets := s.userStickerSets[userID]
|
||||
if sets == nil {
|
||||
return nil
|
||||
}
|
||||
orderValue := int64(now) << 32
|
||||
for _, id := range order {
|
||||
item, ok := sets[id]
|
||||
if !ok || item.Kind != kind {
|
||||
continue
|
||||
}
|
||||
item.OrderValue = orderValue
|
||||
sets[id] = item
|
||||
orderValue--
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PasswordStore) ListUserStickerSets(_ context.Context, userID int64, kind domain.StickerSetKind, archived *bool, offsetID int64, limit int) ([]domain.UserStickerSet, int, error) {
|
||||
if limit <= 0 || limit > domain.MaxInstalledStickerSets {
|
||||
limit = domain.MaxInstalledStickerSets
|
||||
}
|
||||
s.mu.RLock()
|
||||
raw := s.userStickerSets[userID]
|
||||
items := make([]domain.UserStickerSet, 0, len(raw))
|
||||
for _, item := range raw {
|
||||
if item.Kind != kind {
|
||||
continue
|
||||
}
|
||||
if archived != nil && item.Archived != *archived {
|
||||
continue
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
s.mu.RUnlock()
|
||||
sort.SliceStable(items, func(i, j int) bool {
|
||||
if items[i].OrderValue == items[j].OrderValue {
|
||||
return items[i].StickerSetID > items[j].StickerSetID
|
||||
}
|
||||
return items[i].OrderValue > items[j].OrderValue
|
||||
})
|
||||
total := len(items)
|
||||
if offsetID != 0 {
|
||||
start := 0
|
||||
for i, item := range items {
|
||||
if item.StickerSetID == offsetID {
|
||||
start = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
items = items[start:]
|
||||
}
|
||||
if len(items) > limit {
|
||||
items = items[:limit]
|
||||
}
|
||||
return append([]domain.UserStickerSet(nil), items...), total, nil
|
||||
}
|
||||
|
||||
func (s *PasswordStore) ListNotifyExceptions(_ context.Context, ownerUserID int64) ([]domain.NotifyException, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ type UserStore struct {
|
|||
nextID int64
|
||||
}
|
||||
|
||||
// NewUserStore 创建内存 UserStore。内置系统账号(777000 / BotFather)预置进表,
|
||||
// 与 postgres 的迁移种子(0005 / 0090)保持双 store 行为一致。
|
||||
// NewUserStore 创建内存 UserStore。内置系统账号(777000 / BotFather / Stickers)
|
||||
// 预置进表,与 postgres 的迁移种子保持双 store 行为一致。
|
||||
func NewUserStore() *UserStore {
|
||||
s := &UserStore{byID: make(map[int64]domain.User), nextID: domain.UserIDSequenceBase}
|
||||
for _, id := range []int64{domain.OfficialSystemUserID, domain.BotFatherUserID} {
|
||||
for _, id := range []int64{domain.OfficialSystemUserID, domain.BotFatherUserID, domain.StickersBotUserID} {
|
||||
if u, ok := domain.SystemUserByID(id); ok {
|
||||
s.byID[u.ID] = u
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue