文章目录
-
- 问题
- 分析
-
- 一、msg_sec_check
-
- 接口基本信息
- 核心参数(Body)
- 返回结果
- [获取 access_token(调用必备)](#获取 access_token(调用必备))
- [Demo 实现(云函数版,推荐)](#Demo 实现(云函数版,推荐))
- Demo实现(原生)
- 二、media_check_async
问题
你好,你的小程序涉及提供UGC自定义发布内容功能,但服务体验流程有特定限制,环节暂无法正常体验小程序功能及确认小程序有内容安全识别能力。为避免您的小程序被滥用,建议接入微信公众平台内容安全API(imgSecCheck、msgSecCheck、mediaCheckAsync)能力参考文档,接入后请按文档"示例"指示进行并保存接口返回值的录屏,将接口调用成功录屏及小程序服务截图上传后再提交代码。

分析
一、msg_sec_check
msgSecCheck 是微信小程序服务端的文本内容安全检测接口,用于检查文本是否含违法违规内容(如涉政、色情、辱骂、广告等),必须在开发者服务器 / 云函数调用,不可在小程序前端直接调用
接口基本信息
- 请求地址:POST https://api.weixin.qq.com/wxa/msg_sec_check?access_token=ACCESS_TOKEN
- 请求方式:POST
- Content-Type:application/json
- 权限要求:需携带有效的 access_token
核心参数(Body)
javascript
{
"content": "待检测文本",
"version": 2,// 固定为 2(最新版)
"scene": 2,// 场景值(1 = 资料 / 昵称,2 = 评论,3 = 论坛,4 = 其他)
"openid": "用户openid(可选)",
"title": "标题(可选)",
"nickname": "用户昵称(可选)"
}
- scene
javascript
1 资料:昵称、头像说明、个性签名
2 评论:短文本、留言、评论、弹幕、许愿墙 / 祈福语
3 论坛:长帖子、文章、主题帖
4 社交日志:个人动态、朋友圈式内容、心愿 / 日记类
返回结果
- errcode=0:调用成功
- result.suggest:pass(通过)、risky(可疑)、block(违规)
获取 access_token(调用必备)
access_token 是微信后台接口的全局调用凭证,有效期 2 小时(7200s),需服务端缓存刷新。
- 获取 AppID & AppSecret
小程序后台 → 开发管理 → 开发设置 → 复制 AppID、AppSecret(妥善保管,不可泄露) - 获取接口(GET)
javascript
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的AppID&secret=你的AppSecret
- 返回示例
javascript
{
"access_token": "61_9sX...",
"expires_in": 7200,
"errcode": 0,
"errmsg": "ok"
}
Demo 实现(云函数版,推荐)
- /msgSecCheck/index.js
javascript
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
exports.main = async (event) => {
const { content } = event
try {
const result = await cloud.openapi.security.msgSecCheck({
content: content,
version: 2,
scene: 2
})
return {
code: 0,
data: result
}
} catch (err) {
return {
code: -1,
msg: err.errMsg
}
}
}
- 云函数 config.json
javascript
{
"permissions": {
"openapi": ["security.msgSecCheck"]
}
}
- 小程序端调用
javascript
wx.cloud.callFunction({
name: 'msgSecCheck',
data: {
content: '需要检测的文本'
}
}).then(res => {
console.log(res.result)
})
Demo实现(原生)
- token.js
javascript
// 微信小程序原生写法:无感刷新 access_token
let accessToken = ''
let expireTime = 0
let isRefreshing = false
let requests = []
const getUGCToken = async () => {
return new Promise((resolve, reject) => {
const now = Date.now()
// 1. 如果 token 有效,直接返回
if (accessToken && now < expireTime) {
resolve(accessToken)
return
}
// 2. 防止重复刷新
if (isRefreshing) {
requests.push(() => resolve(accessToken))
return
}
isRefreshing = true
// 3. 原生 wx.request 获取 token
const appid = '你的appid'
const secret = '你的secret'
wx.request({
url: 'https://api.weixin.qq.com/cgi-bin/token',
method: 'GET',
data: {
grant_type: 'client_credential',
appid: appid,
secret: secret
},
success: (res) => {
const data = res.data
if (data.access_token) {
accessToken = data.access_token
expireTime = now + (data.expires_in - 60) * 1000
// 执行等待中的请求
requests.forEach((cb) => cb(accessToken))
requests = []
resolve(accessToken)
} else {
reject(data.errmsg || '获取token失败')
}
},
fail: (err) => {
reject(err)
},
complete: () => {
isRefreshing = false
}
})
})
}
// 文本安全检测
async function msgSecCheck(content) {
const token = await getUGCToken()
const openid = wx.getStorageSync('openId')
return new Promise((resolve, reject) => {
wx.request({
url: `https://api.weixin.qq.com/wxa/msg_sec_check?access_token=${token}`,
method: 'POST',
header: {
'Content-Type': 'application/json'
},
data: {
openid: openid,
content: content,
version: 2,
scene: 2
},
success(res) {
const data = res.data
// errcode 0 成功
// 违规会返回 87014 等
resolve(data)
},
fail(err) {
reject(err)
}
})
})
}
module.exports = {
getUGCToken,
msgSecCheck
}
- 使用
javascript
try {
const result = await msgSecCheck(this.data.wish)
if (result.errcode === 0) {
// 通过
// wx.showToast({ title: '内容正常', icon: 'success' })
} else {
// 违规/风险
wx.showToast({ title: result.errmsg || '内容违规', icon: 'none' })
return
}
} catch (err) {
console.error(err)
wx.showToast({ title: '检测失败', icon: 'none' })
}
二、media_check_async
mediaCheckAsync 是图片 / 音频异步安全检测,用于检测图片是否违规(涉政、色情、敏感等)。
接口地址:POST https://api.weixin.qq.com/wxa/media_check_async?access_token=TOKEN
- 支持:图片(网络 URL)
- 方式:异步检测(结果通过 回调 / 事件 推送)
- scene 场景:
- 1 用户资料
- 2 评论 / 许愿 / 留言(用的这个)
- 3 帖子
- 4 其他
javascript
// 微信小程序原生写法:无感刷新 access_token
let accessToken = ''
let expireTime = 0
let isRefreshing = false
let requests = []
const getUGCToken = async () => {
return new Promise((resolve, reject) => {
const now = Date.now()
// 1. 如果 token 有效,直接返回
if (accessToken && now < expireTime) {
resolve(accessToken)
return
}
// 2. 防止重复刷新
if (isRefreshing) {
requests.push(() => resolve(accessToken))
return
}
isRefreshing = true
// 3. 原生 wx.request 获取 token
const appid = 'appid '
const secret = 'secret '
wx.request({
url: 'https://api.weixin.qq.com/cgi-bin/token',
method: 'GET',
data: {
grant_type: 'client_credential',
appid: appid,
secret: secret
},
success: (res) => {
const data = res.data
if (data.access_token) {
accessToken = data.access_token
expireTime = now + (data.expires_in - 60) * 1000
// 执行等待中的请求
requests.forEach((cb) => cb(accessToken))
requests = []
resolve(accessToken)
} else {
reject(data.errmsg || '获取token失败')
}
},
fail: (err) => {
reject(err)
},
complete: () => {
isRefreshing = false
}
})
})
}
// 文本安全检测
async function msgSecCheck(content) {
const token = await getUGCToken()
const openid = wx.getStorageSync('openId')
return new Promise((resolve, reject) => {
wx.request({
url: `https://api.weixin.qq.com/wxa/msg_sec_check?access_token=${token}`,
method: 'POST',
header: {
'Content-Type': 'application/json'
},
data: {
openid: openid,
content: content,
version: 2,
scene: 2
},
success(res) {
const data = res.data
// errcode 0 成功
// 违规会返回 87014 等
resolve(data)
},
fail(err) {
reject(err)
}
})
})
}
/**
* 图片异步安全检测
* @param {String} media_url 图片网络地址(必须公网可访问)
* @param {String} openid 用户openid
*/
async function mediaCheckAsync(media_url, openid) {
const token = await getUGCToken()
const openid = wx.getStorageSync('openId')
return new Promise((resolve, reject) => {
wx.request({
url: `https://api.weixin.qq.com/wxa/media_check_async?access_token=${token}`,
method: 'POST',
header: {
'Content-Type': 'application/json'
},
data: {
media_url: media_url,
media_type: 2, // 1=音频 2=图片
version: 2, // 固定2
scene: 2, // 2=评论/许愿/留言
openid: openid // 必填
},
success(res) {
resolve(res.data)
},
fail(err) {
reject(err)
}
})
})
}
module.exports = {
getUGCToken,
msgSecCheck,
mediaCheckAsync
}
- 使用
javascript
const { mediaCheckAsync } = require('../../utils/imageCheck')
Page({
// 选择图片 + 检测
async chooseAndCheckImage() {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
success: async (res) => {
const filePath = res.tempFiles[0].tempFilePath
// 1. 上传到你的服务器获得 网络URL
// 这里必须是 https 公网地址
// const onlineUrl = await 你的上传接口(filePath)
// 示例(替换成你真实的图片地址)
const onlineUrl = 'https://pic.baidu.com/xxx.jpg'
const openid = wx.getStorageSync('openid')
// 2. 图片安全检测
const result = await mediaCheckAsync(onlineUrl, openid)
console.log('图片检测结果:', result)
if (result.errcode === 0) {
wx.showToast({ title: '图片已提交检测,等待结果' })
} else {
wx.showToast({ title: '图片违规', icon: 'none' })
}
}
})
}
})