Spaces:
Running
Running
Download BeadQR/cloudfunctions/quickstartFunctions/index.js from Ethscriptions/cut: direct link, hf CLI and curl.
- Browser
- Download file 3.77 kB
-
https://huggingface.co/spaces/Ethscriptions/cut/resolve/main/BeadQR/cloudfunctions/quickstartFunctions/index.js
- Command line
-
hf download hf://spaces/Ethscriptions/cut/BeadQR/cloudfunctions/quickstartFunctions/index.js
-
curl -L -o index.js https://huggingface.co/spaces/Ethscriptions/cut/resolve/main/BeadQR/cloudfunctions/quickstartFunctions/index.js
3.77 kB
| // 豆维 · 内容安全云函数 | |
| // type: checkMessage | checkMessages | checkImage | |
| // 返回约定:{ risk: boolean, skipped?: boolean };skipped 表示检测未能完成,前端必须拦截 | |
| const cloud = require("wx-server-sdk"); | |
| cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); | |
| const MAX_TEXT = 2500; | |
| const MAX_IMAGE_BYTES = 1024 * 1024; | |
| const MAX_BATCH = 5; | |
| const extractErrCode = (error) => { | |
| if (!error) return undefined; | |
| if (typeof error.errCode === "number") return error.errCode; | |
| if (typeof error.code === "number") return error.code; | |
| const match = typeof error.errMsg === "string" ? error.errMsg.match(/-?\d{3,}/) : null; | |
| return match ? Number(match[0]) : undefined; | |
| }; | |
| // msgSecCheck v2:scene 1 资料 / 2 评论 / 3 论坛 / 4 社交日志 | |
| async function checkOneMessage(content, scene, openid) { | |
| const value = String(content || "").slice(0, MAX_TEXT); | |
| if (!value.trim()) return { risk: false }; | |
| const safeScene = [1, 2, 3, 4].includes(Number(scene)) ? Number(scene) : 2; | |
| try { | |
| const response = await cloud.openapi.security.msgSecCheck({ | |
| version: 2, | |
| scene: safeScene, | |
| openid, | |
| content: value, | |
| }); | |
| const suggest = response && response.result && response.result.suggest; | |
| if (!suggest) return { risk: false, skipped: true }; | |
| // review(疑似)按违规处理,宁严勿松 | |
| return { risk: suggest === "risky" || suggest === "review", verdict: suggest }; | |
| } catch (e) { | |
| if (extractErrCode(e) === 87014) return { risk: true, verdict: "risky" }; | |
| return { risk: false, skipped: true, errCode: extractErrCode(e) }; | |
| } | |
| } | |
| // 通过文件头判断真实格式,不信任客户端传入的类型 | |
| function sniffType(buffer) { | |
| if (buffer.length > 3 && buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) return "image/jpeg"; | |
| if (buffer.length > 8 && buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47) return "image/png"; | |
| return ""; | |
| } | |
| async function checkImage(fileID) { | |
| // 只允许检测本小程序上传到 sec-check/ 目录的临时文件,防止借接口删除/读取其他文件 | |
| if (typeof fileID !== "string" || !/^cloud:\/\/[^/]+\/sec-check\/[\w.-]+\.jpg$/.test(fileID)) { | |
| return { risk: false, skipped: true, reason: "INVALID_FILE" }; | |
| } | |
| try { | |
| const download = await cloud.downloadFile({ fileID }); | |
| const buffer = download && download.fileContent; | |
| const contentType = buffer ? sniffType(buffer) : ""; | |
| if (!buffer || !buffer.length || buffer.length > MAX_IMAGE_BYTES || !contentType) { | |
| return { risk: false, skipped: true, reason: "BAD_IMAGE" }; | |
| } | |
| await cloud.openapi.security.imgSecCheck({ | |
| media: { contentType, value: buffer }, | |
| }); | |
| return { risk: false }; | |
| } catch (e) { | |
| if (extractErrCode(e) === 87014) return { risk: true, verdict: "risky" }; | |
| return { risk: false, skipped: true, errCode: extractErrCode(e) }; | |
| } finally { | |
| try { | |
| await cloud.deleteFile({ fileList: [fileID] }); | |
| } catch (e) { | |
| // 清理失败不影响检测结果 | |
| } | |
| } | |
| } | |
| exports.main = async (event) => { | |
| const { OPENID } = cloud.getWXContext(); | |
| if (!OPENID) return { risk: false, skipped: true, reason: "NO_OPENID" }; | |
| const type = event && event.type; | |
| if (type === "checkMessage") { | |
| return checkOneMessage(event.content, event.scene, OPENID); | |
| } | |
| if (type === "checkMessages") { | |
| const items = Array.isArray(event.items) ? event.items.slice(0, MAX_BATCH) : []; | |
| const results = await Promise.all(items.map((it) => checkOneMessage(it && it.value, it && it.scene, OPENID))); | |
| return { results }; | |
| } | |
| if (type === "checkImage") { | |
| return checkImage(event.fileID); | |
| } | |
| return { risk: false, skipped: true, reason: "UNKNOWN_TYPE" }; | |
| }; | |