Skip to content

Commit

Permalink
refactor: refactor bot
Browse files Browse the repository at this point in the history
  • Loading branch information
totanvix committed Jun 26, 2023
1 parent b4e5dc5 commit e596fe7
Show file tree
Hide file tree
Showing 7 changed files with 355 additions and 42 deletions.
3 changes: 1 addition & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"

"remoteUser": "root",
"initializeCommand": "git config --global alias.co checkout && git config --global alias.br branch && git config --global alias.ci commit && git config --global alias.st status"
}
38 changes: 27 additions & 11 deletions api/hook/index.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hook

import (
"encoding/json"
"fmt"
"log"
"net/http"
Expand All @@ -12,25 +13,40 @@ import (
"zeril-bot/utils/kqxs"
"zeril-bot/utils/lunar"
"zeril-bot/utils/qr"
"zeril-bot/utils/quote"
"zeril-bot/utils/random"
"zeril-bot/utils/shortener"
"zeril-bot/utils/structs"
"zeril-bot/utils/weather"
)

func Handler(w http.ResponseWriter, r *http.Request) {
data := r.Context().Value("data").(structs.HookData)
var data structs.HookData
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
panic(err)
}

channel.GetWg().Add(2)
bot := bot.NewBot(data)
res := make(map[string]string)

if data.CallbackQuery.Data != "" {
resolveCallback(data)
} else {
resolveCommand(data)
err = bot.ResolveHook()
if err != nil {
res["status"] = "ERROR"
res["code"] = "internal_error"
res["message"] = err.Error()
Response(w, res, http.StatusInternalServerError)
return
}

channel.GetWg().Wait()
res["status"] = "OK"
Response(w, res, http.StatusOK)
}

func Response(w http.ResponseWriter, res map[string]string, httpStatus int) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(httpStatus)
mRes, _ := json.Marshal(res)
w.Write(mRes)
}

