此次分享下“发帖功能”,这个功能其实风险蛮大的,特别是对一些敏感言论的控制,若是没有作好可能致使小程序被封,因此除了必要的人工审核和巡查之外,咱们须要一些微信安全监测API的帮忙,在AI加持下,如今不少大公司对内容和图片的效率大大提升了。html
这个DEMO仅是一个流程示例,因为涉及到云函数和“真”敏感图,这里就有文字图代替。 node
发帖的功能只要理清思路,其实并不复杂,利用机器AI作内容审查是关键,直接关系到小程序的总体安全。json
let tempImg = 0; //表明已选择的图片
wx.chooseImage({
count: 3 - tempImg.length, //选择不超过3张照片,去掉当前已经选择的照片
sizeType: ['original', 'compressed'], //获取原图或者压缩图
sourceType: ['album', 'camera'], //获取图片来源 图库、拍照
success(res) {
// tempFilePath能够做为img标签的src属性显示图片
let tempFilePaths = res.tempFilePaths;
console.log(tempFilePaths);
//举例:这里能够size 来判断图片是否大于 1MB,方便后面内容检查
if (res.tempFiles[0] && res.tempFiles[0].size > 1024 * 1024) {
console.log("图片大于1MB啦")
}
}
})
复制代码
这里用到的方法是chooseImage,它能够设置让用户选择手机图片库和拍照得到,须要注意的是考虑到后面要用微信自带API作图片安全检查,图片大小不能超过1MB,因此须要设置sizeType为compressed。小程序
因为内容安全对于小程序运营相当重要,稍有不慎就容易致使小程序被封,因此在这块的校验除了常规人工检查外,咱们还能够用到微信的内容安全API。api
为何用微信官方提供的API? 主要有二点:有必定的免费额度,基于企鹅大厂的专业AI检查。安全
目录结构bash
├─checkContent
│ config.json //云调用的权限配置
│ index.js //云服务器node 入口文件
│ package-lock.json
│ package.json // NPM包依赖
│ ...
复制代码
为何要强调这个? 由于本人一开始在用云函数+云调用的时候,常常会出现各类不明BUG,不少都是由于目录里面少传文件,或者少配置。服务器
云函数内容:微信
const cloud = require('wx-server-sdk');
cloud.init();
exports.main = async (event, context) => {
console.log(event.txt);
const { value, txt } = event;
try {
let msgR = false;
let imageR = false;
//检查 文字内容是否违规
if (txt) {
msgR = await cloud.openapi.security.msgSecCheck({
content: txt
})
}
//检查 图片内容是否违规
if (value) {
imageR = await cloud.openapi.security.imgSecCheck({
media: {
header: { 'Content-Type': 'application/octet-stream' },
contentType: 'image/png',
value: Buffer.from(value)
}
})
}
return {
msgR, //内容检查返回值
imageR //图片检查返回值
};
} catch (err) {
// 错误处理
// err.errCode !== 0
return err
}
}
复制代码
这里主要用到security.msgSecCheck和security.imgSecCheck这2个微信开放云调用方法(需开发者工具版本 >= 1.02.1904090),以往咱们还要在服务器上单独写个方法,如今变得十分的方便,直接在云函数中调用便可。app
这里须要重点说2个点
{
"permissions": {
"openapi": [
"security.msgSecCheck",
"security.imgSecCheck"
]
}
}
复制代码
wx.cloud.callFunction({
name: 'checkContent',
data: {
txt: "乐于分享,一块儿进步"
},
success(_res) {
console.log(_res)
},
fail(_res) {
console.log(_res)
}
})
//返回值参考
{
"errMsg": "cloud.callFunction:ok",
"result": {
"msgR": {
"errMsg": "openapi.security.msgSecCheck:ok",
"errCode": 0
},
"imageR": false
},
"requestID": "77952319-b2b4-11e9-bdc8-525400192d0e"
}
复制代码
应用场景举例:
经过wx.cloud.callFunction的方法调用checkContent的云函数,检查一段文本是否含有违法违规内容。
//获取 temp临时图片文件的 buffer
wx.getFileSystemManager().readFile({
filePath: tempImg[0], //这里作示例,因此就选取第一张图片
success: buffer => {
console.log(buffer.data)
//这里是 云函数调用方法
wx.cloud.callFunction({
name: 'checkContent',
data: {
value: buffer.data
},
success(json) {
console.log(json.result.imageR)
if (json.result.imageR.errCode == 87014) {
wx.showToast({
title: '图片含有违法违规内容',
icon: 'none'
});
console.log("bad")
} else {
//图片正常
}
}
})
}
})
//返回值参考
{
"errMsg": "cloud.callFunction:ok",
"result": {
"msgR": false,
"imageR": {
"errMsg": "openapi.security.imgSecCheck:ok",
"errCode": 0
}
},
"requestID": "c126353c2d-b40b-11e9-81c4d-525400235f2a"
}
复制代码
应用场景举例:
图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等; 敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。 频率限制:单个 appId 调用上限为 2000 次/分钟,200,000 次/天*(图片大小限制:1M)
这里先要用 getFileSystemManager() 获取临时图片的buffer(这个是重点),而后再经过wx.cloud.callFunction的方法调用 checkContent的云函数中security.imgSecCheck的方法,校验一张图片是否含有违法违规内容。
一开始本人调试的时候,也遇到没法上传的问题,必须经过文件管理(getFileSystemManager)获取buffer后才能上传检查图片,耗费了本人很多debugger时间。
本来想作个实际的demo(代码片断)分享给你们打开参考的,可是云函数必须是一个已注册的APPID,无奈只能贴代码。
这里主要仍是提供一个总体思路,但愿能帮助你们减小开发成本,更好的解决问题和完成任务 ^_^
html部分:
<!-- pages/post /index.wxml -->
<view class="wrap">
<view class="title">
<input placeholder="智酷方程式,乐于分享" maxlength="30" bindinput="getTitle"/>
</view>
<view class="content">
<textarea auto-focus="true" maxlength="200" bindinput="textareaCtrl" placeholder-style="color:#999;" placeholder="关注公众号,一块儿学习,一块儿进步" />
<view class='fontNum'>{{content.length}}/200</view>
</view>
<view class="chooseImg">
<block wx:for="{{tempImg}}" wx:for-item="item" wx:key="ids" wx:for-index="index">
<view class="chooseImgBox">
<image src="{{item}}" />
<view data-index="{{index}}" catch:tap="removeImg" class="removeImg"></view>
</view>
</block>
<!-- 判断图片 大于等于3张的时候 取消 更多 -->
<block wx:if="{{tempImg.length < 3}}">
<view class="chooseImgBoxMore" catch:tap="choosePhoto">
<view class="arrow"></view>
</view>
</block>
</view>
<view class='submit' catch:tap="submitPost">
<view class='blue'>提交</view>
<view>取消</view>
</view>
</view>
复制代码
JS部分:
Page({
/**
* 页面的初始数据
*/
data: {
titleDetail: "", //帖子title内容
content: "", //发帖内容
tempImg: [], //选择图片的缩略图,临时地址
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.cloud.init();
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 检测输入字数
* @param {object} e
*/
textareaCtrl: function (e) {
if (e.detail.value) {
this.setData({
content: e.detail.value
})
} else {
this.setData({
content: ""
})
}
},
/**
* 选择图片
*/
choosePhoto() {
let self = this;
let tempImg = self.data.tempImg;
if (tempImg.length > 2) {
return;
}
wx.chooseImage({
count: 3 - tempImg.length, //选择不超过3张照片,去掉当前已经选择的照片
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
console.log(res);
// tempFilePath能够做为img标签的src属性显示图片
let tempFilePaths = res.tempFilePaths;
tempImg = tempImg.concat(tempFilePaths);
console.log(tempImg);
self.setData({
tempImg
})
wx.getFileSystemManager().readFile({
filePath: tempImg[0],
success: buffer => {
console.log(buffer.data)
wx.cloud.callFunction({
name: 'checkContent',
data: {
value: buffer.data
},
success(json) {
console.log(JSON.stringify(json))
console.log(json.result.imageR)
if (json.result.imageR.errCode == 87014) {
wx.showToast({
title: '图片含有违法违规内容',
icon: 'none'
});
console.log("bad")
} else {
//图片正常
}
}
})
}
})
},
fail: err => {
console.log(err)
}
})
},
/**
* 删除照片
*/
removeImg(e) {
let self = this;
let index = e.currentTarget.dataset.index;
console.log(e);
let tempImg = self.data.tempImg;
tempImg.splice(index, 1);
self.setData({
tempImg
})
},
/**
* 发贴
*/
submitPost(e) {
let { titleDetail, content } = this.data;
wx.cloud.callFunction({
name: 'checkContent',
data: {
txt: content
},
success(_res) {
console.log(JSON.stringify(_res))
wx.navigateTo({
url: "/pages/postimg/result"
})
},
fail(_res) {
console.log(_res)
}
})
}
})
复制代码
往期回顾:
[打怪升级]小程序评论回复和发贴功能实战(一)
[填坑手册]小程序Canvas生成海报(一)
[拆弹时刻]小程序Canvas生成海报(二)
[填坑手册]小程序目录结构和component组件使用心得