This commit is contained in:
parent
f923429b96
commit
cff74a8319
@ -16,6 +16,7 @@ type AyrshareProvider struct {
|
||||
aryshareMessageLogic logic.IAryshareMessage
|
||||
aryshareCommentLogic logic.IAryshareComment
|
||||
aryshareAnalyticsLogic logic.IAryshareAnalytics
|
||||
aryshareTagLogic logic.IAryshareTag
|
||||
}
|
||||
|
||||
// NewAyrshareProvider 创建 AyrshareProvider 实例
|
||||
@ -28,6 +29,7 @@ func NewAyrshareProvider() *AyrshareProvider {
|
||||
aryshareMessageLogic: &logic.AyrshareMessage{},
|
||||
aryshareCommentLogic: &logic.AyrshareComment{},
|
||||
aryshareAnalyticsLogic: &logic.AyrshareAnalytics{},
|
||||
aryshareTagLogic: &logic.AyrshareTag{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
174
internal/controller/aryshare_tag.go
Normal file
174
internal/controller/aryshare_tag.go
Normal file
@ -0,0 +1,174 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"micro-ayrshare/internal/dto"
|
||||
"micro-ayrshare/pb/aryshare"
|
||||
)
|
||||
|
||||
// AutoHashtags 自动为帖子添加合适的标签
|
||||
// 将 proto 请求转换为 DTO,调用 logic 层,然后再组装回 proto 响应。
|
||||
func (a *AyrshareProvider) AutoHashtags(_ context.Context, req *aryshare.AutoHashtagsRequest) (res *aryshare.AutoHashtagsResponse, err error) {
|
||||
res = new(aryshare.AutoHashtagsResponse)
|
||||
|
||||
// 组装 DTO 请求
|
||||
dtoReq := &dto.AutoHashtagsRequest{
|
||||
Post: req.Post,
|
||||
Position: req.Position,
|
||||
Language: req.Language,
|
||||
ProfileKey: req.ProfileKey,
|
||||
}
|
||||
if req.Max != 0 {
|
||||
max := int(req.Max)
|
||||
dtoReq.Max = &max
|
||||
}
|
||||
|
||||
// 调用 logic 层
|
||||
dtoRes, err := a.aryshareTagLogic.AutoHashtags(dtoReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 组装 proto 响应
|
||||
res.Post = dtoRes.Post
|
||||
res.Action = dtoRes.Action
|
||||
res.Status = dtoRes.Status
|
||||
res.Code = int32(dtoRes.Code)
|
||||
res.Message = dtoRes.Message
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CheckBannedHashtag 查看某个标签是否被平台禁用
|
||||
func (a *AyrshareProvider) CheckBannedHashtag(_ context.Context, req *aryshare.CheckBannedHashtagRequest) (res *aryshare.CheckBannedHashtagResponse, err error) {
|
||||
res = new(aryshare.CheckBannedHashtagResponse)
|
||||
|
||||
// 组装 DTO 请求
|
||||
dtoReq := &dto.CheckBannedHashtagRequest{
|
||||
Hashtag: req.Hashtag,
|
||||
ProfileKey: req.ProfileKey,
|
||||
}
|
||||
|
||||
// 调用 logic 层
|
||||
dtoRes, err := a.aryshareTagLogic.CheckBannedHashtag(dtoReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 组装 proto 响应
|
||||
res.Hashtag = dtoRes.Hashtag
|
||||
res.Banned = dtoRes.Banned
|
||||
res.Action = dtoRes.Action
|
||||
res.Status = dtoRes.Status
|
||||
res.Code = int32(dtoRes.Code)
|
||||
res.Message = dtoRes.Message
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RecommendHashtags 根据关键字推荐热门标签
|
||||
func (a *AyrshareProvider) RecommendHashtags(_ context.Context, req *aryshare.RecommendHashtagsRequest) (res *aryshare.RecommendHashtagsResponse, err error) {
|
||||
res = new(aryshare.RecommendHashtagsResponse)
|
||||
|
||||
// 组装 DTO 请求
|
||||
dtoReq := &dto.RecommendHashtagsRequest{
|
||||
Keyword: req.Keyword,
|
||||
ProfileKey: req.ProfileKey,
|
||||
}
|
||||
|
||||
// 调用 logic 层
|
||||
dtoRes, err := a.aryshareTagLogic.RecommendHashtags(dtoReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 组装 proto 响应
|
||||
res.Keyword = dtoRes.Keyword
|
||||
res.Action = dtoRes.Action
|
||||
res.Status = dtoRes.Status
|
||||
res.Code = int32(dtoRes.Code)
|
||||
res.Message = dtoRes.Message
|
||||
|
||||
// 转换推荐列表
|
||||
if len(dtoRes.Recommendations) > 0 {
|
||||
res.Recommendations = make([]*aryshare.HashtagRecommendation, 0, len(dtoRes.Recommendations))
|
||||
for _, r := range dtoRes.Recommendations {
|
||||
res.Recommendations = append(res.Recommendations, &aryshare.HashtagRecommendation{
|
||||
ViewCount: r.ViewCount,
|
||||
Name: r.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SearchHashtags 搜索话题标签,返回对应的 Instagram 媒体数据
|
||||
func (a *AyrshareProvider) SearchHashtags(_ context.Context, req *aryshare.SearchHashtagsRequest) (res *aryshare.SearchHashtagsResponse, err error) {
|
||||
res = new(aryshare.SearchHashtagsResponse)
|
||||
|
||||
// 组装 DTO 请求
|
||||
dtoReq := &dto.SearchHashtagsRequest{
|
||||
Keyword: req.Keyword,
|
||||
SearchType: req.SearchType,
|
||||
ProfileKey: req.ProfileKey,
|
||||
}
|
||||
|
||||
// 调用 logic 层
|
||||
dtoRes, err := a.aryshareTagLogic.SearchHashtags(dtoReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 组装 proto 响应
|
||||
res.Status = dtoRes.Status
|
||||
res.Count = int32(dtoRes.Count)
|
||||
res.LastUpdated = dtoRes.LastUpdated
|
||||
res.NextUpdate = dtoRes.NextUpdate
|
||||
res.Action = dtoRes.Action
|
||||
res.Code = int32(dtoRes.ErrorCode)
|
||||
res.Message = dtoRes.Message
|
||||
|
||||
// 转换 hashtag 基本信息
|
||||
if dtoRes.Hashtag != nil {
|
||||
res.Hashtag = &aryshare.SearchHashtagInfo{
|
||||
Id: dtoRes.Hashtag.ID,
|
||||
Name: dtoRes.Hashtag.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// 转换 searchResults 列表
|
||||
if len(dtoRes.SearchResults) > 0 {
|
||||
res.SearchResults = make([]*aryshare.SearchHashtagMedia, 0, len(dtoRes.SearchResults))
|
||||
for _, media := range dtoRes.SearchResults {
|
||||
protoMedia := &aryshare.SearchHashtagMedia{
|
||||
Caption: media.Caption,
|
||||
CommentsCount: int32(media.CommentsCount),
|
||||
Id: media.ID,
|
||||
LikeCount: int32(media.LikeCount),
|
||||
MediaType: media.MediaType,
|
||||
MediaUrl: media.MediaUrl,
|
||||
Permalink: media.Permalink,
|
||||
Timestamp: media.Timestamp,
|
||||
}
|
||||
|
||||
// 转换 children
|
||||
if media.Children != nil && len(media.Children.Data) > 0 {
|
||||
children := &aryshare.SearchHashtagChildren{
|
||||
Data: make([]*aryshare.SearchHashtagChild, 0, len(media.Children.Data)),
|
||||
}
|
||||
for _, child := range media.Children.Data {
|
||||
children.Data = append(children.Data, &aryshare.SearchHashtagChild{
|
||||
Id: child.ID,
|
||||
})
|
||||
}
|
||||
protoMedia.Children = children
|
||||
}
|
||||
|
||||
res.SearchResults = append(res.SearchResults, protoMedia)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
125
internal/dto/aryshare_tag.go
Normal file
125
internal/dto/aryshare_tag.go
Normal file
@ -0,0 +1,125 @@
|
||||
package dto
|
||||
|
||||
// AutoHashtagsRequest 自动生成标签请求参数
|
||||
// 对应 Ayrshare 接口文档: https://www.ayrshare.com/docs/apis/hashtags/auto-hashtags
|
||||
type AutoHashtagsRequest struct {
|
||||
Post string `json:"post"` // 必填,原始帖子内容,最大长度 1000 字符
|
||||
Max *int `json:"max,omitempty"` // 可选,生成的最大标签数量,1-10,默认 2
|
||||
Position string `json:"position,omitempty"` // 可选,标签插入位置,例如 "auto"
|
||||
Language string `json:"language,omitempty"` // 可选,帖子语言代码,例如 "en"、"fr"
|
||||
ProfileKey string `json:"-"` // 可选,多用户场景下的 Profile Key,通过请求头传递
|
||||
}
|
||||
|
||||
// AutoHashtagsResponse 自动生成标签返回结果
|
||||
// 正常情况仅返回替换后的 post;出错时返回 action/status/code/message
|
||||
// 参考 internal/dto/自动标签返回参数.md
|
||||
type AutoHashtagsResponse struct {
|
||||
Post string `json:"post,omitempty"` // 自动补全标签后的帖子内容
|
||||
|
||||
// 错误相关字段(当调用失败时会返回)
|
||||
Action string `json:"action,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Code int `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// CheckBannedHashtagRequest 查看被禁用标签请求
|
||||
// 对应 Ayrshare 接口文档: https://www.ayrshare.com/docs/apis/hashtags/check-hashtags
|
||||
type CheckBannedHashtagRequest struct {
|
||||
Hashtag string `json:"-"` // 必填,要检查的标签,例如 "bikinibody" 或 "#bikinibody"
|
||||
ProfileKey string `json:"-"` // 可选,多用户场景下的 Profile Key,通过请求头传递
|
||||
}
|
||||
|
||||
// CheckBannedHashtagResponse 查看被禁用标签返回结果
|
||||
// 参考 internal/dto/查看被禁用的标签返回参数.md
|
||||
type CheckBannedHashtagResponse struct {
|
||||
Hashtag string `json:"hashtag,omitempty"` // 请求的标签
|
||||
Banned bool `json:"banned,omitempty"` // 是否被禁用
|
||||
|
||||
// 出错时的通用返回结构
|
||||
Action string `json:"action,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Code int `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// HashtagRecommendation 单条推荐标签信息
|
||||
// 对应 Ayrshare Recommend Hashtags 返回中的 recommendations 数组元素
|
||||
type HashtagRecommendation struct {
|
||||
ViewCount int64 `json:"viewCount"` // 推荐标签在 TikTok 上的浏览次数
|
||||
Name string `json:"name"` // 推荐的标签名称(不带 #)
|
||||
}
|
||||
|
||||
// RecommendHashtagsRequest 推荐话题标签请求
|
||||
// 对应 Ayrshare 接口文档: https://www.ayrshare.com/docs/apis/hashtags/recommend-hashtags
|
||||
type RecommendHashtagsRequest struct {
|
||||
Keyword string `json:"-"` // 必填,单个关键字,例如 "apple"
|
||||
ProfileKey string `json:"-"` // 可选,多用户场景下的 Profile Key,通过请求头传递
|
||||
}
|
||||
|
||||
// RecommendHashtagsResponse 推荐话题标签返回结果
|
||||
// 参考 internal/dto/推荐话话题返回参数.md
|
||||
type RecommendHashtagsResponse struct {
|
||||
Keyword string `json:"keyword,omitempty"` // 请求时的关键字
|
||||
Recommendations []HashtagRecommendation `json:"recommendations,omitempty"` // 推荐的标签列表
|
||||
|
||||
// 出错时的通用返回结构
|
||||
Action string `json:"action,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Code int `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// SearchHashtagsRequest 搜索话题标签请求
|
||||
// 对应 Ayrshare 接口文档: https://www.ayrshare.com/docs/apis/hashtags/search-hashtags
|
||||
type SearchHashtagsRequest struct {
|
||||
Keyword string `json:"-"` // 必填,要搜索的关键字,例如 "wisdom"
|
||||
SearchType string `json:"-"` // 可选,搜索类型:top 或 recent,不传则使用服务端默认 top
|
||||
ProfileKey string `json:"-"` // 可选,多用户场景下的 Profile Key,通过请求头传递
|
||||
}
|
||||
|
||||
// SearchHashtagInfo 单个话题标签的基本信息
|
||||
type SearchHashtagInfo struct {
|
||||
ID string `json:"id"` // Hashtag ID
|
||||
Name string `json:"name"` // Hashtag 名称,例如 "wisdom"
|
||||
}
|
||||
|
||||
// SearchHashtagChild 搜索结果中 children.data 的元素
|
||||
type SearchHashtagChild struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// SearchHashtagChildren 搜索结果中的 children 对象
|
||||
type SearchHashtagChildren struct {
|
||||
Data []SearchHashtagChild `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// SearchHashtagMedia 搜索结果中的单条 Instagram 媒体信息
|
||||
// 参考 internal/dto/搜索话题标签返回参数.md
|
||||
type SearchHashtagMedia struct {
|
||||
Caption string `json:"caption"` // 媒体文案
|
||||
Children *SearchHashtagChildren `json:"children,omitempty"` // 多图时的子媒体 ID 列表
|
||||
CommentsCount int `json:"commentsCount"` // 评论数
|
||||
ID string `json:"id"` // 媒体 ID
|
||||
LikeCount int `json:"likeCount"` // 点赞数
|
||||
MediaType string `json:"mediaType"` // 媒体类型,例如 CAROUSEL_ALBUM
|
||||
MediaUrl string `json:"mediaUrl"` // 媒体封面 URL
|
||||
Permalink string `json:"permalink"` // Instagram 详情页链接
|
||||
Timestamp string `json:"timestamp"` // 发布时间
|
||||
}
|
||||
|
||||
// SearchHashtagsResponse 搜索话题标签响应
|
||||
// 参考 internal/dto/搜索话题标签返回参数.md
|
||||
type SearchHashtagsResponse struct {
|
||||
Status string `json:"status,omitempty"` // 请求状态:success 或 error
|
||||
Hashtag *SearchHashtagInfo `json:"hashtag,omitempty"` // 命中的 hashtag 信息
|
||||
SearchResults []SearchHashtagMedia `json:"searchResults,omitempty"` // 搜索结果媒体列表
|
||||
Count int `json:"count,omitempty"` // 返回结果条数
|
||||
LastUpdated string `json:"lastUpdated,omitempty"` // 最后更新时间
|
||||
NextUpdate string `json:"nextUpdate,omitempty"` // 下次更新时间
|
||||
|
||||
// 出错时的通用返回结构(情况二)
|
||||
Action string `json:"action,omitempty"`
|
||||
ErrorCode int `json:"code,omitempty"` // 错误码,为避免与正常字段冲突,这里使用不同的结构字段名
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
318
internal/logic/aryshare_tag.go
Normal file
318
internal/logic/aryshare_tag.go
Normal file
@ -0,0 +1,318 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
errCommon "micro-ayrshare/pkg/err"
|
||||
"micro-ayrshare/pkg/msg"
|
||||
|
||||
"micro-ayrshare/internal/dto"
|
||||
"micro-ayrshare/pkg/app"
|
||||
"micro-ayrshare/pkg/utils"
|
||||
)
|
||||
|
||||
// IAryshareTag Hashtags 相关业务接口
|
||||
// 封装 Ayrshare 的自动标签 / 禁用标签检查 / 推荐标签 / 搜索标签 四个接口
|
||||
type IAryshareTag interface {
|
||||
// AutoHashtags 自动为帖子添加合适的标签
|
||||
AutoHashtags(req *dto.AutoHashtagsRequest) (res *dto.AutoHashtagsResponse, err error)
|
||||
// CheckBannedHashtag 检查单个标签是否被社交平台禁用
|
||||
CheckBannedHashtag(req *dto.CheckBannedHashtagRequest) (res *dto.CheckBannedHashtagResponse, err error)
|
||||
// RecommendHashtags 根据关键字推荐热门标签
|
||||
RecommendHashtags(req *dto.RecommendHashtagsRequest) (res *dto.RecommendHashtagsResponse, err error)
|
||||
// SearchHashtags 搜索话题标签并返回相关媒体
|
||||
SearchHashtags(req *dto.SearchHashtagsRequest) (res *dto.SearchHashtagsResponse, err error)
|
||||
}
|
||||
|
||||
// AyrshareTag Hashtags 相关逻辑实现
|
||||
type AyrshareTag struct {
|
||||
}
|
||||
|
||||
// AutoHashtags 自动为帖子添加合适的标签
|
||||
// 文档: https://www.ayrshare.com/docs/apis/hashtags/auto-hashtags
|
||||
func (a *AyrshareTag) AutoHashtags(req *dto.AutoHashtagsRequest) (res *dto.AutoHashtagsResponse, err error) {
|
||||
errCommon.NoReturnInfo(req, "自动生成标签 参数信息: ")
|
||||
|
||||
res = new(dto.AutoHashtagsResponse)
|
||||
|
||||
// 基本参数校验:post 不能为空,其它参数交给 Ayrshare 校验,便于兼容后续扩展
|
||||
if req.Post == "" {
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf(msg.ErrPostContentEmpty),
|
||||
msg.ErrPostContentEmpty,
|
||||
"自动生成标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
// 构建请求 URL
|
||||
urlStr := fmt.Sprintf("%s/api/hashtags/auto", app.ModuleClients.AryshareClient.Config.Endpoint)
|
||||
|
||||
// 准备请求体(ProfileKey 使用请求头传递,因此结构体中使用 json:\"-\" 排除)
|
||||
reqBody, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorJSONMarshal, "自动生成标签失败: ")
|
||||
}
|
||||
|
||||
// 准备请求头
|
||||
headers := make(map[string]string)
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", app.ModuleClients.AryshareClient.Config.ApiKey)
|
||||
if req.ProfileKey != "" {
|
||||
headers["Profile-Key"] = req.ProfileKey
|
||||
}
|
||||
|
||||
// 发起 HTTP 请求
|
||||
statusCode, result, err := utils.PostWithHeaders(urlStr, reqBody, headers)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorAutoHashtagsFailed, "自动生成标签失败: ")
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var autoResp dto.AutoHashtagsResponse
|
||||
if err := json.Unmarshal([]byte(result), &autoResp); err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorJSONParse, "自动生成标签失败: ")
|
||||
}
|
||||
|
||||
// Ayrshare 文档未明确错误时的 HTTP 状态码,这里统一按照:
|
||||
// - 200 且未返回 status=error 视为成功
|
||||
// - 其它情况视为失败,并优先使用返回的 message/code 作为错误信息
|
||||
if statusCode != http.StatusOK || autoResp.Status == "error" {
|
||||
errMsg := autoResp.Message
|
||||
if errMsg == "" {
|
||||
errMsg = msg.ErrorAutoHashtagsFailed
|
||||
}
|
||||
if autoResp.Code != 0 {
|
||||
errMsg = fmt.Sprintf("错误代码: %d, %s", autoResp.Code, errMsg)
|
||||
}
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf("接口返回状态码: %d, 错误信息: %s, 响应结果: %s", statusCode, errMsg, result),
|
||||
errMsg,
|
||||
"自动生成标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
errCommon.NoReturnInfo(&autoResp, "自动生成标签 成功: ")
|
||||
res = &autoResp
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CheckBannedHashtag 检查单个标签是否被社交平台禁用
|
||||
// 文档: https://www.ayrshare.com/docs/apis/hashtags/check-hashtags
|
||||
func (a *AyrshareTag) CheckBannedHashtag(req *dto.CheckBannedHashtagRequest) (res *dto.CheckBannedHashtagResponse, err error) {
|
||||
errCommon.NoReturnInfo(req, "查看被禁用的标签 参数信息: ")
|
||||
|
||||
res = new(dto.CheckBannedHashtagResponse)
|
||||
|
||||
// 基本参数校验:hashtag 不能为空
|
||||
if req.Hashtag == "" {
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf(msg.ErrHashtagEmpty),
|
||||
msg.ErrHashtagEmpty,
|
||||
"查看被禁用的标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
// 构建请求 URL 和查询参数
|
||||
baseURL := fmt.Sprintf("%s/api/hashtags/banned", app.ModuleClients.AryshareClient.Config.Endpoint)
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorParseURL, "查看被禁用的标签 失败: ")
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
// Ayrshare 支持传入 "hashtag" 或 "#hashtag",这里直接透传,由底层接口校验
|
||||
q.Set("hashtag", req.Hashtag)
|
||||
u.RawQuery = q.Encode()
|
||||
fullURL := u.String()
|
||||
|
||||
// 准备请求头
|
||||
headers := make(map[string]string)
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", app.ModuleClients.AryshareClient.Config.ApiKey)
|
||||
if req.ProfileKey != "" {
|
||||
headers["Profile-Key"] = req.ProfileKey
|
||||
}
|
||||
|
||||
// 发起 HTTP 请求
|
||||
statusCode, result, err := utils.GetWithHeaders(fullURL, headers)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorCheckBannedHashtagsFailed, "查看被禁用的标签失败: ")
|
||||
}
|
||||
|
||||
// 解析响应(无论成功还是失败,Ayrshare 都会返回 JSON)
|
||||
var bannedResp dto.CheckBannedHashtagResponse
|
||||
if err := json.Unmarshal([]byte(result), &bannedResp); err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorJSONParse, "查看被禁用的标签失败: ")
|
||||
}
|
||||
|
||||
// 根据文档:
|
||||
// - 200:成功,返回 { "hashtag": "...", "banned": true/false }
|
||||
// - 400:参数错误,返回 { "action": "request", "status": "error", "code": 101, "message": "..." }
|
||||
if statusCode != http.StatusOK || bannedResp.Status == "error" {
|
||||
errMsg := bannedResp.Message
|
||||
if errMsg == "" {
|
||||
errMsg = msg.ErrorCheckBannedHashtagsFailed
|
||||
}
|
||||
if bannedResp.Code != 0 {
|
||||
errMsg = fmt.Sprintf("错误代码: %d, %s", bannedResp.Code, errMsg)
|
||||
}
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf("接口返回状态码: %d, 错误信息: %s, 响应结果: %s", statusCode, errMsg, result),
|
||||
errMsg,
|
||||
"查看被禁用的标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
errCommon.NoReturnInfo(&bannedResp, "查看被禁用的标签 成功: ")
|
||||
res = &bannedResp
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RecommendHashtags 根据关键字推荐热门标签
|
||||
// 文档: https://www.ayrshare.com/docs/apis/hashtags/recommend-hashtags
|
||||
func (a *AyrshareTag) RecommendHashtags(req *dto.RecommendHashtagsRequest) (res *dto.RecommendHashtagsResponse, err error) {
|
||||
errCommon.NoReturnInfo(req, "推荐话题标签 参数信息: ")
|
||||
|
||||
res = new(dto.RecommendHashtagsResponse)
|
||||
|
||||
// 基本参数校验:keyword 不能为空
|
||||
if req.Keyword == "" {
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf(msg.ErrKeywordEmpty),
|
||||
msg.ErrKeywordEmpty,
|
||||
"推荐话题标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
// 构建请求 URL 和查询参数
|
||||
baseURL := fmt.Sprintf("%s/api/hashtags/recommend", app.ModuleClients.AryshareClient.Config.Endpoint)
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorParseURL, "推荐话题标签 失败: ")
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
q.Set("keyword", req.Keyword)
|
||||
u.RawQuery = q.Encode()
|
||||
fullURL := u.String()
|
||||
|
||||
// 准备请求头
|
||||
headers := make(map[string]string)
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", app.ModuleClients.AryshareClient.Config.ApiKey)
|
||||
if req.ProfileKey != "" {
|
||||
headers["Profile-Key"] = req.ProfileKey
|
||||
}
|
||||
|
||||
// 发起 HTTP 请求
|
||||
statusCode, result, err := utils.GetWithHeaders(fullURL, headers)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorRecommendHashtagsFailed, "推荐话题标签失败: ")
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var recommendResp dto.RecommendHashtagsResponse
|
||||
if err := json.Unmarshal([]byte(result), &recommendResp); err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorJSONParse, "推荐话题标签失败: ")
|
||||
}
|
||||
|
||||
// 根据文档:
|
||||
// - 200:成功,返回 keyword + recommendations
|
||||
// - 400:缺少 keyword,返回错误结构
|
||||
if statusCode != http.StatusOK || recommendResp.Status == "error" {
|
||||
errMsg := recommendResp.Message
|
||||
if errMsg == "" {
|
||||
errMsg = msg.ErrorRecommendHashtagsFailed
|
||||
}
|
||||
if recommendResp.Code != 0 {
|
||||
errMsg = fmt.Sprintf("错误代码: %d, %s", recommendResp.Code, errMsg)
|
||||
}
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf("接口返回状态码: %d, 错误信息: %s, 响应结果: %s", statusCode, errMsg, result),
|
||||
errMsg,
|
||||
"推荐话题标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
errCommon.NoReturnInfo(&recommendResp, "推荐话题标签 成功: ")
|
||||
res = &recommendResp
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SearchHashtags 搜索话题标签并返回相关媒体
|
||||
// 文档: https://www.ayrshare.com/docs/apis/hashtags/search-hashtags
|
||||
func (a *AyrshareTag) SearchHashtags(req *dto.SearchHashtagsRequest) (res *dto.SearchHashtagsResponse, err error) {
|
||||
errCommon.NoReturnInfo(req, "搜索话题标签 参数信息: ")
|
||||
|
||||
res = new(dto.SearchHashtagsResponse)
|
||||
|
||||
// 基本参数校验:keyword 不能为空
|
||||
if req.Keyword == "" {
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf(msg.ErrKeywordEmpty),
|
||||
msg.ErrKeywordEmpty,
|
||||
"搜索话题标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
// 构建请求 URL 和查询参数
|
||||
baseURL := fmt.Sprintf("%s/api/hashtags/search", app.ModuleClients.AryshareClient.Config.Endpoint)
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorParseURL, "搜索话题标签 失败: ")
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
q.Set("keyword", req.Keyword)
|
||||
// searchType 可选,默认 top,这里仅在调用方传入时追加
|
||||
if req.SearchType != "" {
|
||||
q.Set("searchType", req.SearchType)
|
||||
}
|
||||
u.RawQuery = q.Encode()
|
||||
fullURL := u.String()
|
||||
|
||||
// 准备请求头
|
||||
headers := make(map[string]string)
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", app.ModuleClients.AryshareClient.Config.ApiKey)
|
||||
if req.ProfileKey != "" {
|
||||
headers["Profile-Key"] = req.ProfileKey
|
||||
}
|
||||
|
||||
// 发起 HTTP 请求
|
||||
statusCode, result, err := utils.GetWithHeaders(fullURL, headers)
|
||||
if err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorSearchHashtagsFailed, "搜索话题标签失败: ")
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var searchResp dto.SearchHashtagsResponse
|
||||
if err := json.Unmarshal([]byte(result), &searchResp); err != nil {
|
||||
return nil, errCommon.ReturnError(err, msg.ErrorJSONParse, "搜索话题标签失败: ")
|
||||
}
|
||||
|
||||
// 根据文档:
|
||||
// - 200:成功,返回 status: success + hashtag + searchResults
|
||||
// - 400:Bad Request,返回 status: error + action/code/message
|
||||
if statusCode != http.StatusOK || searchResp.Status == "error" {
|
||||
errMsg := searchResp.Message
|
||||
if errMsg == "" {
|
||||
errMsg = msg.ErrorSearchHashtagsFailed
|
||||
}
|
||||
if searchResp.ErrorCode != 0 {
|
||||
errMsg = fmt.Sprintf("错误代码: %d, %s", searchResp.ErrorCode, errMsg)
|
||||
}
|
||||
return nil, errCommon.ReturnError(
|
||||
fmt.Errorf("接口返回状态码: %d, 错误信息: %s, 响应结果: %s", statusCode, errMsg, result),
|
||||
errMsg,
|
||||
"搜索话题标签 失败: ",
|
||||
)
|
||||
}
|
||||
|
||||
errCommon.NoReturnInfo(&searchResp, "搜索话题标签 成功: ")
|
||||
res = &searchResp
|
||||
|
||||
return
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -816,3 +816,85 @@ func (this *GetSocialAnalyticsRequest) Validate() error {
|
||||
func (this *GetSocialAnalyticsResponse) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *AutoHashtagsRequest) Validate() error {
|
||||
if this.Post == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Post", fmt.Errorf(`post内容不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *AutoHashtagsResponse) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *CheckBannedHashtagRequest) Validate() error {
|
||||
if this.Hashtag == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Hashtag", fmt.Errorf(`hashtag不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *CheckBannedHashtagResponse) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *HashtagRecommendation) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *RecommendHashtagsRequest) Validate() error {
|
||||
if this.Keyword == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Keyword", fmt.Errorf(`keyword不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *RecommendHashtagsResponse) Validate() error {
|
||||
for _, item := range this.Recommendations {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Recommendations", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *SearchHashtagsRequest) Validate() error {
|
||||
if this.Keyword == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Keyword", fmt.Errorf(`keyword不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *SearchHashtagInfo) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *SearchHashtagChild) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *SearchHashtagChildren) Validate() error {
|
||||
for _, item := range this.Data {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Data", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *SearchHashtagMedia) Validate() error {
|
||||
if this.Children != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Children); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Children", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *SearchHashtagsResponse) Validate() error {
|
||||
if this.Hashtag != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Hashtag); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Hashtag", err)
|
||||
}
|
||||
}
|
||||
for _, item := range this.SearchResults {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("SearchResults", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -53,6 +53,11 @@ type AyrshareClient interface {
|
||||
GetPostAnalytics(ctx context.Context, in *GetPostAnalyticsRequest, opts ...grpc_go.CallOption) (*GetPostAnalyticsResponse, common.ErrorWithAttachment)
|
||||
GetPostAnalyticsBySocialID(ctx context.Context, in *GetPostAnalyticsBySocialIDRequest, opts ...grpc_go.CallOption) (*GetPostAnalyticsResponse, common.ErrorWithAttachment)
|
||||
GetSocialAnalytics(ctx context.Context, in *GetSocialAnalyticsRequest, opts ...grpc_go.CallOption) (*GetSocialAnalyticsResponse, common.ErrorWithAttachment)
|
||||
// Hashtags 相关 api
|
||||
AutoHashtags(ctx context.Context, in *AutoHashtagsRequest, opts ...grpc_go.CallOption) (*AutoHashtagsResponse, common.ErrorWithAttachment)
|
||||
CheckBannedHashtag(ctx context.Context, in *CheckBannedHashtagRequest, opts ...grpc_go.CallOption) (*CheckBannedHashtagResponse, common.ErrorWithAttachment)
|
||||
RecommendHashtags(ctx context.Context, in *RecommendHashtagsRequest, opts ...grpc_go.CallOption) (*RecommendHashtagsResponse, common.ErrorWithAttachment)
|
||||
SearchHashtags(ctx context.Context, in *SearchHashtagsRequest, opts ...grpc_go.CallOption) (*SearchHashtagsResponse, common.ErrorWithAttachment)
|
||||
}
|
||||
|
||||
type ayrshareClient struct {
|
||||
@ -78,6 +83,10 @@ type AyrshareClientImpl struct {
|
||||
GetPostAnalytics func(ctx context.Context, in *GetPostAnalyticsRequest) (*GetPostAnalyticsResponse, error)
|
||||
GetPostAnalyticsBySocialID func(ctx context.Context, in *GetPostAnalyticsBySocialIDRequest) (*GetPostAnalyticsResponse, error)
|
||||
GetSocialAnalytics func(ctx context.Context, in *GetSocialAnalyticsRequest) (*GetSocialAnalyticsResponse, error)
|
||||
AutoHashtags func(ctx context.Context, in *AutoHashtagsRequest) (*AutoHashtagsResponse, error)
|
||||
CheckBannedHashtag func(ctx context.Context, in *CheckBannedHashtagRequest) (*CheckBannedHashtagResponse, error)
|
||||
RecommendHashtags func(ctx context.Context, in *RecommendHashtagsRequest) (*RecommendHashtagsResponse, error)
|
||||
SearchHashtags func(ctx context.Context, in *SearchHashtagsRequest) (*SearchHashtagsResponse, error)
|
||||
}
|
||||
|
||||
func (c *AyrshareClientImpl) GetDubboStub(cc *triple.TripleConn) AyrshareClient {
|
||||
@ -200,6 +209,30 @@ func (c *ayrshareClient) GetSocialAnalytics(ctx context.Context, in *GetSocialAn
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetSocialAnalytics", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) AutoHashtags(ctx context.Context, in *AutoHashtagsRequest, opts ...grpc_go.CallOption) (*AutoHashtagsResponse, common.ErrorWithAttachment) {
|
||||
out := new(AutoHashtagsResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/AutoHashtags", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) CheckBannedHashtag(ctx context.Context, in *CheckBannedHashtagRequest, opts ...grpc_go.CallOption) (*CheckBannedHashtagResponse, common.ErrorWithAttachment) {
|
||||
out := new(CheckBannedHashtagResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/CheckBannedHashtag", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) RecommendHashtags(ctx context.Context, in *RecommendHashtagsRequest, opts ...grpc_go.CallOption) (*RecommendHashtagsResponse, common.ErrorWithAttachment) {
|
||||
out := new(RecommendHashtagsResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/RecommendHashtags", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) SearchHashtags(ctx context.Context, in *SearchHashtagsRequest, opts ...grpc_go.CallOption) (*SearchHashtagsResponse, common.ErrorWithAttachment) {
|
||||
out := new(SearchHashtagsResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/SearchHashtags", in, out)
|
||||
}
|
||||
|
||||
// AyrshareServer is the server API for Ayrshare service.
|
||||
// All implementations must embed UnimplementedAyrshareServer
|
||||
// for forward compatibility
|
||||
@ -229,6 +262,11 @@ type AyrshareServer interface {
|
||||
GetPostAnalytics(context.Context, *GetPostAnalyticsRequest) (*GetPostAnalyticsResponse, error)
|
||||
GetPostAnalyticsBySocialID(context.Context, *GetPostAnalyticsBySocialIDRequest) (*GetPostAnalyticsResponse, error)
|
||||
GetSocialAnalytics(context.Context, *GetSocialAnalyticsRequest) (*GetSocialAnalyticsResponse, error)
|
||||
// Hashtags 相关 api
|
||||
AutoHashtags(context.Context, *AutoHashtagsRequest) (*AutoHashtagsResponse, error)
|
||||
CheckBannedHashtag(context.Context, *CheckBannedHashtagRequest) (*CheckBannedHashtagResponse, error)
|
||||
RecommendHashtags(context.Context, *RecommendHashtagsRequest) (*RecommendHashtagsResponse, error)
|
||||
SearchHashtags(context.Context, *SearchHashtagsRequest) (*SearchHashtagsResponse, error)
|
||||
mustEmbedUnimplementedAyrshareServer()
|
||||
}
|
||||
|
||||
@ -291,6 +329,18 @@ func (UnimplementedAyrshareServer) GetPostAnalyticsBySocialID(context.Context, *
|
||||
func (UnimplementedAyrshareServer) GetSocialAnalytics(context.Context, *GetSocialAnalyticsRequest) (*GetSocialAnalyticsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetSocialAnalytics not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) AutoHashtags(context.Context, *AutoHashtagsRequest) (*AutoHashtagsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AutoHashtags not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) CheckBannedHashtag(context.Context, *CheckBannedHashtagRequest) (*CheckBannedHashtagResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CheckBannedHashtag not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) RecommendHashtags(context.Context, *RecommendHashtagsRequest) (*RecommendHashtagsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RecommendHashtags not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) SearchHashtags(context.Context, *SearchHashtagsRequest) (*SearchHashtagsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SearchHashtags not implemented")
|
||||
}
|
||||
func (s *UnimplementedAyrshareServer) XXX_SetProxyImpl(impl protocol.Invoker) {
|
||||
s.proxyImpl = impl
|
||||
}
|
||||
@ -841,6 +891,122 @@ func _Ayrshare_GetSocialAnalytics_Handler(srv interface{}, ctx context.Context,
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_AutoHashtags_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AutoHashtagsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("AutoHashtags", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_CheckBannedHashtag_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CheckBannedHashtagRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("CheckBannedHashtag", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_RecommendHashtags_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RecommendHashtagsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("RecommendHashtags", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_SearchHashtags_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SearchHashtagsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("SearchHashtags", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Ayrshare_ServiceDesc is the grpc_go.ServiceDesc for Ayrshare service.
|
||||
// It's only intended for direct use with grpc_go.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@ -920,6 +1086,22 @@ var Ayrshare_ServiceDesc = grpc_go.ServiceDesc{
|
||||
MethodName: "GetSocialAnalytics",
|
||||
Handler: _Ayrshare_GetSocialAnalytics_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AutoHashtags",
|
||||
Handler: _Ayrshare_AutoHashtags_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CheckBannedHashtag",
|
||||
Handler: _Ayrshare_CheckBannedHashtag_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RecommendHashtags",
|
||||
Handler: _Ayrshare_RecommendHashtags_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SearchHashtags",
|
||||
Handler: _Ayrshare_SearchHashtags_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc_go.StreamDesc{},
|
||||
Metadata: "pb/ayrshare.proto",
|
||||
|
||||
@ -38,6 +38,12 @@ service Ayrshare {
|
||||
rpc GetPostAnalytics(GetPostAnalyticsRequest) returns (GetPostAnalyticsResponse);
|
||||
rpc GetPostAnalyticsBySocialID(GetPostAnalyticsBySocialIDRequest) returns (GetPostAnalyticsResponse);
|
||||
rpc GetSocialAnalytics(GetSocialAnalyticsRequest) returns (GetSocialAnalyticsResponse);
|
||||
|
||||
// Hashtags 相关 api
|
||||
rpc AutoHashtags(AutoHashtagsRequest) returns (AutoHashtagsResponse);
|
||||
rpc CheckBannedHashtag(CheckBannedHashtagRequest) returns (CheckBannedHashtagResponse);
|
||||
rpc RecommendHashtags(RecommendHashtagsRequest) returns (RecommendHashtagsResponse);
|
||||
rpc SearchHashtags(SearchHashtagsRequest) returns (SearchHashtagsResponse);
|
||||
}
|
||||
|
||||
// Instagram 用户标签(带坐标)
|
||||
@ -1106,3 +1112,110 @@ message GetSocialAnalyticsResponse {
|
||||
string twitter = 12 [json_name = "twitter"];
|
||||
string youtube = 13 [json_name = "youtube"];
|
||||
}
|
||||
|
||||
// ========== Hashtags 相关消息定义 ==========
|
||||
|
||||
// AutoHashtagsRequest 自动生成标签请求参数
|
||||
message AutoHashtagsRequest {
|
||||
string post = 1 [json_name = "post", (validator.field) = {string_not_empty: true, human_error: "post内容不能为空"}];
|
||||
int32 max = 2 [json_name = "max"];
|
||||
string position = 3 [json_name = "position"];
|
||||
string language = 4 [json_name = "language"];
|
||||
string profileKey = 5 [json_name = "profileKey"];
|
||||
}
|
||||
|
||||
// AutoHashtagsResponse 自动生成标签返回结果
|
||||
message AutoHashtagsResponse {
|
||||
string post = 1 [json_name = "post"];
|
||||
string action = 2 [json_name = "action"];
|
||||
string status = 3 [json_name = "status"];
|
||||
int32 code = 4 [json_name = "code"];
|
||||
string message = 5 [json_name = "message"];
|
||||
}
|
||||
|
||||
// CheckBannedHashtagRequest 查看被禁用标签请求
|
||||
message CheckBannedHashtagRequest {
|
||||
string hashtag = 1 [json_name = "hashtag", (validator.field) = {string_not_empty: true, human_error: "hashtag不能为空"}];
|
||||
string profileKey = 2 [json_name = "profileKey"];
|
||||
}
|
||||
|
||||
// CheckBannedHashtagResponse 查看被禁用标签返回结果
|
||||
message CheckBannedHashtagResponse {
|
||||
string hashtag = 1 [json_name = "hashtag"];
|
||||
bool banned = 2 [json_name = "banned"];
|
||||
string action = 3 [json_name = "action"];
|
||||
string status = 4 [json_name = "status"];
|
||||
int32 code = 5 [json_name = "code"];
|
||||
string message = 6 [json_name = "message"];
|
||||
}
|
||||
|
||||
// HashtagRecommendation 单条推荐标签信息
|
||||
message HashtagRecommendation {
|
||||
int64 viewCount = 1 [json_name = "viewCount"];
|
||||
string name = 2 [json_name = "name"];
|
||||
}
|
||||
|
||||
// RecommendHashtagsRequest 推荐话题标签请求
|
||||
message RecommendHashtagsRequest {
|
||||
string keyword = 1 [json_name = "keyword", (validator.field) = {string_not_empty: true, human_error: "keyword不能为空"}];
|
||||
string profileKey = 2 [json_name = "profileKey"];
|
||||
}
|
||||
|
||||
// RecommendHashtagsResponse 推荐话题标签返回结果
|
||||
message RecommendHashtagsResponse {
|
||||
string keyword = 1 [json_name = "keyword"];
|
||||
repeated HashtagRecommendation recommendations = 2 [json_name = "recommendations"];
|
||||
string action = 3 [json_name = "action"];
|
||||
string status = 4 [json_name = "status"];
|
||||
int32 code = 5 [json_name = "code"];
|
||||
string message = 6 [json_name = "message"];
|
||||
}
|
||||
|
||||
// SearchHashtagsRequest 搜索话题标签请求
|
||||
message SearchHashtagsRequest {
|
||||
string keyword = 1 [json_name = "keyword", (validator.field) = {string_not_empty: true, human_error: "keyword不能为空"}];
|
||||
string searchType = 2 [json_name = "searchType"];
|
||||
string profileKey = 3 [json_name = "profileKey"];
|
||||
}
|
||||
|
||||
// SearchHashtagInfo 单个话题标签的基本信息
|
||||
message SearchHashtagInfo {
|
||||
string id = 1 [json_name = "id"];
|
||||
string name = 2 [json_name = "name"];
|
||||
}
|
||||
|
||||
// SearchHashtagChild 搜索结果中 children.data 的元素
|
||||
message SearchHashtagChild {
|
||||
string id = 1 [json_name = "id"];
|
||||
}
|
||||
|
||||
// SearchHashtagChildren 搜索结果中的 children 对象
|
||||
message SearchHashtagChildren {
|
||||
repeated SearchHashtagChild data = 1 [json_name = "data"];
|
||||
}
|
||||
|
||||
// SearchHashtagMedia 搜索结果中的单条 Instagram 媒体信息
|
||||
message SearchHashtagMedia {
|
||||
string caption = 1 [json_name = "caption"];
|
||||
SearchHashtagChildren children = 2 [json_name = "children"];
|
||||
int32 commentsCount = 3 [json_name = "commentsCount"];
|
||||
string id = 4 [json_name = "id"];
|
||||
int32 likeCount = 5 [json_name = "likeCount"];
|
||||
string mediaType = 6 [json_name = "mediaType"];
|
||||
string mediaUrl = 7 [json_name = "mediaUrl"];
|
||||
string permalink = 8 [json_name = "permalink"];
|
||||
string timestamp = 9 [json_name = "timestamp"];
|
||||
}
|
||||
|
||||
// SearchHashtagsResponse 搜索话题标签响应
|
||||
message SearchHashtagsResponse {
|
||||
string status = 1 [json_name = "status"];
|
||||
SearchHashtagInfo hashtag = 2 [json_name = "hashtag"];
|
||||
repeated SearchHashtagMedia searchResults = 3 [json_name = "searchResults"];
|
||||
int32 count = 4 [json_name = "count"];
|
||||
string lastUpdated = 5 [json_name = "lastUpdated"];
|
||||
string nextUpdate = 6 [json_name = "nextUpdate"];
|
||||
string action = 7 [json_name = "action"];
|
||||
int32 code = 8 [json_name = "code"];
|
||||
string message = 9 [json_name = "message"];
|
||||
}
|
||||
|
||||
12
pkg/msg/tag_msg.go
Normal file
12
pkg/msg/tag_msg.go
Normal file
@ -0,0 +1,12 @@
|
||||
package msg
|
||||
|
||||
const (
|
||||
// Hashtags 相关错误消息
|
||||
ErrorAutoHashtagsFailed = "自动生成标签失败"
|
||||
ErrorCheckBannedHashtagsFailed = "查看被禁用的标签失败"
|
||||
ErrorRecommendHashtagsFailed = "推荐话题标签失败"
|
||||
ErrorSearchHashtagsFailed = "搜索话题标签失败"
|
||||
|
||||
ErrHashtagEmpty = "hashtag不能为空"
|
||||
ErrKeywordEmpty = "keyword不能为空"
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user