2026-06-26 08:37:04 +00:00
|
|
|
|
syntax = "v1"
|
|
|
|
|
|
|
|
|
|
|
|
type (
|
|
|
|
|
|
PlacementTopicData {
|
|
|
|
|
|
ID string `json:"id"`
|
|
|
|
|
|
BrandID string `json:"brand_id"`
|
|
|
|
|
|
BrandDisplayName string `json:"brand_display_name,omitempty"`
|
|
|
|
|
|
TopicName string `json:"topic_name,omitempty"`
|
|
|
|
|
|
SeedQuery string `json:"seed_query,omitempty"`
|
|
|
|
|
|
Brief string `json:"brief,omitempty"`
|
|
|
|
|
|
ProductID string `json:"product_id,omitempty"`
|
|
|
|
|
|
ResearchMap ResearchMapData `json:"research_map,omitempty"`
|
|
|
|
|
|
CreateAt int64 `json:"create_at"`
|
|
|
|
|
|
UpdateAt int64 `json:"update_at"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ListPlacementTopicsData {
|
|
|
|
|
|
List []PlacementTopicData `json:"list"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CreatePlacementTopicReq {
|
|
|
|
|
|
BrandID string `json:"brand_id" validate:"required"`
|
|
|
|
|
|
TopicName string `json:"topic_name" validate:"required"`
|
|
|
|
|
|
SeedQuery string `json:"seed_query" validate:"required"`
|
|
|
|
|
|
Brief string `json:"brief" validate:"required"`
|
|
|
|
|
|
ProductID string `json:"product_id,optional"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UpdatePlacementTopicReq {
|
|
|
|
|
|
BrandID *string `json:"brand_id,optional"`
|
|
|
|
|
|
TopicName *string `json:"topic_name,optional"`
|
|
|
|
|
|
SeedQuery *string `json:"seed_query,optional"`
|
|
|
|
|
|
Brief *string `json:"brief,optional"`
|
|
|
|
|
|
ProductID *string `json:"product_id,optional"`
|
|
|
|
|
|
AudienceSummary *string `json:"audience_summary,optional"`
|
|
|
|
|
|
ContentGoal *string `json:"content_goal,optional"`
|
|
|
|
|
|
Questions []string `json:"questions,optional"`
|
|
|
|
|
|
Pillars []string `json:"pillars,optional"`
|
|
|
|
|
|
Exclusions []string `json:"exclusions,optional"`
|
|
|
|
|
|
PatrolKeywords []string `json:"patrol_keywords,optional"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PlacementTopicPath {
|
|
|
|
|
|
ID string `path:"id" validate:"required"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UpdatePlacementTopicHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
UpdatePlacementTopicReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CreatePlacementTopicHandlerReq {
|
|
|
|
|
|
CreatePlacementTopicReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ExpandPlacementTopicGraphHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
ExpandKnowledgeGraphReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PatchPlacementTopicGraphNodesHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
PatchKnowledgeGraphNodesReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StartPlacementTopicScanJobHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
StartBrandScanJobReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ListPlacementTopicScanPostsHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
ListBrandScanPostsReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GeneratePlacementTopicOutreachDraftsHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
GenerateOutreachDraftsReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PublishPlacementTopicOutreachDraftHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
PublishOutreachDraftReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-06 06:13:14 +00:00
|
|
|
|
UpdatePlacementTopicOutreachDraftHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
DraftID string `path:"draftId" validate:"required"`
|
|
|
|
|
|
UpdateOutreachDraftReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-26 08:37:04 +00:00
|
|
|
|
PatchPlacementTopicScanPostOutreachHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
PostID string `path:"postId"`
|
|
|
|
|
|
PatchScanPostOutreachReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DeletePlacementTopicScanPostHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
PostID string `path:"postId" validate:"required"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BatchDeletePlacementTopicScanPostsReq {
|
|
|
|
|
|
PostIDs []string `json:"post_ids" validate:"required"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BatchDeletePlacementTopicScanPostsData {
|
|
|
|
|
|
DeletedCount int `json:"deleted_count"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BatchDeletePlacementTopicScanPostsHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
BatchDeletePlacementTopicScanPostsReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GeneratePlacementTopicContentMatrixHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
GenerateContentMatrixReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UpsertPlacementTopicScanScheduleHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
UpsertBrandScanScheduleReq
|
|
|
|
|
|
}
|
2026-07-06 06:13:14 +00:00
|
|
|
|
|
|
|
|
|
|
StartPlacementTopicOutreachDraftJobReq {
|
|
|
|
|
|
ScanPostID string `json:"scan_post_id,optional"`
|
|
|
|
|
|
ScanPostIDs []string `json:"scan_post_ids,optional"`
|
|
|
|
|
|
Count int `json:"count,optional"`
|
|
|
|
|
|
VoicePersonaID string `json:"voice_persona_id,optional"`
|
|
|
|
|
|
ProductID string `json:"product_id,optional"`
|
|
|
|
|
|
Regenerate bool `json:"regenerate,optional"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StartPlacementTopicOutreachDraftJobHandlerReq {
|
|
|
|
|
|
PlacementTopicPath
|
|
|
|
|
|
StartPlacementTopicOutreachDraftJobReq
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StartPlacementTopicOutreachDraftJobsData {
|
|
|
|
|
|
Jobs []StartBrandScanJobData `json:"jobs"`
|
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
|
}
|
2026-06-26 08:37:04 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@server(
|
|
|
|
|
|
group: placement_topic
|
|
|
|
|
|
prefix: /api/v1/placement/topics
|
|
|
|
|
|
middleware: AuthJWT
|
|
|
|
|
|
tags: "Placement Topic"
|
|
|
|
|
|
summary: "找 TA 主題;每個主題關聯一個品牌,一個品牌可有多個主題。Requires Bearer JWT."
|
|
|
|
|
|
)
|
|
|
|
|
|
service gateway {
|
|
|
|
|
|
@handler listPlacementTopics
|
|
|
|
|
|
get / returns (ListPlacementTopicsData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler createPlacementTopic
|
|
|
|
|
|
post / (CreatePlacementTopicHandlerReq) returns (PlacementTopicData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler getPlacementTopic
|
|
|
|
|
|
get /:id (PlacementTopicPath) returns (PlacementTopicData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler updatePlacementTopic
|
|
|
|
|
|
patch /:id (UpdatePlacementTopicHandlerReq) returns (PlacementTopicData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler deletePlacementTopic
|
|
|
|
|
|
delete /:id (PlacementTopicPath)
|
|
|
|
|
|
|
|
|
|
|
|
@handler expandPlacementTopicGraph
|
|
|
|
|
|
post /:id/knowledge-graph/expand (ExpandPlacementTopicGraphHandlerReq) returns (ExpandKnowledgeGraphData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler getPlacementTopicGraph
|
|
|
|
|
|
get /:id/knowledge-graph (PlacementTopicPath) returns (KnowledgeGraphData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler patchPlacementTopicGraphNodes
|
|
|
|
|
|
patch /:id/knowledge-graph/nodes (PatchPlacementTopicGraphNodesHandlerReq) returns (KnowledgeGraphData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler startPlacementTopicScanJob
|
|
|
|
|
|
post /:id/scan-jobs (StartPlacementTopicScanJobHandlerReq) returns (StartBrandScanJobData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler listPlacementTopicScanPosts
|
|
|
|
|
|
get /:id/scan-posts (ListPlacementTopicScanPostsHandlerReq) returns (ListBrandScanPostsData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler generatePlacementTopicOutreachDrafts
|
|
|
|
|
|
post /:id/outreach-drafts/generate (GeneratePlacementTopicOutreachDraftsHandlerReq) returns (GenerateOutreachDraftsData)
|
|
|
|
|
|
|
2026-07-06 06:13:14 +00:00
|
|
|
|
@handler startPlacementTopicOutreachDraftJob
|
|
|
|
|
|
post /:id/outreach-draft-jobs (StartPlacementTopicOutreachDraftJobHandlerReq) returns (StartPlacementTopicOutreachDraftJobsData)
|
|
|
|
|
|
|
2026-06-26 08:37:04 +00:00
|
|
|
|
@handler publishPlacementTopicOutreachDraft
|
|
|
|
|
|
post /:id/outreach-drafts/publish (PublishPlacementTopicOutreachDraftHandlerReq) returns (PublishOutreachDraftData)
|
|
|
|
|
|
|
2026-07-06 06:13:14 +00:00
|
|
|
|
@handler updatePlacementTopicOutreachDraft
|
|
|
|
|
|
patch /:id/outreach-drafts/:draftId (UpdatePlacementTopicOutreachDraftHandlerReq) returns (GenerateOutreachDraftsData)
|
|
|
|
|
|
|
2026-06-26 08:37:04 +00:00
|
|
|
|
@handler patchPlacementTopicScanPostOutreach
|
|
|
|
|
|
patch /:id/scan-posts/:postId (PatchPlacementTopicScanPostOutreachHandlerReq) returns (ScanPostData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler deletePlacementTopicScanPost
|
|
|
|
|
|
delete /:id/scan-posts/:postId (DeletePlacementTopicScanPostHandlerReq)
|
|
|
|
|
|
|
|
|
|
|
|
@handler batchDeletePlacementTopicScanPosts
|
|
|
|
|
|
post /:id/scan-posts/batch-delete (BatchDeletePlacementTopicScanPostsHandlerReq) returns (BatchDeletePlacementTopicScanPostsData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler getPlacementTopicContentMatrix
|
|
|
|
|
|
get /:id/content-matrix (PlacementTopicPath) returns (ContentMatrixData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler generatePlacementTopicContentMatrix
|
|
|
|
|
|
post /:id/content-matrix/generate (GeneratePlacementTopicContentMatrixHandlerReq) returns (ContentMatrixData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler getPlacementTopicScanSchedule
|
|
|
|
|
|
get /:id/scan-schedule (PlacementTopicPath) returns (BrandScanScheduleData)
|
|
|
|
|
|
|
|
|
|
|
|
@handler upsertPlacementTopicScanSchedule
|
|
|
|
|
|
put /:id/scan-schedule (UpsertPlacementTopicScanScheduleHandlerReq) returns (BrandScanScheduleData)
|
|
|
|
|
|
}
|