-
Notifications
You must be signed in to change notification settings - Fork 384
/
recipes.go
143 lines (131 loc) · 3.9 KB
/
recipes.go
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package bertybot
import (
"strings"
"time"
"go.uber.org/zap"
"berty.tech/berty/v2/go/pkg/messengertypes"
)
// Recipe is a set of handlers that performs common behaviors.
type Recipe map[HandlerType][]Handler
// AutoAcceptIncomingContactRequestRecipe makes the bot "click" on the "accept" button automatically.
func AutoAcceptIncomingContactRequestRecipe() Recipe {
recipe := map[HandlerType][]Handler{}
recipe[IncomingContactRequestHandler] = []Handler{
func(ctx Context) {
ctx.Logger.Info("auto-accepting incoming contact request", zap.Any("contact", ctx.Contact))
req := &messengertypes.ContactAccept_Request{
PublicKey: ctx.Contact.PublicKey,
}
_, err := ctx.Client.ContactAccept(ctx.Context, req)
if err != nil {
ctx.Logger.Error("contact accept failed", zap.Error(err))
}
},
}
return recipe
}
// DebugEventRecipe logs every event using zap.DebugLevel.
func DebugEventRecipe(logger *zap.Logger) Recipe {
recipe := map[HandlerType][]Handler{}
recipe[PreAnythingHandler] = []Handler{
func(ctx Context) {
if logger == nil { // if no logger is passed, use the bot's one
logger = ctx.Logger
}
logger.Debug("new event",
zap.Stringer("type", ctx.EventType),
zap.Any("context", ctx),
)
},
}
return recipe
}
// WelcomeMessageRecipe automatically sends a text message to new contacts.
func WelcomeMessageRecipe(text string) Recipe {
recipe := map[HandlerType][]Handler{}
if text == "" {
return recipe
}
// send welcome message to new contacts
recipe[NewConversationHandler] = []Handler{
func(ctx Context) {
// skip old events
if ctx.IsReplay {
return
}
time.Sleep(time.Second) // I don't know why, but this is required :/
ctx.Logger.Info("sending welcome message",
zap.String("text", text),
zap.String("conversation", ctx.ConversationPK),
)
err := ctx.ReplyString(text)
if err != nil {
ctx.Logger.Error("reply failed", zap.Error(err))
}
},
}
// FIXME: send welcome message to new conversations
return recipe
}
// EchoRecipe configures the bot to automatically reply any message with the same message.
// If a prefix is specified, the bot will prefix its response.
// If a prefix is specified, the bot will ignore incoming messages with that prefix (i.e., a conversation with multiple echo bots).
// The bot will skip incoming commands (messages starting with a '/').
func EchoRecipe(prefix string) Recipe {
recipe := map[HandlerType][]Handler{}
recipe[UserMessageHandler] = []Handler{
func(ctx Context) {
// skip old events
if ctx.IsReplay {
return
}
// do not reply to myself
if ctx.IsMe {
return
}
// avoid bot loops
if strings.HasPrefix(ctx.UserMessage, prefix) {
return
}
// ignore commands
if strings.HasPrefix(ctx.UserMessage, "/") {
return
}
// to avoid replying twice, only reply on the unacked message
if ctx.Interaction.Acknowledged {
return
}
msg := prefix + ctx.UserMessage
ctx.Logger.Info("echo replying", zap.String("text", msg), zap.String("conversation", ctx.ConversationPK))
err := ctx.ReplyString(msg)
if err != nil {
ctx.Logger.Error("reply failed", zap.Error(err))
}
},
}
return recipe
}
// DelayResponseRecipe will wait for the specified duration before handling an event.
func DelayResponseRecipe(duration time.Duration) Recipe {
recipe := map[HandlerType][]Handler{}
recipe[PreAnythingHandler] = []Handler{
func(ctx Context) {
// skip old events
if ctx.IsReplay {
return
}
time.Sleep(duration)
},
}
return recipe
}
// AutoAcceptIncomingContactRequestRecipe makes the bot "click" on the "accept" button automatically.
// NOT YET IMPLEMENTED.
func AutoAcceptIncomingGroupInviteRecipe() Recipe {
panic("not implemented.")
}
// SendErrorToClientRecipe will send internal errors to the related context (a contact or a conversation).
// NOT YET IMPLEMENTED.
func SendErrorToClientRecipe() Recipe {
panic("not implemented")
}