Spaces:
Runtime error
Runtime error
File size: 2,984 Bytes
41af422 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
import fetch from 'node-fetch'
export interface TextAuditServiceOptions {
apiKey: string
apiSecret: string
label: string
}
export interface TextAuditService {
containsSensitiveWords(text: string): Promise<boolean>
}
/**
* https://ai.baidu.com/ai-doc/ANTIPORN/Vk3h6xaga
*/
export class BaiduTextAuditService implements TextAuditService {
private accessToken: string
private expiredTime: number
constructor(private options: TextAuditServiceOptions) { }
async containsSensitiveWords(text: string): Promise<boolean> {
if (!await this.refreshAccessToken())
throw new Error('Access Token Error')
const url = `https://aip.baidubce.com/rest/2.0/solution/v1/text_censor/v2/user_defined?access_token=${this.accessToken}`
let headers: {
'Content-Type': 'application/x-www-form-urlencoded'
'Accept': 'application/json'
}
const response = await fetch(url, { headers, method: 'POST', body: `text=${encodeURIComponent(text)}` })
const data = await response.json() as { conclusionType: number; data: any; error_msg: string }
if (data.error_msg)
throw new Error(data.error_msg)
// 审核结果类型,可取值1、2、3、4,分别代表1:合规,2:不合规,3:疑似,4:审核失败
if (data.conclusionType === 1)
return false
// https://ai.baidu.com/ai-doc/ANTIPORN/Nk3h6xbb2#%E7%BB%86%E5%88%86%E6%A0%87%E7%AD%BE%E5%AF%B9%E7%85%A7%E8%A1%A8
// 3 仅政治
const sensitive = data.data.filter(d => d.subType === 3).length > 0
if (sensitive || !this.options.label)
return sensitive
const str = JSON.stringify(data)
for (const l of this.options.label.split(',')) {
if (str.includes(l))
return true
}
return false
}
async refreshAccessToken() {
if (!this.options.apiKey || !this.options.apiSecret)
throw new Error('未配置 | Not configured.')
try {
if (this.accessToken && Math.floor(new Date().getTime() / 1000) <= this.expiredTime)
return true
const url = `https://aip.baidubce.com/oauth/2.0/token?client_id=${this.options.apiKey}&client_secret=${this.options.apiSecret}&grant_type=client_credentials`
let headers: {
'Content-Type': 'application/json'
'Accept': 'application/json'
}
const response = await fetch(url, { headers })
const data = (await response.json()) as { access_token: string; expires_in: number }
this.accessToken = data.access_token
this.expiredTime = Math.floor(new Date().getTime() / 1000) + (+data.expires_in)
return true
}
catch (error) {
global.console.error(`百度审核${error}`)
}
return false
}
}
export type TextAuditServiceProvider = 'baidu' // | 'ali'
export type TextAuditServices = {
[key in TextAuditServiceProvider]: new (
options: TextAuditServiceOptions,
) => TextAuditService;
}
export const textAuditServices: TextAuditServices = {
baidu: BaiduTextAuditService,
}
|