package internal import ( "context" "encoding/json" "fmt" "log" "os" "path/filepath" "exporter/config" "exporter/database/telegram_resource/public/model" "exporter/database/telegram_resource/public/table" "exporter/pkg/memos" . "github.com/go-jet/jet/v2/postgres" "github.com/pkg/errors" "github.com/spf13/cobra" ) func PublishCmd() *cobra.Command { cmd := &cobra.Command{ Use: "publish", Short: "publish posts", RunE: func(cmd *cobra.Command, args []string) error { for { if err := publishCmd(context.Background()); err != nil { log.Println("ERROR: ", err) return err } } }, } return cmd } type publishMsg struct { model.ChannelMessages model.Channels } func publishCmd(ctx context.Context) error { var msg publishMsg tbl := table.ChannelMessages tblC := table.Channels var maxIDResult struct { MaxID int64 } stmt := tbl.SELECT(MAX(tbl.ID).AS("maxID")).FROM(tbl) if err := stmt.QueryContext(context.Background(), db, &maxIDResult); err != nil { return errors.Wrap(err, "failed to get max id") } stmt = tbl.SELECT(tbl.AllColumns, tblC.Title). WHERE(tbl.Published.IS_FALSE().AND(tbl.ID.NOT_EQ(Int(maxIDResult.MaxID)))). LIMIT(1). ORDER_BY(tbl.UUID.ASC()). FROM(tbl.LEFT_JOIN(tblC, tbl.ChannelID.EQ(tblC.UUID))) if err := stmt.QueryContext(context.Background(), db, &msg); err != nil { return errors.Wrap(err, "failed to get message") } // publish item if err := publish(ctx, msg); err != nil { return errors.Wrapf(err, "failed to publish id: %d", msg.ChannelMessages.ID) } _, err := tbl.UPDATE().SET(tbl.Published.SET(Bool(true))).WHERE(tbl.ID.EQ(Int64(msg.ChannelMessages.ID))).ExecContext(ctx, db) if err != nil { return err } return nil } func publish(_ context.Context, msg publishMsg) error { memos.InitClient(config.C.PublishHost, config.C.PublishToken) data := memos.PostData{ Content: *msg.ChannelMessages.Content, ChannelID: msg.ChannelMessages.ChannelID, ChannelTitle: msg.Channels.Title, Resources: []memos.Resource{}, } var medias []ChannelMessageMedia if err := json.Unmarshal([]byte(msg.ChannelMessages.Media), &medias); err != nil { return errors.Wrap(err, "failed to unmarshal media") } for _, media := range medias { res := memos.Resource{} var file string if media.Photo != nil { res.Type = "image/jpeg" res.Filename = *media.Photo file = fmt.Sprintf("%d/%s", data.ChannelID, *media.Photo) } else if media.Document != nil { res.Type = media.Document.MimeType res.Filename = media.Document.Filename file = fmt.Sprintf("%d/%d%s", data.ChannelID, media.AssetID, media.Document.Ext) } else if media.WebPage != nil { data.Content += fmt.Sprintf("\n\n[%s](%s)", media.WebPage.Title, media.WebPage.URL) } else { continue } if file == "" { continue } filepath := filepath.Join(config.C.Output, file) b, err := os.ReadFile(filepath) if err != nil { return err } res.Content = b resource, err := memos.Upload(res) if err != nil { return err } data.Resources = append(data.Resources, resource) } return memos.Post(data) }