chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
506
internal/app/account/business.go
Normal file
506
internal/app/account/business.go
Normal file
|
|
@ -0,0 +1,506 @@
|
|||
package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
maxBusinessLocationAddress = 96
|
||||
maxBusinessIntroTitle = 64
|
||||
maxBusinessIntroDesc = 160
|
||||
)
|
||||
|
||||
func (s *Service) GetBusinessProfile(ctx context.Context, userID int64) (domain.BusinessProfile, bool, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.BusinessProfile{UserID: userID}, false, nil
|
||||
}
|
||||
return s.business.GetBusinessProfile(ctx, userID)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateBusinessWorkHours(ctx context.Context, userID int64, hours *domain.BusinessWorkHours) (domain.BusinessProfile, error) {
|
||||
profile, err := s.businessProfileForUpdate(ctx, userID)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
normalized, err := normalizeBusinessWorkHours(hours)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
profile.WorkHours = normalized
|
||||
return s.saveBusinessProfile(ctx, profile)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateBusinessLocation(ctx context.Context, userID int64, location *domain.BusinessLocation) (domain.BusinessProfile, error) {
|
||||
profile, err := s.businessProfileForUpdate(ctx, userID)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
normalized, err := normalizeBusinessLocation(location)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
profile.Location = normalized
|
||||
return s.saveBusinessProfile(ctx, profile)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateBusinessIntro(ctx context.Context, userID int64, intro *domain.BusinessIntro) (domain.BusinessProfile, error) {
|
||||
profile, err := s.businessProfileForUpdate(ctx, userID)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
normalized, err := normalizeBusinessIntro(intro)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
profile.Intro = normalized
|
||||
return s.saveBusinessProfile(ctx, profile)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateBusinessGreetingMessage(ctx context.Context, userID int64, greeting *domain.BusinessGreetingMessage) (domain.BusinessProfile, error) {
|
||||
profile, err := s.businessProfileForUpdate(ctx, userID)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
normalized, err := normalizeBusinessGreeting(greeting)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
profile.Greeting = normalized
|
||||
return s.saveBusinessProfile(ctx, profile)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateBusinessAwayMessage(ctx context.Context, userID int64, away *domain.BusinessAwayMessage) (domain.BusinessProfile, error) {
|
||||
profile, err := s.businessProfileForUpdate(ctx, userID)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
normalized, err := normalizeBusinessAway(away)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
profile.Away = normalized
|
||||
return s.saveBusinessProfile(ctx, profile)
|
||||
}
|
||||
|
||||
func (s *Service) ListBusinessChatLinks(ctx context.Context, userID int64) ([]domain.BusinessChatLink, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return s.business.ListBusinessChatLinks(ctx, userID)
|
||||
}
|
||||
|
||||
func (s *Service) CreateBusinessChatLink(ctx context.Context, userID int64, input domain.BusinessChatLinkInput) (domain.BusinessChatLink, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.BusinessChatLink{}, domain.ErrPremiumRequired
|
||||
}
|
||||
normalized, err := domain.NormalizeBusinessChatLinkInput(input)
|
||||
if err != nil {
|
||||
return domain.BusinessChatLink{}, err
|
||||
}
|
||||
now := time.Now().Unix()
|
||||
for i := 0; i < 8; i++ {
|
||||
slug, err := randomBusinessChatLinkSlug()
|
||||
if err != nil {
|
||||
return domain.BusinessChatLink{}, err
|
||||
}
|
||||
link, err := s.business.CreateBusinessChatLink(ctx, domain.BusinessChatLink{
|
||||
OwnerUserID: userID,
|
||||
Slug: slug,
|
||||
Link: businessChatLinkURL(slug),
|
||||
Message: normalized.Message,
|
||||
Entities: normalized.Entities,
|
||||
Title: normalized.Title,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
})
|
||||
if err == nil {
|
||||
return link, nil
|
||||
}
|
||||
if !errors.Is(err, domain.ErrBusinessChatLinkInvalid) {
|
||||
return domain.BusinessChatLink{}, err
|
||||
}
|
||||
}
|
||||
return domain.BusinessChatLink{}, domain.ErrBusinessChatLinkInvalid
|
||||
}
|
||||
|
||||
func (s *Service) EditBusinessChatLink(ctx context.Context, userID int64, slug string, input domain.BusinessChatLinkInput) (domain.BusinessChatLink, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.BusinessChatLink{}, domain.ErrPremiumRequired
|
||||
}
|
||||
normalized, err := domain.NormalizeBusinessChatLinkInput(input)
|
||||
if err != nil {
|
||||
return domain.BusinessChatLink{}, err
|
||||
}
|
||||
return s.business.UpdateBusinessChatLink(ctx, userID, strings.TrimSpace(slug), normalized)
|
||||
}
|
||||
|
||||
func (s *Service) DeleteBusinessChatLink(ctx context.Context, userID int64, slug string) (bool, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return false, domain.ErrBusinessChatLinkNotFound
|
||||
}
|
||||
return s.business.DeleteBusinessChatLink(ctx, userID, strings.TrimSpace(slug))
|
||||
}
|
||||
|
||||
func (s *Service) ResolveBusinessChatLink(ctx context.Context, slug string, bumpViews bool) (domain.BusinessChatLink, bool, error) {
|
||||
if s == nil || s.business == nil {
|
||||
return domain.BusinessChatLink{}, false, nil
|
||||
}
|
||||
return s.business.ResolveBusinessChatLink(ctx, strings.TrimSpace(slug), bumpViews)
|
||||
}
|
||||
|
||||
func (s *Service) GetConnectedBusinessBot(ctx context.Context, ownerUserID int64) (domain.ConnectedBusinessBot, bool, error) {
|
||||
if s == nil || s.business == nil || ownerUserID == 0 {
|
||||
return domain.ConnectedBusinessBot{}, false, nil
|
||||
}
|
||||
return s.business.GetConnectedBusinessBot(ctx, ownerUserID)
|
||||
}
|
||||
|
||||
func (s *Service) SaveConnectedBusinessBot(ctx context.Context, ownerUserID int64, bot domain.ConnectedBusinessBot) (domain.ConnectedBusinessBot, error) {
|
||||
if s == nil || s.business == nil || ownerUserID == 0 || bot.BotUserID == 0 || bot.BotUserID == ownerUserID {
|
||||
return domain.ConnectedBusinessBot{}, domain.ErrBotBusinessMissing
|
||||
}
|
||||
recipients, err := normalizeBusinessBotRecipients(bot.Recipients)
|
||||
if err != nil {
|
||||
return domain.ConnectedBusinessBot{}, err
|
||||
}
|
||||
now := time.Now().Unix()
|
||||
bot.OwnerUserID = ownerUserID
|
||||
bot.Recipients = recipients
|
||||
if bot.CreatedAtUnix == 0 {
|
||||
bot.CreatedAtUnix = now
|
||||
}
|
||||
bot.UpdatedAtUnix = now
|
||||
return s.business.SaveConnectedBusinessBot(ctx, bot)
|
||||
}
|
||||
|
||||
func (s *Service) DeleteConnectedBusinessBot(ctx context.Context, ownerUserID, botUserID int64) (bool, error) {
|
||||
if s == nil || s.business == nil || ownerUserID == 0 || botUserID == 0 {
|
||||
return false, domain.ErrBotBusinessMissing
|
||||
}
|
||||
return s.business.DeleteConnectedBusinessBot(ctx, ownerUserID, botUserID)
|
||||
}
|
||||
|
||||
func (s *Service) SetConnectedBusinessBotPaused(ctx context.Context, ownerUserID, peerUserID int64, paused bool) (domain.ConnectedBusinessBotPeerState, error) {
|
||||
if s == nil || s.business == nil || ownerUserID == 0 || peerUserID == 0 || ownerUserID == peerUserID {
|
||||
return domain.ConnectedBusinessBotPeerState{}, domain.ErrBotBusinessMissing
|
||||
}
|
||||
if _, ok, err := s.business.GetConnectedBusinessBot(ctx, ownerUserID); err != nil {
|
||||
return domain.ConnectedBusinessBotPeerState{}, err
|
||||
} else if !ok {
|
||||
return domain.ConnectedBusinessBotPeerState{}, domain.ErrBotBusinessMissing
|
||||
}
|
||||
state, err := s.business.SetConnectedBusinessBotPaused(ctx, ownerUserID, peerUserID, paused)
|
||||
if err != nil {
|
||||
return domain.ConnectedBusinessBotPeerState{}, err
|
||||
}
|
||||
if state.UpdatedAtUnix == 0 {
|
||||
state.UpdatedAtUnix = time.Now().Unix()
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (s *Service) DisableConnectedBusinessBotForPeer(ctx context.Context, ownerUserID, peerUserID int64) (domain.ConnectedBusinessBotPeerState, error) {
|
||||
if s == nil || s.business == nil || ownerUserID == 0 || peerUserID == 0 || ownerUserID == peerUserID {
|
||||
return domain.ConnectedBusinessBotPeerState{}, domain.ErrBotBusinessMissing
|
||||
}
|
||||
if _, ok, err := s.business.GetConnectedBusinessBot(ctx, ownerUserID); err != nil {
|
||||
return domain.ConnectedBusinessBotPeerState{}, err
|
||||
} else if !ok {
|
||||
return domain.ConnectedBusinessBotPeerState{}, domain.ErrBotBusinessMissing
|
||||
}
|
||||
state, err := s.business.DisableConnectedBusinessBotForPeer(ctx, ownerUserID, peerUserID)
|
||||
if err != nil {
|
||||
return domain.ConnectedBusinessBotPeerState{}, err
|
||||
}
|
||||
if state.UpdatedAtUnix == 0 {
|
||||
state.UpdatedAtUnix = time.Now().Unix()
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetConnectedBusinessBotPeerState(ctx context.Context, ownerUserID, peerUserID int64) (domain.ConnectedBusinessBotPeerState, bool, error) {
|
||||
if s == nil || s.business == nil || ownerUserID == 0 || peerUserID == 0 {
|
||||
return domain.ConnectedBusinessBotPeerState{}, false, nil
|
||||
}
|
||||
return s.business.GetConnectedBusinessBotPeerState(ctx, ownerUserID, peerUserID)
|
||||
}
|
||||
|
||||
func (s *Service) ListQuickReplies(ctx context.Context, userID int64) (domain.QuickReplyList, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.QuickReplyList{OwnerUserID: userID}, nil
|
||||
}
|
||||
return s.business.ListQuickReplies(ctx, userID, true)
|
||||
}
|
||||
|
||||
func (s *Service) CheckQuickReplyShortcut(ctx context.Context, userID int64, shortcut string) (bool, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
if _, err := domain.NormalizeQuickReplyShortcut(shortcut); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
return s.business.CheckQuickReplyShortcut(ctx, userID, shortcut)
|
||||
}
|
||||
|
||||
func (s *Service) SaveQuickReplyText(ctx context.Context, userID int64, shortcut string, msg domain.QuickReplyMessage) (domain.QuickReplyMutation, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.QuickReplyMutation{}, domain.ErrPremiumRequired
|
||||
}
|
||||
if msg.Message == "" || utf8.RuneCountInString(msg.Message) > domain.MaxMessageTextLength || len(msg.Entities) > domain.MaxMessageEntityCount {
|
||||
return domain.QuickReplyMutation{}, domain.ErrShortcutInvalid
|
||||
}
|
||||
return s.business.SaveQuickReplyText(ctx, userID, shortcut, msg)
|
||||
}
|
||||
|
||||
func (s *Service) GetQuickReplyMessages(ctx context.Context, userID int64, shortcutID int, ids []int) (domain.QuickReplyMessages, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.QuickReplyMessages{}, domain.ErrShortcutInvalid
|
||||
}
|
||||
return s.business.GetQuickReplyMessages(ctx, userID, shortcutID, ids)
|
||||
}
|
||||
|
||||
func (s *Service) RenameQuickReplyShortcut(ctx context.Context, userID int64, shortcutID int, shortcut string) (domain.QuickReplyMutation, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.QuickReplyMutation{}, domain.ErrPremiumRequired
|
||||
}
|
||||
return s.business.RenameQuickReplyShortcut(ctx, userID, shortcutID, shortcut)
|
||||
}
|
||||
|
||||
func (s *Service) ReorderQuickReplies(ctx context.Context, userID int64, order []int) (domain.QuickReplyMutation, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.QuickReplyMutation{}, domain.ErrPremiumRequired
|
||||
}
|
||||
return s.business.ReorderQuickReplies(ctx, userID, append([]int(nil), order...))
|
||||
}
|
||||
|
||||
func (s *Service) DeleteQuickReplyShortcut(ctx context.Context, userID int64, shortcutID int) (domain.QuickReplyMutation, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.QuickReplyMutation{}, domain.ErrShortcutInvalid
|
||||
}
|
||||
return s.business.DeleteQuickReplyShortcut(ctx, userID, shortcutID)
|
||||
}
|
||||
|
||||
func (s *Service) DeleteQuickReplyMessages(ctx context.Context, userID int64, shortcutID int, ids []int) (domain.QuickReplyMutation, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.QuickReplyMutation{}, domain.ErrShortcutInvalid
|
||||
}
|
||||
return s.business.DeleteQuickReplyMessages(ctx, userID, shortcutID, append([]int(nil), ids...))
|
||||
}
|
||||
|
||||
func (s *Service) businessProfileForUpdate(ctx context.Context, userID int64) (domain.BusinessProfile, error) {
|
||||
if s == nil || s.business == nil || userID == 0 {
|
||||
return domain.BusinessProfile{}, domain.ErrPremiumRequired
|
||||
}
|
||||
profile, _, err := s.business.GetBusinessProfile(ctx, userID)
|
||||
if err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
profile.UserID = userID
|
||||
return profile, nil
|
||||
}
|
||||
|
||||
func (s *Service) saveBusinessProfile(ctx context.Context, profile domain.BusinessProfile) (domain.BusinessProfile, error) {
|
||||
profile.UpdatedAtUnix = time.Now().Unix()
|
||||
if err := s.business.SaveBusinessProfile(ctx, profile); err != nil {
|
||||
return domain.BusinessProfile{}, err
|
||||
}
|
||||
return profile, nil
|
||||
}
|
||||
|
||||
func normalizeBusinessWorkHours(in *domain.BusinessWorkHours) (*domain.BusinessWorkHours, error) {
|
||||
if in == nil {
|
||||
return nil, nil
|
||||
}
|
||||
out := *in
|
||||
out.TimezoneID = strings.TrimSpace(out.TimezoneID)
|
||||
out.OpenNow = false
|
||||
if out.TimezoneID == "" || len(out.WeeklyOpen) == 0 || len(out.WeeklyOpen) > domain.MaxBusinessWorkHourIntervals {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
out.WeeklyOpen = append([]domain.BusinessWeeklyOpen(nil), out.WeeklyOpen...)
|
||||
for _, item := range out.WeeklyOpen {
|
||||
if item.StartMinute < 0 || item.EndMinute <= item.StartMinute || item.EndMinute > 8*24*60 {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func normalizeBusinessLocation(in *domain.BusinessLocation) (*domain.BusinessLocation, error) {
|
||||
if in == nil {
|
||||
return nil, nil
|
||||
}
|
||||
out := *in
|
||||
out.Address = strings.TrimSpace(out.Address)
|
||||
if out.Address == "" || utf8.RuneCountInString(out.Address) > maxBusinessLocationAddress {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
if out.Geo != nil {
|
||||
geo := *out.Geo
|
||||
if geo.Lat < -90 || geo.Lat > 90 || geo.Long < -180 || geo.Long > 180 {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
out.Geo = &geo
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func normalizeBusinessIntro(in *domain.BusinessIntro) (*domain.BusinessIntro, error) {
|
||||
if in == nil {
|
||||
return nil, nil
|
||||
}
|
||||
out := *in
|
||||
out.Title = strings.TrimSpace(out.Title)
|
||||
out.Description = strings.TrimSpace(out.Description)
|
||||
if out.Title == "" && out.Description == "" && out.StickerDocumentID == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if utf8.RuneCountInString(out.Title) > maxBusinessIntroTitle || utf8.RuneCountInString(out.Description) > maxBusinessIntroDesc {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func normalizeBusinessGreeting(in *domain.BusinessGreetingMessage) (*domain.BusinessGreetingMessage, error) {
|
||||
if in == nil {
|
||||
return nil, nil
|
||||
}
|
||||
out := *in
|
||||
if out.ShortcutID <= 0 || !validGreetingNoActivityDays(out.NoActivityDays) {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
recipients, err := normalizeBusinessRecipients(out.Recipients)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out.Recipients = recipients
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func normalizeBusinessAway(in *domain.BusinessAwayMessage) (*domain.BusinessAwayMessage, error) {
|
||||
if in == nil {
|
||||
return nil, nil
|
||||
}
|
||||
out := *in
|
||||
if out.ShortcutID <= 0 {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
switch out.Schedule.Kind {
|
||||
case domain.BusinessAwayScheduleAlways, domain.BusinessAwayScheduleOutsideWorkHours:
|
||||
out.Schedule.StartDate = 0
|
||||
out.Schedule.EndDate = 0
|
||||
case domain.BusinessAwayScheduleCustom:
|
||||
if out.Schedule.StartDate <= 0 || out.Schedule.EndDate <= out.Schedule.StartDate {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
default:
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
recipients, err := normalizeBusinessRecipients(out.Recipients)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out.Recipients = recipients
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func normalizeBusinessRecipients(in domain.BusinessRecipients) (domain.BusinessRecipients, error) {
|
||||
out := in
|
||||
out.Users = append([]int64(nil), in.Users...)
|
||||
if len(out.Users) > domain.MaxBusinessRecipientUsers {
|
||||
return domain.BusinessRecipients{}, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
seen := make(map[int64]struct{}, len(out.Users))
|
||||
users := out.Users[:0]
|
||||
for _, id := range out.Users {
|
||||
if id <= 0 {
|
||||
return domain.BusinessRecipients{}, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
users = append(users, id)
|
||||
}
|
||||
out.Users = users
|
||||
if !out.ExistingChats && !out.NewChats && !out.Contacts && !out.NonContacts && len(out.Users) == 0 {
|
||||
return domain.BusinessRecipients{}, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func normalizeBusinessBotRecipients(in domain.BusinessBotRecipients) (domain.BusinessBotRecipients, error) {
|
||||
out := in
|
||||
users, err := dedupeBusinessUserIDs(in.Users)
|
||||
if err != nil {
|
||||
return domain.BusinessBotRecipients{}, err
|
||||
}
|
||||
excluded, err := dedupeBusinessUserIDs(in.ExcludeUsers)
|
||||
if err != nil {
|
||||
return domain.BusinessBotRecipients{}, err
|
||||
}
|
||||
if len(users)+len(excluded) > domain.MaxBusinessRecipientUsers {
|
||||
return domain.BusinessBotRecipients{}, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
if out.ExcludeSelected {
|
||||
merged := append(users, excluded...)
|
||||
users, err = dedupeBusinessUserIDs(merged)
|
||||
if err != nil {
|
||||
return domain.BusinessBotRecipients{}, err
|
||||
}
|
||||
excluded = nil
|
||||
}
|
||||
out.Users = users
|
||||
out.ExcludeUsers = excluded
|
||||
if !out.ExcludeSelected && !out.ExistingChats && !out.NewChats && !out.Contacts && !out.NonContacts && len(out.Users) == 0 {
|
||||
return domain.BusinessBotRecipients{}, domain.ErrBusinessRecipientsEmpty
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func dedupeBusinessUserIDs(in []int64) ([]int64, error) {
|
||||
if len(in) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
seen := make(map[int64]struct{}, len(in))
|
||||
out := make([]int64, 0, len(in))
|
||||
for _, id := range in {
|
||||
if id <= 0 {
|
||||
return nil, domain.ErrBusinessProfileInvalid
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
out = append(out, id)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func validGreetingNoActivityDays(days int) bool {
|
||||
switch days {
|
||||
case 7, 14, 21, 28:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func randomBusinessChatLinkSlug() (string, error) {
|
||||
value, err := randomInt64()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%x", value), nil
|
||||
}
|
||||
|
||||
func businessChatLinkURL(slug string) string {
|
||||
return "https://telesrv.net/m/" + slug
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue