package internal import ( "fmt" "strconv" "exporter/database/telegram_resource/public/model" "exporter/database/telegram_resource/public/table" . "github.com/go-jet/jet/v2/postgres" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/spf13/cobra" ) type Pagination struct { Page int64 `json:"page"` Limit int64 `json:"limit"` Offset int64 `json:"-"` } func (p *Pagination) Format() { if p.Limit == 0 { p.Limit = 10 } if p.Page == 0 { p.Offset = 0 } else { p.Offset = (p.Page - 1) * p.Limit } } func ServeCmd() *cobra.Command { cmd := &cobra.Command{ Use: "serve", Short: "http server", RunE: serveCmd, } return cmd } func serveCmd(cmd *cobra.Command, args []string) error { var err error var port int64 = 3000 if len(args) > 0 { port, err = strconv.ParseInt(args[0], 10, 64) if err != nil { return err } } app := fiber.New() app.Static("/medias", "/share/telegram/outputs") app.Static("/", "/public") // Initialize default config app.Use(recover.New()) group := app.Group("/api") // get channel list group.Get("/channels", func(c *fiber.Ctx) error { var channels []model.Channels tbl := table.Channels if err := tbl.SELECT(tbl.AllColumns).QueryContext(c.Context(), db, &channels); err != nil { return err } return c.JSON(channels) }) // get channel info group.Get("/channels/:channel", func(c *fiber.Ctx) error { channelID, err := c.ParamsInt("channel") if err != nil { return err } var channel model.Channels tbl := table.Channels err = tbl. SELECT(tbl.AllColumns). WHERE(tbl.UUID.EQ(Int64(int64(channelID)))). QueryContext(c.Context(), db, &channel) if err != nil { return err } return c.JSON(channel) }) // get channel's post list group.Get("/channels/:channel/messages", func(c *fiber.Ctx) error { channelID, err := c.ParamsInt("channel") if err != nil { return err } var p Pagination if err := c.QueryParser(&p); err != nil { return err } p.Format() var messages []model.ChannelMessages tbl := table.ChannelMessages err = tbl. SELECT(tbl.AllColumns). WHERE(tbl.ChannelID.EQ(Int64(int64(channelID)))). ORDER_BY(tbl.ID.DESC()). LIMIT(p.Limit). OFFSET(p.Offset). QueryContext(c.Context(), db, &messages) if err != nil { return err } return c.JSON(messages) }) // favorite messages group.Get("/favorites", func(c *fiber.Ctx) error { var p Pagination if err := c.QueryParser(&p); err != nil { return err } p.Format() var messages []model.ChannelMessages tbl := table.ChannelMessages err = tbl. SELECT(tbl.AllColumns). WHERE( tbl.ChannelID.EQ(Int64(int64(channelID))).AND( tbl.Like.EQ(Bool(true)), ), ). ORDER_BY(tbl.ID.DESC()). LIMIT(p.Limit). OFFSET(p.Offset). QueryContext(c.Context(), db, &messages) if err != nil { return err } return c.JSON(messages) }) // toggle favorite message group.Patch("message/:message/favorite", func(c *fiber.Ctx) error { messageID, err := c.ParamsInt("message") if err != nil { return err } var msg model.ChannelMessages tbl := table.ChannelMessages err = tbl. SELECT(tbl.AllColumns). WHERE(tbl.ID.EQ(Int64(int64(messageID)))). ORDER_BY(tbl.ID.DESC()). LIMIT(1). QueryContext(c.Context(), db, &msg) if err != nil { return err } _, err = tbl. UPDATE(). SET(tbl.Like.SET(Bool(!msg.Like))). WHERE(tbl.ID.EQ(Int64(int64(messageID)))). ExecContext(c.Context(), db) if err != nil { return err } return nil }) // delete message group.Delete("/messages/:message", func(c *fiber.Ctx) error { msgID, err := c.ParamsInt("message") if err != nil { return err } tbl := table.ChannelMessages _, err = tbl. DELETE(). WHERE(tbl.ID.EQ(Int64(int64(msgID)))). ExecContext(c.Context(), db) if err != nil { return err } return nil }) return app.Listen(fmt.Sprintf(":%d", port)) }