テキストの悪用を検出
テキスト虐待検出APIは、テキスト内の虐待(禁止用語、スパム広告)を検出し、検証するAPIです。
準備¶
Hive コンソール > AI サービス > 悪用検出 > チャット悪用検出 メニューにアクセスできるか確認し、できない場合は、Hive コンソールの権限管理ガイドを参照してメニューアクセス権を取得してください。チャット悪用検出に新しいプロジェクトを登録します。
テキストが攻撃的かどうかの判断¶
テキストを送信した後、それがスパム広告であるか、禁止された単語を含んでいるかを判断し、結果を返します。
リクエストURL¶
ライブURL | https://tads.withhive.com/cads2/send-text-data |
---|---|
サンドボックスURL | https://sandbox-tads.withhive.com/cads2/send-text-data |
HTTPメソッド | POST |
コンテンツタイプ | application/json |
リクエストボディ¶
フィールド名 | 説明 | タイプ | 必須 |
---|---|---|---|
project_key | プロジェクトキー | 文字列 | Y |
text_log | テキスト情報 | オブジェクト | Y |
テキストログ¶
フィールド名 | 説明 | タイプ | 必須 |
---|---|---|---|
text_array | テキストとテキストが送信された時間を含むオブジェクトの配列 | 配列(オブジェクト) | Y |
text_count | text_array内のオブジェクトの数 | 整数 | Y |
テキスト配列のオブジェクト¶
フィールド名 | 説明 | タイプ | 必須 |
---|---|---|---|
time_stamp | テキストが送信された時間(UTCベースのISO形式の時間文字列、例: 2024-01-30T10:35:49.95457+09:00 ) | 文字列 | Y |
text_info | JSONオブジェクトから取得したHive コンソールの暗号化キーを使用してAES256で暗号化された文字列。最大サイズは5KBです。暗号化方法の詳細については、例のコードを参照してください。 | 文字列 | Y |
text_info
JSONオブジェクト¶
以下のフォーマットに従ってJSONオブジェクトを作成し、それをAES256で暗号化してtext_info
文字列を形成します。
フィールド名 | 説明 | タイプ | 必須 |
---|---|---|---|
user_id | ユーザーのユニークID番号 | 文字列 | Y |
lang_code | 言語コード (ISO 639-1) * 韓国語: ko * 英語: en * 日本語: ja * 簡体字中国語: zh-hans * 繁体字中国語: zh-hant * スペイン語: es * ロシア語: ru * ドイツ語: de * フランス語: fr * ポルトガル語: pt * イタリア語: it * タイ語: th * インドネシア語: id * トルコ語: tr * マレー語: ms * ベトナム語: vi | 文字列 | Y |
text | 検査するテキスト | 文字列 | Y |
text_type | テキストがチャットテキストの場合、以下の3つのチャット形式のいずれかに該当します。 * "chat_party": パーティーチャット * "chat_guild": ギルドチャット * "chat_whisper": ウィスパー | 文字列 | N |
room_num | テキストがチャットテキストの場合、これはチャットルーム番号です。 | 文字列 | N |
channel_info | テキストがチャットテキストの場合、これはチャットチャンネル情報です。 | 文字列 | N |
応答¶
フィールド名 | 説明 | タイプ |
---|---|---|
result_code | レスポンスコード | 文字列 |
result_text | レスポンスコードの説明 | 文字列 |
result_array | 検出結果を含む配列 | 配列(オブジェクト) |
結果配列¶
フィールド名 | 説明 | タイプ |
---|---|---|
tads_result | 検出結果 | オブジェクト |
text_result | 元のテキストと検出結果に基づいてマスキングを適用した結果 | オブジェクト |
tads_result¶
フィールド名 | 説明 | タイプ |
---|---|---|
forbidden_yn | 禁止ワードが検出されたかどうか(0 : テキストに禁止ワードは見つかりませんでした、1 : テキストに禁止ワードが見つかりました) | 文字列 |
spam_yn | テキストがスパムとして検出されたかどうか(0 : スパムとして検出されていません、1 : スパムとして検出されました) | 文字列 |
aug_yn | テキストがバッチ処理されたかどうか(0 : バッチ処理されていません、1 : バッチ処理されました) | 文字列 |
long_yn | テキストが長い文字列かどうか、つまり5,000文字を超える場合、検出アルゴリズムをテキストに対して実行できないことを意味します(0 : 5,000文字未満、1 : 5,000文字以上) | 文字列 |
テキスト結果¶
フィールド名 | 説明 | タイプ |
---|---|---|
text | 検出するためのテキスト | 文字列 |
masking_text | マスキングが適用されたテキスト(Hive コンソールでマスキング設定が行われていない場合、またはtads_result.forbidden_yn の値が0 の場合、text は同一になります) | 文字列 |
レスポンスコード¶
コード | テキスト | 備考 |
---|---|---|
200 | "成功" | 成功 |
500 | "不正なリクエスト" | リクエストにエラーがあります。リクエストURLとリクエストボディが正しいか確認してください。 |
501 | "不正なデータカウント" | 渡されたテキストのカウントが一致しません。text_countの値とtext_arrayの長さが一致する必要があります。 |
502 | "不正な秘密鍵" | 秘密鍵の値が不正です。プロジェクト管理でプロジェクトの秘密鍵を確認してください。 |
503 | "未登録のプロジェクトキー" | プロジェクトキーの値が不正です。プロジェクト管理でプロジェクトのプロジェクトキーを確認してください。 |
506 | "システムエラー" | これはネットワークエラーなどの内部エラーです。しばらくしてからAPIを再度呼び出してください。 |
507 | "メッセージのサイズが大きすぎます" | テキストのサイズが大きすぎます。text_arrayの最大サイズは5KBです。メッセージのサイズを減らしてください。 |
リクエストの例¶
import json
import base64
import requests
from datetime import datetime
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
def encrypt(text, user_id, lang_code, secret_key, channel_info=None, room_num=None, text_type=None) -> str: ## 暗号化のためのコード
aes = AES.new(secret_key, AES.MODE_ECB)
jsonData = {"text_type": text_type, ## 必要な場合のみ使用
"room_num" : room_num, ## 必要な場合のみ使用
"user_id": user_id,
"channel_info" : channel_info, ## 必要な場合のみ使用
"lang_code": lang_code,
"text": text}
rawJsonStr = json.dumps(jsonData)
paddedStr = pad(rawJsonStr.encode("utf-8"),AES.block_size)
encrypted_data = aes.encrypt(paddedStr)
encrypted_data_b64 = base64.b64encode(encrypted_data).decode("utf-8")
return encrypted_data_b64
project_key = <PROJECT_KEY>
secret_key = <SECRET_KEY>
now = datetime.now().astimezone().isoformat()
lang_code = "ko"
user_id = "432414"
channel_info = "4342314" ## Use it only when it is required
room_num = "12312" ## Use it only when it is required
text_type = "chat_whisper" ## Use it only when it is required
url = "https://tads.withhive.com/cads2/send-text-data"
payload = {"project_key": project_key,
"text_log": {
"text_count": 2, ## should match the number of elements of text_array
"text_array": [
{"time_stamp": now,
"text_info": encrypt(text=str("test1"),
user_id=user_id,
channel_info=channel_info, ## Use it only when it is required
room_num=room_num, ## Use it only when it is required
text_type=text_type, ## Use it only when it is required
lang_code=lang_code,
secret_key=secret_key)},
{"time_stamp": now,
"text_info": encrypt(text=str("test2"),
user_id=user_id,
channel_info=channel_info, ## Use it only when it is required
room_num=room_num, ## Use it only when it is required
text_type=text_type, ## Use it only when it is required
lang_code=lang_code,
secret_key=secret_key)}]},}
res = requests.post(url, data=json.dumps(payload), headers={"Content-Type": "application/json"})
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import org.jooq.tools.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.log;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
public class TadsComponent {
@Autowired
RestTemplate restTemplate;
@Autowired
ObjectMapper objectMapper;
public void sendHttp() throws Exception{
String projectKey = <PROJECT_KEY>; // プロジェクトキーを提供してください
String secretKey = <SECRET_KEY>; // プロジェクトの秘密鍵を提供してください
String url = "https://tads.withhive.com/cads2/send-text-data";
String user_id = "432414";
String channel_info = "4342314"; // 必要な場合のみ使用
String room_num = "12312"; // 必要な場合のみ使用
String text_type = "chat_whisper"; // 必要な場合のみ使用
String lang_code = "ko";
String text_1 = "test1";
String text_2 = "test2";
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
ZonedDateTime now = ZonedDateTime.now();
Map<String, Object> payload = new HashMap<>();
payload.put("project_key", projectKey);
Map<String, Object> textLog = new HashMap<>();
textLog.put("text_count", 2); // should match the number of elements of text_array
Map<String, Object> textArray1 = new HashMap<>();
textArray1.put("time_stamp", now.format(formatter));
textArray1.put("text_info", encrypt(text_1, user_id, channel_info, room_num, text_type, lang_code, secretKey));
Map<String, Object> textArray2 = new HashMap<>();
textArray2.put("time_stamp", now.format(formatter));
textArray2.put("text_info", encrypt(text_2, user_id, channel_info, room_num, text_type, lang_code, secretKey));
Object[] textArrayObj = {textArray1, textArray2};
textLog.put("text_array", textArrayObj);
payload.put("text_log", textLog);
JsonNode callBodyNode = objectMapper.valueToTree(payload);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
HttpEntity<String> entity = new HttpEntity<>(callBodyNode.toString(), headers);
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
int responseStatusCode = responseEntity.getStatusCodeValue();
String responseBodyString = responseEntity.getBody();
JsonNode responseBodyNode = objectMapper.readTree(responseBodyString);
return;
}
public static String encrypt(String text, String UserId, String channelInfo, String roomNum, String textType, String langCode, String secretKey) {
try {
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "AES");
aes.init(Cipher.ENCRYPT_MODE, secretKeySpec);
Map<String,Object> map = new HashMap<String,Object>();
map.put("room_num", roomNum); // Use it only when it is required
map.put("channel_info", channelInfo); // Use it only when it is required
map.put("lang_code", langCode);
map.put("text", text);
map.put("text_type", textType); // Use it only when it is required
map.put("user_id", UserId);
String encrypt_str = JSONObject.toJSONString(map);
byte[] paddedData = padString(encrypt_str).getBytes();
byte[] encryptedData = aes.doFinal(paddedData);
return Base64.getEncoder().encodeToString(encryptedData);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
return null;
}
}
private static String padString(String source) {
char paddingChar = ' ';
int size = 16;
int x = source.length() % size;
int padLength = size - x;
StringBuilder paddedString = new StringBuilder(source);
for (int i = 0; i < padLength; i++) {
paddedString.append(paddingChar);
}
return paddedString.toString();
}} // 暗号化のためのコード
応答の例¶
{
"result": {
"result_array": '[
{"tads_result":{
"forbidden_yn":"0",
"spam_yn":"0",
"aug_yn":"0",
"long_yn":"0"},
"text_result":{
"text":"test1",
"masking_text":"test1"
}},
{"tads_result":{
"forbidden_yn":"0",
"spam_yn":"0",
"aug_yn":"0",
"long_yn":"0"},
"text_result":{
"text":"test2",
"masking_text":"test2"
}}
]',
"result_code": "200",
"result_text": "success"
}
}