thread-master/backend/internal/logic/persona/publish_persona_copy_draft_...

108 lines
3.1 KiB
Go

package persona
import (
"context"
"strings"
app "haixun-backend/internal/library/errors"
"haixun-backend/internal/library/errors/code"
libthreads "haixun-backend/internal/library/threadsapi"
"haixun-backend/internal/library/threadspost"
copydraftdomain "haixun-backend/internal/model/copy_draft/domain/usecase"
"haixun-backend/internal/svc"
"haixun-backend/internal/types"
)
type PublishPersonaCopyDraftLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewPublishPersonaCopyDraftLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PublishPersonaCopyDraftLogic {
return &PublishPersonaCopyDraftLogic{ctx: ctx, svcCtx: svcCtx}
}
func (l *PublishPersonaCopyDraftLogic) PublishPersonaCopyDraft(
req *types.PublishCopyDraftHandlerReq,
) (*types.PublishCopyDraftData, error) {
tenantID, uid, err := actorFrom(l.ctx)
if err != nil {
return nil, err
}
personaID := strings.TrimSpace(req.ID)
draftID := strings.TrimSpace(req.DraftID)
if !req.Confirm {
return nil, app.For(code.Persona).InputMissingRequired("請確認 confirm=true 後再發布貼文")
}
if _, err := l.svcCtx.Persona.Get(l.ctx, tenantID, uid, personaID); err != nil {
return nil, err
}
draftItem, err := l.svcCtx.CopyDraft.Get(l.ctx, tenantID, uid, personaID, draftID)
if err != nil {
return nil, err
}
draft := draftItem
if draft.Status == "published" {
return nil, app.For(code.Persona).ResInvalidState("此草稿已發布")
}
text := strings.TrimSpace(req.Text)
if text == "" {
text = strings.TrimSpace(draft.Text)
}
if text == "" {
return nil, app.For(code.Persona).InputMissingRequired("text is required")
}
if err := threadspost.ValidatePublish(text); err != nil {
return nil, app.For(code.Persona).InputInvalidFormat(err.Error())
}
if strings.TrimSpace(req.Text) != "" && req.Text != draft.Text {
updatedText, err := l.svcCtx.CopyDraft.Update(l.ctx, copydraftdomain.UpdateRequest{
TenantID: tenantID,
OwnerUID: uid,
PersonaID: personaID,
DraftID: draftID,
Patch: copydraftdomain.CopyDraftPatch{Text: &req.Text},
})
if err != nil {
return nil, err
}
draft = updatedText
text = strings.TrimSpace(updatedText.Text)
}
cred, err := l.svcCtx.ThreadsAccount.ResolveMemberThreadsPublishCredential(l.ctx, tenantID, uid)
if err != nil {
return nil, err
}
result, err := libthreads.PublishText(l.ctx, libthreads.PublishTextInput{
ThreadsUserID: cred.ThreadsUserID,
AccessToken: cred.AccessToken,
Text: text,
})
if err != nil {
return nil, app.For(code.ThreadsAccount).SvcThirdParty("Threads API 發布貼文失敗:" + err.Error())
}
updated, err := l.svcCtx.CopyDraft.MarkPublished(l.ctx, copydraftdomain.MarkPublishedRequest{
TenantID: tenantID,
OwnerUID: uid,
PersonaID: personaID,
DraftID: draftID,
MediaID: result.MediaID,
Permalink: result.Permalink,
})
if err != nil {
return nil, err
}
return &types.PublishCopyDraftData{
DraftID: draftID,
MediaID: result.MediaID,
Permalink: result.Permalink,
Status: updated.Status,
Message: "仿寫貼文已透過 Threads API 發布",
}, nil
}