텍스트 어뷰징 탐지
텍스트 어뷰징 탐지 API는 텍스트에서 어뷰징(금칙어, 스팸 광고)을 탐지하고 확인하는 API입니다.
사전 준비¶
Hive 콘솔 > AI 서비스 > 어뷰징 탐지 > 텍스트 어뷰징 탐지 메뉴에 접근할 수 있는지 확인하고, 접근이 안 되면 Hive 콘솔 권한 관리 가이드를 참고해 메뉴 접근 권한을 얻습니다. 텍스트 어뷰징 탐지에서 새 프로젝트를 등록합니다.
텍스트 어뷰징 여부 판단¶
텍스트를 전송한 후 이 텍스트가 스팸성 광고인지 텍스트에 금칙어가 포함되었는지 등을 판단해 결과를 반환합니다.
Request URL¶
| LIVE URL | https://tads.withhive.com/cads2/send-text-data | 
|---|---|
| Sandbox URL | https://sandbox-tads.withhive.com/cads2/send-text-data | 
| HTTP Method | POST | 
| Content-Type | application/json | 
Request body¶
| 필드명 | 설명 | 타입 | 필수 | 
|---|---|---|---|
| project_key | 프로젝트 키 | String | Y | 
| text_log | 텍스트 정보 | Object | Y | 
text_log¶
| 필드명 | 설명 | 타입 | 필수 | 
|---|---|---|---|
| text_array | 텍스트와 텍스트 전송 시간이 들어있는 객체들의 배열 | Array(Object) | Y | 
| text_count | text_array에 있는 객체 개수 | Integer | Y | 
text_array에 있는 객체¶
| 필드명 | 설명 | 타입 | 필수 | 
|---|---|---|---|
| time_stamp | 텍스트 전송 시간(UTC 기준 ISO 형식 시간 문자열, 예시: 2024-01-30T10:35:49.95457+09:00) | String | Y | 
| text_info | JSON 객체를 Hive 콘솔에서 얻은 암호키를 사용해 AES256 방식으로 암호화한 문자열입니다. 최대 크기는 5KB입니다. 암호화 방법에 대한 자세한 내용은 예제 코드를 참고하세요. | String | Y | 
text\_info JSON 객체¶
 아래 양식을 따라 JSON 객체를 생성 후, 이를 AES256 방식으로 암호화하여 text_info 문자열을 만듭니다.
| 필드명 | 설명 | 타입 | 필수 | 
|---|---|---|---|
| user_id | 사용자 고유 ID 번호 | String | Y | 
| lang_code | 언어 코드(ISO 639-1 기반) 
 | String | Y | 
| text | 어뷰징 여부를 체크할 텍스트 | String | Y | 
| text_type | 텍스트가 채팅 텍스트인 경우, 3가지 채팅 형태중 하나입니다. 
 | String | N | 
