feat: ugc内容审核工具类
This commit is contained in:
@@ -0,0 +1,156 @@
|
|||||||
|
package wechat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"sundynix-go/global"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WeChatCommonResponse 微信通用响应
|
||||||
|
type WeChatCommonResponse struct {
|
||||||
|
Errcode int `json:"errcode"`
|
||||||
|
Errmsg string `json:"errmsg"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgSecCheckDetail 文本检测结果详情
|
||||||
|
type MsgSecCheckDetail struct {
|
||||||
|
Strategy string `json:"strategy"`
|
||||||
|
Errcode int `json:"errcode"`
|
||||||
|
Suggest string `json:"suggest"`
|
||||||
|
Label int `json:"label"`
|
||||||
|
Prob int `json:"prob"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgSecCheckResult 文本检测结果
|
||||||
|
type MsgSecCheckResult struct {
|
||||||
|
Suggest string `json:"suggest"`
|
||||||
|
Label int `json:"label"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgSecCheckResponse 文本检测响应
|
||||||
|
type MsgSecCheckResponse struct {
|
||||||
|
WeChatCommonResponse
|
||||||
|
Result MsgSecCheckResult `json:"result"`
|
||||||
|
Detail []MsgSecCheckDetail `json:"detail"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MediaCheckAsyncResponse 媒体检测异步响应
|
||||||
|
type MediaCheckAsyncResponse struct {
|
||||||
|
WeChatCommonResponse
|
||||||
|
TraceId string `json:"trace_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgSecCheck 文本内容安全识别
|
||||||
|
// content: 需检测的文本内容
|
||||||
|
// openid: 用户的openid(用户需在近两小时访问过小程序)
|
||||||
|
// return: true-通过, false-不通过
|
||||||
|
func MsgSecCheck(content string, openid string) bool {
|
||||||
|
// 2024-05-15: 微信api调整
|
||||||
|
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/sec-center/sec-check/msgSecCheck.html
|
||||||
|
accessToken := GetMiniAccessToken()
|
||||||
|
url := "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + accessToken
|
||||||
|
|
||||||
|
payload := map[string]interface{}{
|
||||||
|
"version": 2,
|
||||||
|
"openid": openid,
|
||||||
|
"scene": 2, // 2-资料说明
|
||||||
|
"content": content,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
global.Logger.Error("MsgSecCheck json marshal error", zap.Error(err))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
global.Logger.Error("MsgSecCheck http post error", zap.Error(err))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
global.Logger.Error("MsgSecCheck read body error", zap.Error(err))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var response MsgSecCheckResponse
|
||||||
|
if err := json.Unmarshal(body, &response); err != nil {
|
||||||
|
global.Logger.Error("MsgSecCheck json unmarshal error", zap.Error(err))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.Errcode != 0 {
|
||||||
|
global.Logger.Error("MsgSecCheck api error", zap.Int("errcode", response.Errcode), zap.String("errmsg", response.Errmsg))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 result.suggest
|
||||||
|
if response.Result.Suggest == "pass" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
global.Logger.Warn("MsgSecCheck risky content",
|
||||||
|
zap.String("content", content),
|
||||||
|
zap.String("suggest", response.Result.Suggest),
|
||||||
|
zap.Int("label", response.Result.Label),
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// MediaCheckAsync 多媒体内容安全识别(异步)
|
||||||
|
// mediaUrl: 需检测的多媒体url
|
||||||
|
// mediaType: 1:音频; 2:图片
|
||||||
|
// openid: 用户的openid
|
||||||
|
// return: trace_id, error
|
||||||
|
func MediaCheckAsync(mediaUrl string, mediaType int, openid string) (string, error) {
|
||||||
|
accessToken := GetMiniAccessToken()
|
||||||
|
url := "https://api.weixin.qq.com/wxa/media_check_async?access_token=" + accessToken
|
||||||
|
|
||||||
|
payload := map[string]interface{}{
|
||||||
|
"media_url": mediaUrl,
|
||||||
|
"media_type": mediaType,
|
||||||
|
"version": 2,
|
||||||
|
"openid": openid,
|
||||||
|
"scene": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var response MediaCheckAsyncResponse
|
||||||
|
if err := json.Unmarshal(body, &response); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.Errcode != 0 {
|
||||||
|
global.Logger.Error("MediaCheckAsync api error", zap.Int("errcode", response.Errcode), zap.String("errmsg", response.Errmsg))
|
||||||
|
return "", fmt.Errorf("errcode: %d, errmsg: %s", response.Errcode, response.Errmsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.TraceId != "" {
|
||||||
|
return response.TraceId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("no trace_id returned")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user