func resolveCommand(data structs.HookData) {
Expand All @@ -53,7 +69,7 @@ func resolveCommand(data structs.HookData) {
case "/groupid", "/groupid@zerill_bot":
help.SendGroupId(chatId, string(data.Message.Chat.Type))
case "/quote", "/quote@zerill_bot":
quote.SendAQuote(chatId)
// quote.SendAQuote(chatId)
case "/lunar", "/lunar@zerill_bot":
lunar.SendLunarDateNow(chatId)
case "/weather", "/weather@zerill_bot":
Expand Down Expand Up @@ -96,7 +112,7 @@ func resolveCallback(callback structs.HookData) {

func setBotIsTyping(chatId int) {
go func() {
bot.SetTypingAction(chatId)
channel.GetWg().Done()
// bot.SetTypingAction(chatId)
// channel.GetWg().Done()
}()
}
7 changes: 5 additions & 2 deletions api/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ func Handler(wri http.ResponseWriter, req *http.Request) {

r := chi.NewRouter()
r.Use(chiMiddle.Logger)
r.Use(middleware.PreRequest)
// r.Use(middleware.PreRequest)
r.Use(middleware.Recoverer)

r.Get("/", func(w http.ResponseWriter, r *http.Request) {})
r.NotFound(middleware.Handle404NotFound())
r.MethodNotAllowed(middleware.Handle405MethodNotAllowed())

// r.Get("/", func(w http.ResponseWriter, r *http.Request) {})
r.Post("/api/hook", hook.Handler)
r.Get("/url", url.Handler)
r.Get("/trip", trip.Handler)
Expand Down
95 changes: 92 additions & 3 deletions utils/bot/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,100 @@ import (
"os"
"path/filepath"
"strconv"
"strings"

// "zeril-bot/utils/quote"
"zeril-bot/utils/quote"
"zeril-bot/utils/structs"
"zeril-bot/utils/telegram"
)

var API_URL string = "https://api.telegram.org/bot" + os.Getenv("TELE_BOT_TOKEN")

var chatType string
var chatFrom structs.From

type Bot struct {
HookData structs.HookData
typingCh chan struct{}
commandCh chan error
}

func NewBot(hookData structs.HookData) *Bot {
tCh := make(chan struct{})
commandCh := make(chan error)

return &Bot{hookData, tCh, commandCh}
}

func (b Bot) ResolveHook() error {
go b.setTypingAction()

var err error

switch {
case b.isCommand():
go b.resolveCommand()
case b.isCallbackCommand():
go b.resolveCallbackCommand()
}

// to do refactor
<-b.typingCh
err = <-b.commandCh

return err
}

func (b Bot) resolveCommand() error {
var err error

defer func() {
b.commandCh <- err
}()

data := b.HookData
name := data.Message.From.FirstName
chatId := data.Message.Chat.ID
text := data.Message.Text
arr := strings.Fields(text)

log.Printf("Yêu cầu từ bạn %s: %s", name, text)

tData := telegram.Data{
ChatId: chatId,
ChatType: "",
Username: "",
}

command := arr[0]

switch command {
case "/quote", "/quote@zerill_bot":
err = quote.SendAQuote(tData)
default:
// channel.SendMessage(chatId, "Tôi không hiểu câu lệnh của bạn !!!")
}

return nil
}

func (b Bot) resolveCallbackCommand() error {
return nil
}

func (b Bot) isCommand() bool {
return b.HookData.CallbackQuery.Data == ""
}

func (b Bot) isCallbackCommand() bool {
return b.HookData.CallbackQuery.Data != ""
}

func (b Bot) getApiURL() string {
return "https://api.telegram.org/bot" + os.Getenv("TELE_BOT_TOKEN")
}

func SendMessage(chatId int, message string) {
if chatType == "group" {
message = message + "\n@" + chatFrom.Username
Expand Down Expand Up @@ -168,10 +254,13 @@ func SendMessageWithReplyMarkup(chatId int, message string, replyMark []structs.
log.Println("SendMessageWithReplyMarkup OK")
}

func SetTypingAction(chatId int) {
uri := API_URL + "/sendChatAction"
req, err := http.NewRequest("GET", uri, nil)
func (b Bot) setTypingAction() {
defer close(b.typingCh)

url := b.getApiURL()
chatId := b.HookData.Message.Chat.ID

req, err := http.NewRequest("GET", url+"/sendChatAction", nil)
if err != nil {
log.Println(err)
return
Expand Down
47 changes: 34 additions & 13 deletions utils/middleware/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,14 @@ func PreRequest(next http.Handler) http.Handler {
func Recoverer(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
defer func() {
path := r.URL.Path
if path == "/trip" {
return
}

resp := make(map[string]string)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
// fmt.Println("After R")
if rvr := recover(); rvr != nil {
resp := make(map[string]string)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)

resp["status"] = "ERROR"
resp["message"] = rvr.(string)
jsonResp, _ := json.Marshal(resp)

logEntry := middleware.GetLogEntry(r)
if logEntry != nil {
Expand All @@ -84,15 +80,40 @@ func Recoverer(next http.Handler) http.Handler {
middleware.PrintPrettyStack(rvr)
}

} else {
resp["status"] = "OK"
w.Write(jsonResp)
}
jsonResp, _ := json.Marshal(resp)
w.Write(jsonResp)
}()

next.ServeHTTP(w, r)
}

return http.HandlerFunc(fn)
}

func Handle404NotFound() func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)

res := make(map[string]string)
res["status"] = "ERROR"
res["error"] = "http.error"
res["message"] = "route does not exist"

mRes, _ := json.Marshal(res)
w.Write(mRes)
}
}

func Handle405MethodNotAllowed() func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(405)

res := make(map[string]string)
res["status"] = "ERROR"
res["error"] = "http.error"
res["message"] = "method is not valid"

mRes, _ := json.Marshal(res)
w.Write(mRes)
}
}
28 changes: 17 additions & 11 deletions utils/quote/quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,41 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"zeril-bot/utils/channel"
"zeril-bot/utils/structs"
"zeril-bot/utils/telegram"
)

func SendAQuote(chatId int) {
quote := getAQuote()
func SendAQuote(data telegram.Data) error {
quote, err := getAQuote()
if err != nil {
return err
}

quoteFormat := fmt.Sprintf("&quot;%s&quot; - <b>%s</b>", quote.Quote, quote.Author)
channel.SendMessage(chatId, quoteFormat)
data.Message = quoteFormat

return telegram.SendMessage(data)
}

func getAQuote() structs.QuoteData {
func getAQuote() (*structs.QuoteData, error) {
res, err := http.Get("https://zenquotes.io/api/random")

if err != nil {
log.Panic(err)
return nil, err
}

defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}

var data []structs.QuoteData
err = json.Unmarshal(body, &data)

if err != nil {
log.Panic(err)
return nil, err
}

return data[0]
return &data[0], nil
}
Loading

0 comments on commit e596fe7

Please sign in to comment.