| 1 | import type { z } from 'zod' |
| 2 | import { Injectable } from '@nestjs/common' |
| 3 | import { getUser, toYamlTextResult } from '@yikart/common' |
| 4 | import { Tool } from '@yikart/nest-mcp' |
| 5 | import { ChannelAccountAnalyticsVo, ChannelWorkAnalyticsVo } from '../analytics/analytics.vo' |
| 6 | import { ChannelCommentListVo, ChannelEngagementActionVo } from '../engagement/engagement.vo' |
| 7 | import { ChannelPublishRecordVo } from '../publish/records/publish-record.vo' |
| 8 | import { ChannelWorkDataVo, ChannelWorkListVo, ChannelWorkOwnershipVo } from '../works/works.vo' |
| 9 | import { |
| 10 | CallChannelEngagementFunctionSchema, |
| 11 | ChannelPlatformSchema, |
| 12 | ChannelPublishTaskSchema, |
| 13 | ChannelWorkSchema, |
| 14 | CreateChannelPublishFlowSchema, |
| 15 | GetChannelAccountAnalyticsSchema, |
| 16 | GetChannelPublishRecordByFlowIdSchema, |
| 17 | GetChannelPublishRecordByRecordIdSchema, |
| 18 | GetChannelPublishRecordByTaskIdSchema, |
| 19 | GetChannelWorkLinkInfoSchema, |
| 20 | ListBilibiliChannelPlatformCategoriesSchema, |
| 21 | ListChannelEngagementCommentsSchema, |
| 22 | ListChannelPublishRecordsSchema, |
| 23 | ListChannelWorksSchema, |
| 24 | ListYoutubeChannelPlatformCategoriesSchema, |
| 25 | RequestChannelPublishUpdateSchema, |
| 26 | SubmitChannelEngagementCommentSchema, |
| 27 | UpdateChannelPublishAtSchema, |
| 28 | VerifyChannelWorkOwnershipSchema, |
| 29 | } from './channels-mcp.schema' |
| 30 | import { ChannelsMcpService } from './channels.mcp.service' |
| 31 | |
| 32 | @Injectable() |
| 33 | export class ChannelsMcpController { |
| 34 | constructor(private readonly channelsMcpService: ChannelsMcpService) {} |
| 35 | |
| 36 | @Tool({ |
| 37 | name: 'createChannelPublishFlow', |
| 38 | description: 'Create a channels publish flow with the v2 channels input shape. Side Effect: yes.', |
| 39 | parameters: CreateChannelPublishFlowSchema, |
| 40 | }) |
| 41 | async createChannelPublishFlow(params: z.infer<typeof CreateChannelPublishFlowSchema>) { |
| 42 | const user = getUser() |
| 43 | return toYamlTextResult(await this.channelsMcpService.createChannelPublishFlow(user.id, params)) |
| 44 | } |
| 45 | |
| 46 | @Tool({ |
| 47 | name: 'listChannelPublishRecords', |
| 48 | description: 'List channels publish records for the authenticated user.', |
| 49 | parameters: ListChannelPublishRecordsSchema, |
| 50 | }) |
| 51 | async listChannelPublishRecords(params: z.infer<typeof ListChannelPublishRecordsSchema>) { |
| 52 | const user = getUser() |
| 53 | const records = await this.channelsMcpService.listChannelPublishRecords(user.id, params) |
| 54 | return toYamlTextResult( |
| 55 | records.map(record => ChannelPublishRecordVo.create(record)), |
| 56 | ) |
| 57 | } |
| 58 | |
| 59 | @Tool({ |
| 60 | name: 'getChannelPublishRecordByRecordId', |
| 61 | description: 'Get one channels publish record by recordId.', |
| 62 | parameters: GetChannelPublishRecordByRecordIdSchema, |
| 63 | }) |
| 64 | async getChannelPublishRecordByRecordId(params: z.infer<typeof GetChannelPublishRecordByRecordIdSchema>) { |
| 65 | const user = getUser() |
| 66 | return toYamlTextResult( |
| 67 | ChannelPublishRecordVo.create(await this.channelsMcpService.getChannelPublishRecordByRecordId(user.id, params)), |
| 68 | ) |
| 69 | } |
| 70 | |
| 71 | @Tool({ |
| 72 | name: 'getChannelPublishRecordByTaskId', |
| 73 | description: 'Get one channels publish record by taskId.', |
| 74 | parameters: GetChannelPublishRecordByTaskIdSchema, |
| 75 | }) |
| 76 | async getChannelPublishRecordByTaskId(params: z.infer<typeof GetChannelPublishRecordByTaskIdSchema>) { |
| 77 | const user = getUser() |
| 78 | const record = await this.channelsMcpService.getChannelPublishRecordByTaskId(user.id, params) |
| 79 | return toYamlTextResult(record ? ChannelPublishRecordVo.create(record) : null) |
| 80 | } |
| 81 | |
| 82 | @Tool({ |
| 83 | name: 'getChannelPublishRecordByFlowId', |
| 84 | description: 'Get one channels publish record by flowId.', |
| 85 | parameters: GetChannelPublishRecordByFlowIdSchema, |
| 86 | }) |
| 87 | async getChannelPublishRecordByFlowId(params: z.infer<typeof GetChannelPublishRecordByFlowIdSchema>) { |
| 88 | const user = getUser() |
| 89 | return toYamlTextResult( |
| 90 | ChannelPublishRecordVo.create(await this.channelsMcpService.getChannelPublishRecordByFlowId(user.id, params)), |
| 91 | ) |
| 92 | } |
| 93 | |
| 94 | @Tool({ |
| 95 | name: 'publishChannelTaskNow', |
| 96 | description: 'Publish a channels task immediately. Side Effect: yes.', |
| 97 | parameters: ChannelPublishTaskSchema, |
| 98 | }) |
| 99 | async publishChannelTaskNow(params: z.infer<typeof ChannelPublishTaskSchema>) { |
| 100 | const user = getUser() |
| 101 | return toYamlTextResult(await this.channelsMcpService.publishChannelTaskNow(user.id, params)) |
| 102 | } |
| 103 | |
| 104 | @Tool({ |
| 105 | name: 'cancelChannelPublishTask', |
| 106 | description: 'Cancel a channels publish task. Side Effect: yes.', |
| 107 | parameters: ChannelPublishTaskSchema, |
| 108 | }) |
| 109 | async cancelChannelPublishTask(params: z.infer<typeof ChannelPublishTaskSchema>) { |
| 110 | const user = getUser() |
| 111 | return toYamlTextResult(await this.channelsMcpService.cancelChannelPublishTask(user.id, params)) |
| 112 | } |
| 113 | |
| 114 | @Tool({ |
| 115 | name: 'updateChannelPublishAt', |
| 116 | description: 'Update a channels publish task publish time. Side Effect: yes.', |
| 117 | parameters: UpdateChannelPublishAtSchema, |
| 118 | }) |
| 119 | async updateChannelPublishAt(params: z.infer<typeof UpdateChannelPublishAtSchema>) { |
| 120 | const user = getUser() |
| 121 | return toYamlTextResult(await this.channelsMcpService.updateChannelPublishAt(user.id, params)) |
| 122 | } |
| 123 | |
| 124 | @Tool({ |
| 125 | name: 'requestChannelPublishUpdate', |
| 126 | description: 'Request an update for a published channels task using the v2 update data shape. Side Effect: yes.', |
| 127 | parameters: RequestChannelPublishUpdateSchema, |
| 128 | }) |
| 129 | async requestChannelPublishUpdate(params: z.infer<typeof RequestChannelPublishUpdateSchema>) { |
| 130 | const user = getUser() |
| 131 | return toYamlTextResult(await this.channelsMcpService.requestChannelPublishUpdate(user.id, params)) |
| 132 | } |
| 133 | |
| 134 | @Tool({ |
| 135 | name: 'listChannelPlatforms', |
| 136 | description: 'List channels platform metadata, capabilities, publish limits, and option schemas.', |
| 137 | parameters: undefined, |
| 138 | }) |
| 139 | async listChannelPlatforms() { |
| 140 | return toYamlTextResult(await this.channelsMcpService.listChannelPlatforms()) |
| 141 | } |
| 142 | |
| 143 | @Tool({ |
| 144 | name: 'getChannelPlatform', |
| 145 | description: 'Get one channels platform metadata entry.', |
| 146 | parameters: ChannelPlatformSchema, |
| 147 | }) |
| 148 | async getChannelPlatform(params: z.infer<typeof ChannelPlatformSchema>) { |
| 149 | return toYamlTextResult(await this.channelsMcpService.getChannelPlatform(params)) |
| 150 | } |
| 151 | |
| 152 | @Tool({ |
| 153 | name: 'listBilibiliChannelPlatformCategories', |
| 154 | description: 'List Bilibili content categories currently supported by channels MCP.', |
| 155 | parameters: ListBilibiliChannelPlatformCategoriesSchema, |
| 156 | }) |
| 157 | async listBilibiliChannelPlatformCategories(params: z.infer<typeof ListBilibiliChannelPlatformCategoriesSchema>) { |
| 158 | const user = getUser() |
| 159 | return toYamlTextResult(await this.channelsMcpService.listBilibiliChannelPlatformCategories(user.id, params)) |
| 160 | } |
| 161 | |
| 162 | @Tool({ |
| 163 | name: 'listYoutubeChannelPlatformCategories', |
| 164 | description: 'List YouTube content categories currently supported by channels MCP.', |
| 165 | parameters: ListYoutubeChannelPlatformCategoriesSchema, |
| 166 | }) |
| 167 | async listYoutubeChannelPlatformCategories(params: z.infer<typeof ListYoutubeChannelPlatformCategoriesSchema>) { |
| 168 | const user = getUser() |
| 169 | return toYamlTextResult(await this.channelsMcpService.listYoutubeChannelPlatformCategories(user.id, params)) |
| 170 | } |
| 171 | |
| 172 | @Tool({ |
| 173 | name: 'getChannelWorkLinkInfo', |
| 174 | description: 'Resolve a work link through the channels work provider.', |
| 175 | parameters: GetChannelWorkLinkInfoSchema, |
| 176 | }) |
| 177 | async getChannelWorkLinkInfo(params: z.infer<typeof GetChannelWorkLinkInfoSchema>) { |
| 178 | const user = getUser() |
| 179 | return toYamlTextResult( |
| 180 | ChannelWorkDataVo.create(await this.channelsMcpService.getChannelWorkLinkInfo(user.id, params)), |
| 181 | ) |
| 182 | } |
| 183 | |
| 184 | @Tool({ |
| 185 | name: 'listChannelWorks', |
| 186 | description: 'List works for a platform account through the channels work provider.', |
| 187 | parameters: ListChannelWorksSchema, |
| 188 | }) |
| 189 | async listChannelWorks(params: z.infer<typeof ListChannelWorksSchema>) { |
| 190 | const user = getUser() |
| 191 | return toYamlTextResult( |
| 192 | ChannelWorkListVo.create(await this.channelsMcpService.listChannelWorks(user.id, params)), |
| 193 | ) |
| 194 | } |
| 195 | |
| 196 | @Tool({ |
| 197 | name: 'getChannelWorkDetail', |
| 198 | description: 'Get a platform work detail through the channels work provider.', |
| 199 | parameters: ChannelWorkSchema, |
| 200 | }) |
| 201 | async getChannelWorkDetail(params: z.infer<typeof ChannelWorkSchema>) { |
| 202 | const user = getUser() |
| 203 | return toYamlTextResult( |
| 204 | ChannelWorkDataVo.create(await this.channelsMcpService.getChannelWorkDetail(user.id, params)), |
| 205 | ) |
| 206 | } |
| 207 | |
| 208 | @Tool({ |
| 209 | name: 'verifyChannelWorkOwnership', |
| 210 | description: 'Verify whether a platform work belongs to a candidate channels account.', |
| 211 | parameters: VerifyChannelWorkOwnershipSchema, |
| 212 | }) |
| 213 | async verifyChannelWorkOwnership(params: z.infer<typeof VerifyChannelWorkOwnershipSchema>) { |
| 214 | const user = getUser() |
| 215 | return toYamlTextResult( |
| 216 | ChannelWorkOwnershipVo.create(await this.channelsMcpService.verifyChannelWorkOwnership(user.id, params)), |
| 217 | ) |
| 218 | } |
| 219 | |
| 220 | @Tool({ |
| 221 | name: 'getChannelAccountAnalytics', |
| 222 | description: 'Get channels account analytics through the platform analytics provider.', |
| 223 | parameters: GetChannelAccountAnalyticsSchema, |
| 224 | }) |
| 225 | async getChannelAccountAnalytics(params: z.infer<typeof GetChannelAccountAnalyticsSchema>) { |
| 226 | const user = getUser() |
| 227 | return toYamlTextResult( |
| 228 | ChannelAccountAnalyticsVo.create(await this.channelsMcpService.getChannelAccountAnalytics(user.id, params)), |
| 229 | ) |
| 230 | } |
| 231 | |
| 232 | @Tool({ |
| 233 | name: 'getChannelWorkAnalytics', |
| 234 | description: 'Get channels work analytics through the platform analytics provider.', |
| 235 | parameters: ChannelWorkSchema, |
| 236 | }) |
| 237 | async getChannelWorkAnalytics(params: z.infer<typeof ChannelWorkSchema>) { |
| 238 | const user = getUser() |
| 239 | return toYamlTextResult( |
| 240 | ChannelWorkAnalyticsVo.create(await this.channelsMcpService.getChannelWorkAnalytics(user.id, params)), |
| 241 | ) |
| 242 | } |
| 243 | |
| 244 | @Tool({ |
| 245 | name: 'listChannelEngagementComments', |
| 246 | description: 'List comments for a platform work through the channels engagement provider.', |
| 247 | parameters: ListChannelEngagementCommentsSchema, |
| 248 | }) |
| 249 | async listChannelEngagementComments(params: z.infer<typeof ListChannelEngagementCommentsSchema>) { |
| 250 | const user = getUser() |
| 251 | return toYamlTextResult( |
| 252 | ChannelCommentListVo.create(await this.channelsMcpService.listChannelEngagementComments(user.id, params)), |
| 253 | ) |
| 254 | } |
| 255 | |
| 256 | @Tool({ |
| 257 | name: 'submitChannelEngagementComment', |
| 258 | description: 'Create a comment for a platform work through the channels engagement provider. Side Effect: yes.', |
| 259 | parameters: SubmitChannelEngagementCommentSchema, |
| 260 | }) |
| 261 | async submitChannelEngagementComment(params: z.infer<typeof SubmitChannelEngagementCommentSchema>) { |
| 262 | const user = getUser() |
| 263 | return toYamlTextResult( |
| 264 | ChannelEngagementActionVo.create(await this.channelsMcpService.submitChannelEngagementComment(user.id, params)), |
| 265 | ) |
| 266 | } |
| 267 | |
| 268 | @Tool({ |
| 269 | name: 'callChannelEngagementFunction', |
| 270 | description: 'Call a channels engagement function. Side Effect: yes. data fields: delete_comment/hide_reply/unhide_reply use commentId; like/unlike/repost/undo_repost/bookmark/remove_bookmark use platformWorkId; quote uses platformWorkId and content; follow/unfollow use targetPlatformUid.', |
| 271 | parameters: CallChannelEngagementFunctionSchema, |
| 272 | }) |
| 273 | async callChannelEngagementFunction(params: z.infer<typeof CallChannelEngagementFunctionSchema>) { |
| 274 | const user = getUser() |
| 275 | return toYamlTextResult( |
| 276 | ChannelEngagementActionVo.create(await this.channelsMcpService.callChannelEngagementFunction(user.id, params)), |
| 277 | ) |
| 278 | } |
| 279 | } |
| 280 |