82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
|
|
package job
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
libthreads "haixun-backend/internal/library/threadsapi"
|
||
|
|
jobdom "haixun-backend/internal/model/job/domain/usecase"
|
||
|
|
publishanalyticsdomain "haixun-backend/internal/model/publish_analytics/domain/usecase"
|
||
|
|
threadsaccountdomain "haixun-backend/internal/model/threads_account/domain/usecase"
|
||
|
|
)
|
||
|
|
|
||
|
|
type PublishAnalyticsDeps struct {
|
||
|
|
Jobs jobdom.UseCase
|
||
|
|
ThreadsAccount threadsaccountdomain.UseCase
|
||
|
|
PublishAnalytics publishanalyticsdomain.UseCase
|
||
|
|
}
|
||
|
|
|
||
|
|
func RegisterPublishAnalyticsHandler(runner *Runner, deps PublishAnalyticsDeps) {
|
||
|
|
if runner == nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
runner.RegisterStepHandler("check", func(ctx context.Context, step StepContext) error {
|
||
|
|
return runPublishAnalyticsCheck(ctx, step, deps)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func runPublishAnalyticsCheck(ctx context.Context, step StepContext, deps PublishAnalyticsDeps) error {
|
||
|
|
payload := step.Run.Payload
|
||
|
|
tenantID, ownerUID := runActorFromPayload(payload, step.Run)
|
||
|
|
mediaID := strings.TrimSpace(stringField(payload, "media_id"))
|
||
|
|
checkpoint := strings.TrimSpace(stringField(payload, "checkpoint"))
|
||
|
|
permalink := strings.TrimSpace(stringField(payload, "permalink"))
|
||
|
|
publishedAt := int64Field(payload, "published_at")
|
||
|
|
if mediaID == "" || checkpoint == "" {
|
||
|
|
return fmt.Errorf("publish-analytics payload missing media_id or checkpoint")
|
||
|
|
}
|
||
|
|
|
||
|
|
cred, err := deps.ThreadsAccount.ResolveMemberThreadsPublishCredential(ctx, tenantID, ownerUID)
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("resolve publish credential: %w", err)
|
||
|
|
}
|
||
|
|
if cred == nil || cred.AccessToken == "" {
|
||
|
|
return fmt.Errorf("no access token found")
|
||
|
|
}
|
||
|
|
|
||
|
|
stats, err := libthreads.GetMediaStats(ctx, cred.AccessToken, mediaID)
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("get media stats: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
saved, err := deps.PublishAnalytics.RecordCheckpoint(ctx, tenantID, ownerUID, publishanalyticsdomain.PublishAnalyticsSummary{
|
||
|
|
MediaID: mediaID,
|
||
|
|
Permalink: permalink,
|
||
|
|
PublishedAt: publishedAt,
|
||
|
|
Checkpoint: checkpoint,
|
||
|
|
LikeCount: stats.LikeCount,
|
||
|
|
ReplyCount: stats.ReplyCount,
|
||
|
|
RepostCount: stats.RepostCount,
|
||
|
|
QuoteCount: stats.QuoteCount,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("record checkpoint: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
_, err = deps.Jobs.CompleteRun(ctx, jobdom.CompleteRunRequest{
|
||
|
|
JobID: step.JobID,
|
||
|
|
WorkerID: step.WorkerID,
|
||
|
|
Result: map[string]any{
|
||
|
|
"media_id": mediaID,
|
||
|
|
"checkpoint": checkpoint,
|
||
|
|
"like_count": saved.LikeCount,
|
||
|
|
"reply_count": saved.ReplyCount,
|
||
|
|
"repost_count": saved.RepostCount,
|
||
|
|
"quote_count": saved.QuoteCount,
|
||
|
|
"analytics_id": saved.ID,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
return err
|
||
|
|
}
|