此次分享下「發帖功能」,這個功能其實風險蠻大的,特別是對一些敏感言論的控制,若是沒有作好可能致使小程序被封,因此除了必要的人工審覈和巡查之外,咱們須要一些微信安全監測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組件使用心得