This repository has been archived by the owner on May 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
message.go
153 lines (130 loc) · 4.38 KB
/
message.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
144
145
146
147
148
149
150
151
152
153
package busetabot
import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/pkg/errors"
"github.com/yi-jiayu/telegram-bot-api"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
"github.com/yi-jiayu/bus-eta-bot/v4/telegram"
)
// MessageHandler is a handler for incoming messages
type MessageHandler func(context.Context, *BusEtaBot, *tgbotapi.Message) error
// TextHandler handles incoming text messages
func TextHandler(ctx context.Context, bot *BusEtaBot, message *tgbotapi.Message) error {
if strings.Contains(message.Text, "Fetching etas...") {
return nil
}
chatID := message.Chat.ID
// a message is a continuation if it was a reply to a message asking for a bus stop code
continuation := message.ReplyToMessage != nil && message.ReplyToMessage.Text == "Alright, send me a bus stop code to get etas for."
busStopID, serviceNos, err := InferEtaQuery(message.Text)
if err != nil {
// if it wasn't a continuation, we ignore the message
if !continuation {
return nil
}
go bot.LogEvent(ctx, message.From, CategoryMessage, ActionContinuedTextMessage, message.Chat.Type)
// else, we should inform the user if it was invalid
req := telegram.SendMessageRequest{
ChatID: chatID,
Text: "Oops, a bus stop code should be a 5-digit number.",
}
err = bot.TelegramService.Do(req)
if err != nil {
return errors.Wrap(err, "error sending message")
}
return nil
}
eta := NewETA(ctx, bot.BusStops, bot.Datamall, ETARequest{
UserID: message.From.ID,
Time: bot.NowFunc(),
Code: busStopID,
Services: serviceNos,
})
text, err := summaryFormatter.Format(eta)
if err != nil {
return err
}
markup := NewETAMessageReplyMarkup(busStopID, serviceNos, "", false)
req := telegram.SendMessageRequest{
ChatID: chatID,
Text: text,
ParseMode: "markdown",
ReplyMarkup: markup,
}
if continuation {
go bot.LogEvent(ctx, message.From, CategoryMessage, ActionContinuedTextMessage, message.Chat.Type)
} else {
go bot.LogEvent(ctx, message.From, CategoryMessage, ActionEtaTextMessage, message.Chat.Type)
}
err = bot.TelegramService.Do(req)
if err != nil {
return errors.Wrap(err, "error sending message")
}
return nil
}
// LocationHandler handles messages contain a location
func LocationHandler(ctx context.Context, bot *BusEtaBot, message *tgbotapi.Message) error {
chatID := message.Chat.ID
location := message.Location
nearby := bot.BusStops.Nearby(ctx, location.Latitude, location.Longitude, 500, 5)
if len(nearby) > 0 {
go bot.LogEvent(ctx, message.From, CategoryMessage, ActionLocationMessage, message.Chat.Type)
reply := tgbotapi.NewMessage(chatID, "Here are some bus stops near your location:")
if !message.Chat.IsPrivate() {
reply.ReplyToMessageID = message.MessageID
}
_, err := bot.Telegram.Send(reply)
if err != nil {
return err
}
// sleep a while so that this message is received before the others
time.Sleep(250 * time.Millisecond)
for _, bs := range nearby {
distance := bs.Distance
callbackData := CallbackData{
Type: "new_eta",
BusStopID: bs.BusStopCode,
}
callbackDataJSON, err := json.Marshal(callbackData)
if err != nil {
return err
}
callbackDataJSONStr := string(callbackDataJSON)
reply := tgbotapi.NewVenue(chatID, fmt.Sprintf("%s (%s)", bs.Description, bs.BusStopCode), fmt.Sprintf("%.0f m away", distance), bs.Latitude, bs.Longitude)
reply.ReplyMarkup = tgbotapi.InlineKeyboardMarkup{
InlineKeyboard: [][]tgbotapi.InlineKeyboardButton{
{
tgbotapi.InlineKeyboardButton{
Text: "Get etas",
CallbackData: &callbackDataJSONStr,
},
},
},
}
_, err = bot.Telegram.Send(reply)
if err != nil {
log.Errorf(ctx, "%+v", err)
}
}
return nil
}
go bot.LogEvent(ctx, message.From, CategoryMessage, ActionLocationMessage, message.Chat.Type)
reply := tgbotapi.NewMessage(chatID, "Oops, I couldn't find any bus stops within 500 m of your location.")
_, err := bot.Telegram.Send(reply)
return err
}
func messageErrorHandler(ctx context.Context, bot *BusEtaBot, message *tgbotapi.Message, err error) {
log.Errorf(ctx, "%+v", err)
text := fmt.Sprintf("Oh no! Something went wrong. \n\nRequest ID: `%s`", appengine.RequestID(ctx))
reply := tgbotapi.NewMessage(message.Chat.ID, text)
reply.ParseMode = "markdown"
_, err = bot.Telegram.Send(reply)
if err != nil {
log.Errorf(ctx, "%+v", err)
}
}