feat: add dig command

Other changes:
- use middleware for permission checking
- able to respond with emoji
- log incoming requests
This commit is contained in:
Yiyang Kang 2022-11-23 04:05:39 +08:00
parent 412725c6b9
commit 37dffe56ce
3 changed files with 285 additions and 7 deletions

102
bot.go
View file

@ -2,17 +2,25 @@ package main
import (
"fmt"
"html"
"math"
"strings"
"text/tabwriter"
"time"
"github.com/go-errors/errors"
"github.com/samber/lo"
tele "gopkg.in/telebot.v3"
"git.gensokyo.cafe/kkyy/tgbot_misaka_5882f7/cmds"
"git.gensokyo.cafe/kkyy/tgbot_misaka_5882f7/stats"
)
const (
stickerPanic = "CAACAgUAAxkBAAMjY3zoraxZGB8Xejyw86bHLSWLjVcAArMIAAL7-nhXNK7dStmRUGsrBA"
stickerLoading = "CAACAgUAAxkBAAMmY3zp5UCMVRvy1isFCPHrx-UBWX8AApYHAALP8GhXEm9ZIBjn1v8rBA"
)
func isFromAdmin(sender *tele.User) bool {
if sender == nil {
return false
@ -33,17 +41,49 @@ func initBot() (*tele.Bot, error) {
return nil, errors.Wrap(err, 0)
}
b.Use(logMiddleware)
// command routing
b.Handle("/start", handleStartCmd)
b.Handle("/traffic", handleTrafficCmd)
b.Handle("/me", handleUserInfoCmd)
b.Handle("/chat", handleChatInfoCmd)
b.Handle("/year_progress", handleYearProgressCmd)
b.Handle(tele.OnText, handleGeneralMessage)
b.Handle(tele.OnSticker, handleGeneralMessage)
// admin required
adminGrp := b.Group()
adminGrp.Use(adminMiddleware)
adminGrp.Handle("/traffic", handleTrafficCmd)
adminGrp.Handle("/dig", handleDigCmd)
// adminGrp.Handle("/test", handleTestCmd)
return b, nil
}
func adminMiddleware(next tele.HandlerFunc) tele.HandlerFunc {
return func(c tele.Context) error {
if !isFromAdmin(c.Sender()) {
return nil
}
return next(c)
}
}
func logMiddleware(next tele.HandlerFunc) tele.HandlerFunc {
return func(c tele.Context) error {
upd := c.Update()
defer func() {
logger.Infow("Log middleware", "update", upd)
}()
return next(c)
}
}
func handleStartCmd(c tele.Context) error {
if !isFromAdmin(c.Sender()) {
return c.Send("Hello, stranger :)")
@ -53,18 +93,14 @@ func handleStartCmd(c tele.Context) error {
}
func handleTrafficCmd(c tele.Context) error {
if !isFromAdmin(c.Sender()) {
return nil
}
dailyTraffic, err := stats.VnstatDailyTraffic(config.WatchedInterface)
if err != nil {
_ = c.Reply("im die, thank you forever")
_ = c.Reply(stickerFromID(stickerPanic))
return err
}
monthlyTraffic, err := stats.VnstatMonthlyTraffic(config.WatchedInterface)
if err != nil {
_ = c.Reply("im die, thank you forever")
_ = c.Reply(stickerFromID(stickerPanic))
return err
}
@ -200,3 +236,55 @@ func handleYearProgressCmd(c tele.Context) error {
)
return c.Reply(replyText, &tele.SendOptions{ParseMode: tele.ModeHTML})
}
func handleGeneralMessage(_ tele.Context) error {
// Do nothing for now
return nil
}
func stickerFromID(id string) *tele.Sticker {
return &tele.Sticker{
File: tele.File{
FileID: id,
},
}
}
func handleDigCmd(c tele.Context) error {
msg := c.Message()
if msg == nil {
return nil
}
req, err := cmds.NewDigRequest(msg.Payload)
if err != nil {
return c.Reply("Invalid arguments.\nUsage: `/dig <name> [type]`", &tele.SendOptions{ParseMode: tele.ModeMarkdown})
}
resp, err := cmds.Dig(req)
if err != nil {
_ = c.Reply(stickerFromID(stickerPanic))
return err
}
replyBuf := &strings.Builder{}
tw := tabwriter.NewWriter(replyBuf, 0, 0, 2, ' ', 0)
// Write header
if len(resp.Records) > 0 {
_, _ = tw.Write([]byte("Name\tTTL\tType\tData\n"))
}
// Write data
for _, r := range resp.Records {
_, _ = fmt.Fprintf(tw, "%s\t%d\t%s\t%s\n", r.Name, r.TTL, r.Type, r.Data)
}
_ = tw.Flush()
replyText := []string{
fmt.Sprintf("<i>Status: <b>%s</b></i>\n", resp.Status),
fmt.Sprintf("<i>Query Time: <b>%s</b></i>\n\n", resp.QueryTime),
"<pre>",
html.EscapeString(replyBuf.String()),
"</pre>",
}
return c.Reply(strings.Join(replyText, ""), &tele.SendOptions{ParseMode: tele.ModeHTML})
}