98 lines
3.2 KiB
Go
98 lines
3.2 KiB
Go
package job
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
liboutreach "haixun-backend/internal/library/outreach"
|
|
aiusecase "haixun-backend/internal/model/ai/usecase"
|
|
branddomain "haixun-backend/internal/model/brand/domain/usecase"
|
|
jobdom "haixun-backend/internal/model/job/domain/usecase"
|
|
kgdomain "haixun-backend/internal/model/knowledge_graph/domain/usecase"
|
|
outreachdraftdomain "haixun-backend/internal/model/outreach_draft/domain/usecase"
|
|
personadomain "haixun-backend/internal/model/persona/domain/usecase"
|
|
scanpostdomain "haixun-backend/internal/model/scan_post/domain/usecase"
|
|
threadsaccountdomain "haixun-backend/internal/model/threads_account/domain/usecase"
|
|
)
|
|
|
|
type GenerateOutreachDraftDeps struct {
|
|
Jobs jobdom.UseCase
|
|
Brand branddomain.UseCase
|
|
Persona personadomain.UseCase
|
|
ScanPost scanpostdomain.UseCase
|
|
KnowledgeGraph kgdomain.UseCase
|
|
ThreadsAccount threadsaccountdomain.UseCase
|
|
AI aiusecase.UseCase
|
|
OutreachDraft outreachdraftdomain.UseCase
|
|
}
|
|
|
|
func RegisterGenerateOutreachDraftHandler(runner *Runner, deps GenerateOutreachDraftDeps) {
|
|
if runner == nil {
|
|
return
|
|
}
|
|
runner.RegisterStepHandler("outreach_draft_generate", func(ctx context.Context, step StepContext) error {
|
|
return runGenerateOutreachDraft(ctx, step, deps)
|
|
})
|
|
}
|
|
|
|
func runGenerateOutreachDraft(ctx context.Context, step StepContext, deps GenerateOutreachDraftDeps) error {
|
|
payload := step.Run.Payload
|
|
tenantID, ownerUID := runActorFromPayload(payload, step.Run)
|
|
brandID := stringField(payload, "brand_id")
|
|
topicID := stringField(payload, "topic_id")
|
|
scanPostID := stringField(payload, "scan_post_id")
|
|
voicePersonaID := stringField(payload, "voice_persona_id")
|
|
if tenantID == "" || ownerUID == "" || brandID == "" || scanPostID == "" || voicePersonaID == "" {
|
|
return fmt.Errorf("generate-outreach-draft payload missing tenant_id, owner_uid, brand_id, scan_post_id, or voice_persona_id")
|
|
}
|
|
|
|
updateProgress := func(summary string, percentage int) {
|
|
_ = step.Heartbeat(ctx)
|
|
_, _ = deps.Jobs.UpdateProgress(ctx, jobdom.UpdateProgressRequest{
|
|
JobID: step.JobID,
|
|
WorkerID: step.WorkerID,
|
|
Phase: "outreach_draft_generate",
|
|
Summary: summary,
|
|
Percentage: percentage,
|
|
})
|
|
}
|
|
|
|
updateProgress("讀取貼文與產品脈絡…", 15)
|
|
updateProgress("呼叫 AI 生成獲客草稿…", 45)
|
|
|
|
count := intField(payload, "count")
|
|
if count <= 0 {
|
|
count = 3
|
|
}
|
|
|
|
regenerate := false
|
|
if v, ok := payload["regenerate"].(bool); ok {
|
|
regenerate = v
|
|
}
|
|
|
|
_, err := liboutreach.GenerateDraft(ctx, liboutreach.GenerateDraftDeps{
|
|
Brand: deps.Brand,
|
|
Persona: deps.Persona,
|
|
ScanPost: deps.ScanPost,
|
|
KnowledgeGraph: deps.KnowledgeGraph,
|
|
ThreadsAccount: deps.ThreadsAccount,
|
|
AI: deps.AI,
|
|
OutreachDraft: deps.OutreachDraft,
|
|
}, liboutreach.GenerateDraftRequest{
|
|
TenantID: tenantID,
|
|
OwnerUID: ownerUID,
|
|
BrandID: brandID,
|
|
TopicID: topicID,
|
|
ScanPostID: scanPostID,
|
|
Count: count,
|
|
VoicePersonaID: voicePersonaID,
|
|
ProductID: stringField(payload, "product_id"),
|
|
Regenerate: regenerate,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
updateProgress("草稿已寫入", 100)
|
|
return nil
|
|
}
|