콘텐츠로 이동

채팅 로그 전송

채팅 로그 수집 시스템(CLCS)

send-chat-log

채팅 로그 수집 시스템에 채팅 로그를 전송하기 위한 API입니다.

  • Request URL
상용 URL https://clcs.qpyou.cn/chat/api/v1/send-chat-log
Sandbox URL https://sandbox-clcs.qpyou.cn/chat/api/v1/send-chat-log
HTTP Method POST
Content-Type application/json
  • Request Body
필드명 타입 필수 설명
game_key String Y 회사 id와 게임 id로 정의한 키 값(16글자)입니다. Hive 콘솔 AI 서비스 > 채팅 어뷰징 탐지 > 게임 관리 > 암호 키에서 얻을 수 있습니다. 회사 id와 게임 id는 Hive 콘솔 AI 서비스 > 채팅 어뷰징 탐지 > 게임 관리에서 확인 가능합니다.   예) abcdefghijklmnop
chat_log object Y 암호화된 메시지의 배열 혹은 컬렉션 및 채팅 카운트
  • chat_log object
필드명 타입 필수 설명
chat_count int Y msg_array에 존재하는 msg 개수입니다. 예) 32 (chat_count값과 암호화한 msg들이 들어있는 msg_array 크기는 동일해야 합니다.)
msg_array array Y 1개 이상의 msg object
* msg object;
필드명 타입 필수 설명
time_stamp string Y 채팅 발생 시간을 ISO8601 포맷으로 변경하여 전송합니다. ISO8601 포맷으로 변경하면 채팅 전송 유저가 소속된 타임존에 따라 채팅 발생 시간에 ±hh:mm가 붙습니다.

채팅 전송 유저가 소속된 타임존과 채팅 발생 시간에 따른 time_stamp값 예시
  • 소속 타임존이 UTC이고 채팅 발생 시간이 2023-03-30 17:13:00
  • 2023-03-30T17:13:00+00:00 또는 2023-03-30T17:13:00Z를 사용
  • +00:00은 Z로도 표기할 수 있음(YYYY-MM-DDTHH🇲🇲ss{.mmm}±hh:mm 또는 YYYY-MM-DDTHH🇲🇲ss{.mmm}Z)
  • 소속 타임존이 한국 표준시(KST)이고 채팅 발생 시간이 2023-03-30 17:13:00
  • 2023-03-30T17:13:00+09:00를 사용
  • 소속 타임존이 중부 표준시(CST)이고 채팅 발생 시간이 2023-03-30 17:13:00
  • 2023-03-30T17:13:00-05:00를 사용
msg string Y Hive 콘솔 AI 서비스 > 채팅 어뷰징 탐지 > 게임 관리에서 발급한 암호 키를 이용하여 AES256 방식으로 암호화 된 JSON string (최대 사이즈 2KB)
  • msg
필드명 타입 필수 설명
time_stamp string Y 채팅 발생 시간을 ISO8601 포맷으로 변경하여 전송합니다. ISO8601 포맷으로 변경하면 채팅 전송 유저가 소속된 타임존에 따라 채팅 발생 시간에 ±hh:mm가 붙습니다.

채팅 전송 유저가 소속된 타임존과 채팅 발생 시간에 따른 time_stamp값 예시
  • 소속 타임존이 UTC이고 채팅 발생 시간이 2023-03-30 17:13:00
  • 2023-03-30T17:13:00+00:00 또는 2023-03-30T17:13:00Z를 사용
  • +00:00은 Z로도 표기할 수 있음(YYYY-MM-DDTHH🇲🇲ss{.mmm}±hh:mm 또는 YYYY-MM-DDTHH🇲🇲ss{.mmm}Z)
  • 소속 타임존이 한국 표준시(KST)이고 채팅 발생 시간이 2023-03-30 17:13:00
  • 2023-03-30T17:13:00+09:00를 사용
  • 소속 타임존이 중부 표준시(CST)이고 채팅 발생 시간이 2023-03-30 17:13:00
  • 2023-03-30T17:13:00-05:00를 사용
