All checks were successful
Docker Build / build-and-push-image (push) Successful in 1m8s
76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type Server struct {
|
|
registry *Registry
|
|
}
|
|
|
|
func NewServer(r *Registry) *Server {
|
|
return &Server{registry: r}
|
|
}
|
|
|
|
func (s *Server) Routes() http.Handler {
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/healthz", s.health)
|
|
mux.HandleFunc("/readyz", s.ready)
|
|
mux.HandleFunc("/bot/", s.botWebhook)
|
|
return chain(mux, recoverMW, accessLogMW)
|
|
}
|
|
|
|
func (s *Server) health(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = fmt.Fprint(w, "OK")
|
|
}
|
|
|
|
func (s *Server) ready(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = fmt.Fprint(w, "OK")
|
|
}
|
|
|
|
func (s *Server) botWebhook(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
|
|
slug := strings.TrimPrefix(r.URL.Path, "/bot/")
|
|
slug = strings.Trim(slug, "/")
|
|
if slug == "" || strings.Contains(slug, "/") {
|
|
http.Error(w, "bot slug missing or malformed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
bot, ok := s.registry.Get(slug)
|
|
if !ok {
|
|
http.Error(w, "unknown bot", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
if !verifyTelegramSecret(r.Header.Get("X-Telegram-Bot-Api-Secret-Token"), bot.Secret) {
|
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
var update Update
|
|
dec := json.NewDecoder(r.Body)
|
|
dec.DisallowUnknownFields()
|
|
if err := dec.Decode(&update); err != nil {
|
|
http.Error(w, "bad update payload", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if err := bot.Handler.Handle(r.Context(), update, bot); err != nil {
|
|
log.Printf("bot=%s update=%d handler error: %v", slug, update.UpdateID, err)
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = fmt.Fprint(w, "{}")
|
|
}
|