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") }