| room_num | 텍스트가 채팅 텍스트인 경우, 채팅방 번호입니다. | String | N | 
| channel_info | 텍스트가 채팅 텍스트인 경우, 채팅 채널 정보입니다. | String | N | 
Response¶
| 필드명 | 설명 | 타입 | 
|---|---|---|
| result_code | 응답 코드 | String | 
| result_text | 응답 코드 설명 | String | 
| result_array | 탐지 결과를 담은 배열 | Array(Object) | 
result_array¶
| 필드명 | 설명 | 타입 | 
|---|---|---|
| tads_result | 탐지 결과 | Object | 
| text_result | 원문 텍스트와 탐지 결과를 토대로 원문 텍스트에 마스킹을 적용한 결과 | Object | 
tads_result¶
| 필드명 | 설명 | 타입 | 
|---|---|---|
| forbidden_yn | 금칙어 탐지 여부( 0: 텍스트에서 금칙어 미발견,1: 텍스트에서 금칙어 발견) | String | 
| spam_yn | 광고 탐지 여부( 0: 텍스트가 스팸성 광고가 아님,1: 텍스트가 스팸성 광고임) | String | 
| aug_yn | 묶음 처리 여부( 0: 묶음 처리되지 않음,1: 묶음 처리됨) | String | 
| long_yn | 긴 문자열 여부로 5,000자 이상이면 어뷰징 여부를 탐지할 수 없음 ( 0: 5,000자 이하,1: 5,000자 초과) | String | 
text_result¶
| 필드명 | 설명 | 타입 | 
|---|---|---|
| text | 어뷰징 여부를 체크하려는 텍스트 | String | 
| masking_text | text에 마스킹을 적용한 텍스트(Hive 콘솔에서 마스킹 설정을 하지 않았거나tads_result.forbidden_yn값이0이면text와 동일) | String | 
Response code¶
| 코드 | 텍스트 | 비고 | 
|---|---|---|
| 200 | "success" | 성공 | 
| 500 | "Incorrect request" | 요청에 오류가 있습니다. Request URL과 Reqest Body가 정확한지 확인하세요. | 
| 501 | "Incorrect Data Count" | 전달된 텍스트의 카운트가 일치하지 않습니다. text_count 값과 text_array의 길이가 일치해야 합니다. | 
| 502 | "Incorrect Secret Key" | 올바르지 않은 암호키 값입니다. 프로젝트 관리에서 해당 프로젝트 암호키를 확인하세요. | 
| 503 | "Unregistered ProjectKey" | 올바르지 않은 프로젝트 키 값입니다. 프로젝트 관리에서 해당 프로젝트의 프로젝트 키를 확인하세요. | 
| 506 | "System Error" | 네트워크 오류 등 내부 오류입니다. 일정 시간 후 API를 다시 호출하세요. | 
| 507 | "The size of message is too large" | 텍스트 크기가 너무 큽니다. text_array 최대 크기는 5KB입니다. 메세지 크기를 줄여주세요. | 
Request example¶
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" ## 필요 없을 경우 제외
room_num = "12312" ## 필요 없을 경우 제외
text_type = "chat_whisper" ## 필요 없을 경우 제외
url = "https://tads.withhive.com/cads2/send-text-data"
payload =  {"project_key": project_key,
                                            "text_log": {
                                                            "text_count": 2, ## text_array의 개수에 맞춰서 설정
                                                            "text_array": [
                                                                                        {"time_stamp": now,
                                                                                        "text_info": encrypt(text=str("테스트1"), 
                                                                                                                        user_id=user_id,
                                                                                                                        channel_info=channel_info, ## 필요 없을 경우 제외
                                                                                                                        room_num=room_num, ## 필요 없을 경우 제외
                                                                                                                        text_type=text_type, ## 필요 없을 경우 제외
                                                                                                                        lang_code=lang_code,
                                                                                                                        secret_key=secret_key)},
                                                                                        {"time_stamp": now,
                                                                                        "text_info": encrypt(text=str("테스트2"), 
                                                                                                                        user_id=user_id,
                                                                                                                        channel_info=channel_info, ## 필요 없을 경우 제외
                                                                                                                        room_num=room_num, ## 필요 없을 경우 제외
                                                                                                                        text_type=text_type, ## 필요 없을 경우 제외
                                                                                                                        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.Slf4j;
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 = "테스트1";
        String text_2 = "테스트2";
        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); // 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); // 필요 없을 경우 제외
                map.put("channel_info", channelInfo); // 필요 없을 경우 제외
                map.put("lang_code", langCode);
                map.put("text", text);
                map.put("text_type", textType); // 필요 없을 경우 제외
                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();
}} // 암호화 코드
Response example¶
{
    "result": {
        "result_array": '[
                        {"tads_result":{
                            "forbidden_yn":"0",
                            "spam_yn":"0",
                            "aug_yn":"0",
                            "long_yn":"0"},
                        "text_result":{
                            "text":"테스트1",
                            "masking_text":"테스트1"
                        }},
                        {"tads_result":{
                            "forbidden_yn":"0",
                            "spam_yn":"0",
                            "aug_yn":"0",
                            "long_yn":"0"},
                        "text_result":{
                            "text":"테스트2",
                            "masking_text":"테스트2"
                        }}
                            ]',
        "result_code": "200",
        "result_text": "success"
    }
}