room_num int Y 채팅방 번호 예) 123342
lang_code int Y 언어 코드 값
  • 한국어(ko) : 1
  • 영어(en) : 2
  • 일본어(ja) : 3
  • 중문 간체 : 4
  • 중문 번체 : 5
  • 에스파냐(es) : 6
  • 러시아(ru) : 7
  • 독일어(de) : 8
  • 프랑스어(fr) : 9
  • 포르투갈어(pt) : 10
  • 이태리어(it) : 11
  • 태국어(th) : 12
  • 인도네시아어(id) : 13
  • 터키어(tr) : 14
  • 말레이시아어(ms) : 15
  • 베트남어(vi) : 16
chat_msg string Y 유저 채팅 내용 예) 안녕하세요! 오늘 날씨가 좋네요
chat_mode int Y 채팅 형태 구분 예) 100: 일반 채팅 200: 그룹(1:1~N) 채팅 300: 귓속말 4NN: 게임사가 자체적으로 정의한 채팅 타입
channel_user_id int Y 게임 상의 유저 ID 번호(playerId)
  • Response
필드명 타입 설명
result object 출력 결과 컨테이너
result_code string 결과 코드
result_msg string 결과 메시지
  • Result Code
result_code result_msg 조치 방법
200 Success 전송 성공으로 별도의 조치가 필요 없습니다.
500 Incorrect request 요청에 오류가 있습니다. URL , 필요 요청 변수의 값이 정확한지 확인 바랍니다.
501 The number of messages does not match 전달 된 메시지의 카운트가 일치하지 않습니다. chat_count 값과 msg_array의 길이가 일치해야합니다.
502 Incorrect secret key 올바르지 않은 암호 키 값입니다. 게임 관리에서 해당 게임의 옵션 열의 "암호 키 확인"를 눌러 암호 키 값을 확인하시기 바랍니다.
503 Unregistered game key 올바르지 않은 게임 키 값입니다. 게임 관리에서 해당 게임의 옵션 열의 "암호 키 확인"를 눌러 게임 키 값을 확인하시기 바랍니다.
506 System error 채팅 로그 수집 시스템의 오류에 의한 점검 시 발생합니다.
507 The size of the message is too large 전달한 메시지의 사이즈가 너무 큽니다. msg_array의 최대 크기는 2KB 입니다.
  • 예시

    • Python
    import requests
    import json 
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    import base64
    
    
    game_key = <GAME_KEY>
    secret_key = <SECRET_KEY>
    aes = AES.new(secret_key, AES.MODE_ECB)
    url = "https://clcs.qpyou.cn/chat/api/v1/send-chat-log"
    
    ## 메시지 암호화
    def encrypt_msg(room_num:int,lang_code:int,chat_msg:str,chat_mode:int,channel_user_id:int) -> str:
        json_data = {
            "time_stamp":"2023-02-20T10:22:10+09:00", ## datetime.now().isoformat()
            "room_num":room_num,
            "lang_code":lang_code,
            "chat_msg":chat_msg,
            "chat_mode":chat_mode,
            "channel_user_id":channel_user_id
            }
        json_str = json.dumps(json_data)
        padded_str = pad(json_str.encode("utf-8"),AES.block_size)
        encrypted_data = aes.encrypt(padded_str)
        encrypted_data_b64 = base64.b64encode(encrypted_data).decode("utf-8")
        return encrypted_data_b64
    
    ## Json 정의
    json_payload = {
        "game_key":  game_key,
        "chat_log": {
            "chat_count": N, ## msg_array 리스트 사이즈
            "msg_array": [
                 {
                    "time_stamp":"2023-02-20T10:22:10+09:00", 
                    "msg":encrypt_msg(room_num,lang_code,.......)
                 },
                 {
                    "time_stamp":"2023-02-20T10:22:10+09:00", 
                    "msg":encrypt_msg(room_num,lang_code,.......)
                }, ...
            ]
        }
    }
    
    def call_curl_post(url, json_payload):
        headers = {'Content-type': 'application/json'}
        response = requests.post(url, data=json.dumps(json_payload), headers=headers)
    
    
    ## 함수 호출
    call_curl_post(url=url, json_payload)
    
    • Java
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.apache.tomcat.util.codec.binary.Base64;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    import net.minidev.json.JSONObject;   
    
    public class SampleCode {
    
        private String gameKey = <GAME_KEY>;
        private String secretKey = <SECRET_KEY>;
        private String url = "https://clcs.qpyou.cn/chat/api/v1/send-chat-log"
    
        public void callCurlPost() {
            RestTemplate restTemplate = new RestTemplate();
    
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
            headers.setContentType(MediaType.APPLICATION_JSON);
            Map<String, Object> parameters = new HashMap<>();
    
            parameters.put("game_key",  gameKey);
            parameters.put("chat_log", "{"chat_count" : N //msg_array 리스트 사이즈,"msg_array":[{"time_stamp":"2023-02-20T10:22:10+09:00", "msg":encrypt_msg(,,....)},{"time_stamp":"2023-02-20T10:22:10+09:00", "msg":encrypt_msg(,,....)}, ...]}");
    
            JSONObject jsonParam = getJsonStringFromMap(parameters);
    
            HttpEntity<JSONObject> requestEntity = new HttpEntity<>(jsonParam, headers);
    
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
    
            System.out.println("Response status code: " + response.getStatusCode());
            System.out.println("Response body: " + response.getBody());
        }
    
        // 메시지 암호화
        private String encrypt_msg(int room_num, int lang_code, String chat_msg, int chat_mode, int channel_user_id) throws Exception {
    
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("time_stamp", "2023-02-20T10:22:10+09:00"); //## "%Y-%m-%d %H:%M:%S",
            map.put("room_num", room_num);
            map.put("lang_code", lang_code);
            map.put("chat_msg", chat_msg);
            map.put("chat_mode", chat_mode);
            map.put("channel_user_id", channel_user_id);
            JSONObject encrypt_json = new JSONObject(map);
            String encrypt_str = encrypt_json.toJSONString();
            return encrypt(encrypt_str, secret_key);
        }
    
        // 암호화
        private String encrypt(String plainText, String key) throws Exception {
            byte[] keyBytes = key.getBytes("UTF-8");
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
            return Base64.encodeBase64String(encryptedBytes);
        }
    
        private static JSONObject getJsonStringFromMap( Map<String, Object> map )
        {
            JSONObject jsonObject = new JSONObject();
            for( Map.Entry<String, Object> entry : map.entrySet() ) {
                String key = entry.getKey();
                Object value = entry.getValue();
                jsonObject.put(key, value);
            }
    
            return jsonObject;
        }
    }
    
    • Curl

    //TEST CALL
    curl 
    -d '{"game_key": 회사 키,"chat_log":{"chat_count" : 1,"msg_array":[{"2023-02-20T10:22:10+09:00", "msg":"암호화된 텍스트"}]}}' 
    -H "Content-Type: application/json" 
    -X POST https://test-clcs.qpyou.cn/chat/api/v1/send-chat-log
    
    //HEADER
    POST https://clcs-qpyou.cn/v1/chat/send-chat-log
    Host: clcs-qpyou.cn
    User-Agent: curl/7.43.0
    Accept: */*
    Content-Type: application/json
    
    //BODY
    {
        "game_key":"abcdefghijklmnop",
        "chat_log":{
            "chat_count" : 2,
            "msg_array":[
                {                           
                    "time_stamp":"2023-02-20T10:22:10+09:00", 
                    "msg":"yBDyG1rCthbkXCSpSgGM+ZfHs/B3bZtnxq7f6BOPX2c1Bk8xRAwF6HbkDeN/9prpqeD......"
                },
                {
                    "time_stamp":"2023-02-20T10:22:10+09:00",
                    "msg":"yBDyG1rCthbkXCSpSgGM+ZfHs/B3bZtnxq7f6BOPX2c1Bk8xRAwF6HbkDeN....."
                }
            ]
        }
    }
    
    + 결과

    {
        "result":{
            "result_code":"100",
            "result_msg":"success"
        }
    }