forked from gotd/botapi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadmin.go
More file actions
110 lines (88 loc) · 3.15 KB
/
Copy pathadmin.go
File metadata and controls
110 lines (88 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"fmt"
glog "github.com/gotd/log"
"github.com/gotd/botapi"
)
// registerAdmin builds a Group whose handlers only run in group/supergroup chats
// and share an extra middleware. Groups keep related, similarly-gated handlers
// together instead of repeating the same predicate on each registration.
func registerAdmin(bot *botapi.Bot) {
// The group predicate narrows every handler below to group chats; Use adds a
// middleware that runs only for this group.
groups := bot.Group(botapi.Or(
botapi.ChatTypeIs(botapi.ChatTypeGroup),
botapi.ChatTypeIs(botapi.ChatTypeSupergroup),
)).Use(announce())
// Chat info: title, members count and the caller's membership status.
groups.OnCommand("info", "Show info about this group", func(c *botapi.Context) error {
chat, _ := c.Chat()
info, err := c.Bot.GetChat(c, chat)
if err != nil {
return err
}
count, err := c.Bot.GetChatMemberCount(c, chat)
if err != nil {
return err
}
status := "unknown"
if u := c.Sender(); u != nil {
if member, err := c.Bot.GetChatMember(c, chat, u.ID); err == nil {
status = chatMemberStatus(member)
}
}
_, err = c.Reply(fmt.Sprintf("Group %q\nMembers: %d\nYour status: %s",
info.Title, count, status))
return err
})
// React to the command message with an emoji, then pin it.
groups.OnCommand("pin", "React to and pin your command", func(c *botapi.Context) error {
chat, _ := c.Chat()
id := c.Message().MessageID
if err := c.Bot.SetMessageReaction(c, chat, id, []botapi.ReactionType{botapi.Emoji("👍")}); err != nil {
return err
}
if err := c.Bot.PinChatMessage(c, chat, id, botapi.Silent()); err != nil {
return err
}
_, err := c.Reply("📌 Pinned (and reacted).")
return err
})
// Raw() is the escape hatch to the underlying *tg.Client for anything the
// typed surface doesn't cover. Here we just confirm it's reachable.
groups.OnCommand("raw", "Demonstrate the raw MTProto client escape hatch", func(c *botapi.Context) error {
_ = c.Bot.Raw() // *tg.Client — full MTProto API available here.
_, err := c.Reply("The raw *tg.Client is reachable via Bot.Raw() for anything not yet typed.")
return err
})
}
// announce is a group-scoped middleware: it logs every group-chat update it
// handles before delegating. Unlike the global metrics middleware it is attached
// only to this Group, so it runs for group commands only.
func announce() botapi.Middleware {
return func(next botapi.Handler) botapi.Handler {
return func(c *botapi.Context) error {
glog.For(c.Bot.Logger()).Debug(c, "group command", glog.String("text", c.Message().Text))
return next(c)
}
}
}
// chatMemberStatus extracts the status string from a ChatMember union value.
func chatMemberStatus(m botapi.ChatMember) string {
switch v := m.(type) {
case *botapi.ChatMemberOwner:
return string(v.Status)
case *botapi.ChatMemberAdministrator:
return string(v.Status)
case *botapi.ChatMemberMember:
return string(v.Status)
case *botapi.ChatMemberRestricted:
return string(v.Status)
case *botapi.ChatMemberLeft:
return string(v.Status)
case *botapi.ChatMemberBanned:
return string(v.Status)
default:
return "unknown"
}
}