package httpserver import ( "context" "encoding/json" "net/http" "strings" "github.com/TelegramExchange/tgex-backend/tg_parser/internal/usecase" "github.com/gotd/td/tgerr" "github.com/rs/zerolog/log" ) type Server struct { httpServer *http.Server } func New(uc *usecase.UseCase, addr string) *Server { mux := http.NewServeMux() mux.HandleFunc("/fetch-telegram-channel", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } username := strings.TrimSpace(r.URL.Query().Get("username")) username = strings.TrimPrefix(username, "@") if username == "" { http.Error(w, "missing username", http.StatusBadRequest) return } channel, err := uc.FetchChannelMeta(r.Context(), username) if err != nil { if isNotFoundError(err) { http.Error(w, "channel not found", http.StatusNotFound) return } log.Error().Err(err).Str("username", username).Msg("fetch channel meta failed") http.Error(w, "internal error", http.StatusInternalServerError) return } resp := struct { ID string `json:"id"` TelegramID int64 `json:"telegram_id"` Username string `json:"username"` Title string `json:"title"` AccessHash int64 `json:"access_hash"` Pts int `json:"pts"` }{ ID: channel.ID.String(), TelegramID: channel.TelegramID, Username: channel.Username, Title: channel.Title, AccessHash: channel.AccessHash, Pts: channel.Pts, } w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(resp); err != nil { log.Error().Err(err).Msg("encode channel response") } }) return &Server{ httpServer: &http.Server{ Addr: addr, Handler: mux, }, } } func (s *Server) ListenAndServe() error { return s.httpServer.ListenAndServe() } func (s *Server) Shutdown(ctx context.Context) error { return s.httpServer.Shutdown(ctx) } func isNotFoundError(err error) bool { if tgerr.Is(err, "USERNAME_NOT_OCCUPIED", "USERNAME_INVALID", "CHANNEL_INVALID", "CHANNEL_PRIVATE") { return true } msg := err.Error() return strings.Contains(msg, "no chats in resolve result") || strings.Contains(msg, "not a channel") }