> For the complete documentation index, see [llms.txt](https://docs.ggwp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ggwp.com/kr/api/standard-package/websocket.md).

# 웹소켓

\[ 기본 URL: `ws.ggwp.com`]

## **이벤트**

`service: chat, version: v1, action: message`

## **설명**

GGWP Chat API에는 개발자가 애플리케이션에 거의 실시간에 가까운 채팅 필터링 및 제재 기능을 구축할 수 있게 해주는 Websocket 엔드포인트가 포함되어 있습니다. 이 Websocket 엔드포인트는 위에 설명된 RESTful API와 동일한 기능 출력을 지원합니다.

## **헤더**

다음을 참조하세요 `헤더` 위 섹션에서 `/chat/v2/message` 엔드포인트, 이 웹소켓 엔드포인트는 동일한 `x-api-config` 헤더를 사용해 채팅 필터를 구성합니다.

## **프로토콜**

GGWP 웹소켓 엔드포인트는 WebSocket Secure(`wss`) 프로토콜만 지원합니다.

## **제약**

* 웹소켓 엔드포인트의 최대 연결 지속 시간은 2시간으로 제한됩니다. 이후 자동으로 연결이 끊기며, 서비스를 계속 사용하려면 다시 연결해야 합니다.
* 웹소켓 엔드포인트 연결이 10분 동안 유휴 상태이면(즉, 메시지가 전송되지 않으면) 자동으로 연결이 끊기며 다시 연결해야 합니다.

## **매개변수**

`payload`: 다음 필드를 포함하는 딕셔너리:

* **session\_id:** 대화 채널의 고유 식별자입니다. 게임플레이 메시지의 경우 단일 매치에서 전개되는 대화를 식별할 수 있습니다. 포럼이나 게시판에서는 개별 스레드나 토론을 나타낼 수 있습니다. 플랫폼에 다양한 채널 유형(예: 로비, 매치, 다이렉트 메시지 등)이 있는 경우, 대화 유형별 추가 분석을 위해 이 정보를 session\_id에 포함하는 것을 권장합니다. 권장 형식은 다음과 같습니다:

  ```json
    session_id = "channelType_numericID"
  ```
* **message:** 대화 중 사용자가 보낸 메시지입니다. 1,000자를 초과할 수 없습니다.
* **user\_id:** 메시지를 보낸 플레이어 또는 사용자의 고유 식별자입니다.
* (선택 사항) **username**: 사용자가 선택한 친숙한 표시 이름을 담은 문자열입니다.
* (선택 사항) **timestamp:** 메시지가 발생한 시간 *YYYY-MM-DD HH:MM:SS.SSS or YYYY-MM-DD HH:MM:SS* 형식의 UTC 시간입니다. 추가되지 않으면 서버 측 UTC 타임스탬프가 대신 추가됩니다.
* (선택 사항) **language**: 처리할 메시지의 언어입니다. 생략하면 API는 메시지 내용과 이전 사용자 기록을 바탕으로 언어를 감지하려고 시도합니다. 표준 영어 언어 이름(예: `"english"` 또는 `"spanish"`), 그리고 ISO 639-1 두 글자 언어 코드(예:  `"en"` 또는 `"es"`). 다음과 같은 전체 로케일 태그는 `"en-US"`, `"en-GB"`, `"pt-BR"`, 그리고 `"es-MX"` 현재 지원되지 않습니다. 보내세요 `"en"`, `"pt"`, 또는 `"es"` 대신.
* (선택 사항) **message\_index**: 전송된 메시지를 추적하는 문자열 필드입니다. 출력에는 아래의 `message_details` 에 포함됩니다.
* (선택 사항) **request\_index:** 전송된 비동기 요청을 추적하는 문자열 필드입니다.
* (선택 사항) **message\_url**: 메시지에 태그된 URL을 추적하는 문자열 필드입니다. http 또는 https 스킴만 유효합니다. 유효하고 전달되면 대시보드에 표시됩니다.
* (선택 사항) **metadata**: 메시지와 관련된 메타데이터를 추적하는 Dict 필드입니다. 5KB 이하여야 합니다. 허용된 키와 해당 유형만 유효합니다. 지원되는 키:

  * channel (string) - 메시지가 전달되는 통신 공간입니다. 예: dm, party, guild, local
  * participants (array\<string>) - 채널에 참여하는 user\_ids
  * map (string) - 메시지가 발생한 세계, 레벨 또는 환경의 식별자 또는 이름
  * map\_version (string) - 맵의 버전 식별자로, 레이아웃 등의 변경 사항을 추적하는 데 사용됩니다.
  * zone (string) - 더 세부적인 위치 맥락을 위해 사용되는 맵 내의 하위 구역 또는 이름이 있는 지역
  * coordinates (object) - 맵 또는 구역 내의 공간적 위치
    * x (float) - X축을 따른 위치
    * y (float) - Y축을 따른 위치
    * z (float) - Z축을 따른 위치

  예시:

  ```json
  {
    "metadata": {
      "channel": "dm",
      "participants": ["user989", "user990"],
      "map":"golden_wasteland",
      "map_version":"2026.03.1",
      "zone":"cacti_forest",
      "coordinates":{
         "x":123.45,
         "y":67.89,
         "z":-10.25
      }
    }
  }
  ```

  참고: 추가 메타데이터 키를 지원할 수 있습니다. 귀사 플랫폼에 적용 가능한 구체적인 키를 정의하려면 고객 담당자와 협의하세요.

예시

```json
{
	"service": "chat", 
	"version": "v1", 
	"action": "message", 
	"payload": {
		"session_id": "match_7765", 
		"message": "fucking retards everywhere", 
		"user_id": "user989", 
		"username": "nlxdz", 
		"timestamp": "2022-06-02 16:49:02", 
		"request_index": "1"
	}
}
```

샘플 호출:

다음 예시는 [wscat](https://www.npmjs.com/package/wscat) 을 애플리케이션 클라이언트로 사용해 웹소켓 엔드포인트에 연결하는 방법입니다:

```bash
wscat --header 'x-api-key: api_key' \\
--connect 'wss://ws.ggwp.com' \\
--execute '{
	"service": "chat", 
	"version": "v1", 
	"action": "message", 
	"payload": {
		"session_id": "match_7765", 
		"message": "fucking retards everywhere", 
		"user_id": "user989", 
		"username": "nlxdz", 
		"timestamp": "2022-06-02 16:49:02", 
		"request_index": "1"
	}
}'
```

## **응답**

* 성공 시

다음 필드를 포함하는 딕셔너리:

* **message\_details**: 페이로드에 전달된 메시지와 관련된 세부 정보
  * message\_details.message\_id: 메시지에 할당된 고유 식별자입니다.
  * message\_details.original\_message: 사용자가 보낸 원본 메시지입니다.
  * message\_details.flag: 메시지가 플래그 처리되었는지 여부를 나타냅니다.
  * message\_details.severity: 독성의 심각도(none, low, medium, high).
  * message\_details.filtered\_message: 플래그된 용어가 필터링된 메시지 버전입니다.&#x20;
    * 공백으로 단어가 구분되는 언어(예: 영어)에서는 전체 단어가 필터링됩니다. 예: `You are a shithead` --> `You are a *****`
    * 명시적인 단어 경계가 없는 언어(예: 한국어, 일본어, 중국어)에서는 감지된 용어 자체만 필터링됩니다. 예: `좆까고 있네`--> `*****고 있네`
  * message\_details.replaced\_message: 원래 메시지를 대체하기 위해 생성된 안전하거나 유머러스한 대안입니다.
  * message\_details.recommended\_message: 클라이언트에 전달할 메시지의 권장 버전입니다. 활성 사용자에게는 이 값이 기본적으로 `filtered_message`. 뮤트된 사용자에게는 `recommended_message` 는 빈 문자열이 됩니다.
  * message\_details.language: 감지된 메시지의 언어입니다.
  * message\_details.violence: 메시지에 폭력이 포함되어 있으면 true입니다.
  * message\_details.verbal\_abuse: 메시지에 언어폭력이 포함되어 있으면 true입니다.
  * message\_details.profanity: 메시지에 욕설이 포함되어 있으면 true입니다.
  * message\_details.sexual\_content: 메시지에 선정적인 내용이 포함되어 있으면 true입니다.
  * message\_details.identity\_hate: 메시지에 정체성 혐오가 포함되어 있으면 true입니다.
  * message\_details.drugs: 메시지에 약물 관련 언급이 포함되어 있으면 true입니다.
  * message\_details.self\_harm: 메시지에 자해가 포함되어 있으면 true입니다.
  * message\_details.custom: 메시지에 사용자 지정 차단 목록 용어가 포함되어 있으면 true입니다.
  * message\_details.spam: 메시지에 스팸이 포함되어 있으면 true입니다.
  * message\_details.link: 메시지에 외부 링크가 포함되어 있으면 true입니다.
  * message\_details.pii: 메시지에 개인 식별 정보가 포함되어 있으면 true입니다.
* **player\_details**: 다음과 관련된 세부 정보를 포함하는 딕셔너리: `user_id` 가 포함된 페이로드의 `session_id`
  * player\_details.user\_id: 사용자의 고유 식별자입니다.
  * player\_details.username: 사용자의 표시 이름입니다.
  * player\_details.num\_messages: 전송된 메시지의 총 수입니다.
  * player\_details.num\_incidents: 사건 수입니다.
  * player\_details.cumulative\_mood: 사용자의 메시지에 대한 전체 감성입니다.
  * player\_details.min\_mood: 사용자의 메시지에서 관찰된 가장 낮은 감성입니다.
  * player\_details.max\_mood: 사용자의 메시지에서 관찰된 가장 높은 감성입니다.
  * player\_details.incident\_types\_detected: 사용자와 관련된 사건 유형 목록입니다.
  * player\_details.incidents\_by\_severity: 심각도 수준별로 분류된 사건 내역입니다.
  * player\_details.reputation\_score: 행동 기록에서 파생된 전체 사용자 평판 점수입니다.
  * player\_details.languages: 사용자 메시지에서 감지된 언어입니다.
  * player\_details.user\_status: 사용자의 현재 모더레이션 상태입니다(예: 활성, 뮤트).
  * player\_details.user\_status.status: 적용된 구체적인 모더레이션 조치입니다(뮤트 등).
  * player\_details.user\_status.expiry\_at: 모더레이션 조치가 만료되는 시간입니다.
* **conversation\_summary**: 다음과 관련된 세부 정보를 포함하는 딕셔너리: `session_id` 의 페이로드
  * conversation\_summary.start\_time: 대화 세션이 시작된 타임스탬프입니다.
  * conversation\_summary.session\_duration: 대화의 총 지속 시간(초)입니다.
  * conversation\_summary.num\_messages: 대화의 총 메시지 수입니다.
  * conversation\_summary.num\_participants: 대화 참여자 수입니다.
  * conversation\_summary.num\_incidents: 사건 총 수입니다.
  * conversation\_summary.conversation\_mood: 전체 대화의 감성입니다.
  * conversation\_summary.incident\_types\_detected: 대화 전체에서 발견된 사건 유형 목록입니다.
  * conversation\_summary.incidents\_by\_severity: 심각도 수준별로 분류된 사건 내역입니다.
* **recommendations**: 다음에 대해 수행할 권장 조치를 포함하는 딕셔너리: `user_id`
  * recommendations.\<user\_id>.action: 권장된 모더레이션 조치입니다(예: 뮤트).
  * recommendations.\<user\_id>.trigger\_message: 권장 사항을 유발한 문제 메시지입니다.
  * recommendations.\<user\_id>.trigger\_time: 트리거된 메시지의 타임스탬프입니다.
  * recommendations.\<user\_id>.duration: 조치가 유효해야 하는 시간 길이(초)입니다.
* **request\_index**: 전송된 비동기 요청을 추적하는 인덱스입니다.

샘플 출력:

```json
{
	"message_details": {
		"message_id": "20220602164902.482311-946bb8a9-0766-4c31-995a-d910da8531e5",
		"original_message": "fucking retards everywhere",
		"flag": true,
		"severity": "high",
		"filtered_message": "***** ***** everywhere",
		"replaced_message": "It's gonna be legen..wait for it..dary..",
		"recommended_message": "",
		"language": "english",
		"violence": false,
		"verbal_abuse": false,
		"profanity": true,
		"sexual_content": false,
		"identity_hate": true,
		"drugs": false,
		"self_harm": false,
		"custom": false,
		"spam": false,
		"link": false,
		"pii": false,
		"solicitation": false,
	    	"scam": false
	},
	"player_details": {
		"user_id": "user989",
		"username": "nlxdz",
		"num_messages": 1,
		"num_incidents": 1,
		"cumulative_mood": -0.8518,
		"min_mood": -0.8518,
		"max_mood": -0.8518,
		"incident_types_detected": [
			"identity_hate_language",
			"profanity",
			"identity_hate",
			"chat_verbal_abuse"
		],
		"incidents_by_severity": {
			"high": 1
		},
		"reputation_score": 450,
	        "languages": [
			"english"
		],
		"user_status": {
			"status": "session-muted",
			"expiry_at": "2022-06-02 17:49:02"
		}
	},
	"conversation_summary": {
		"start_time": "2022-06-02 16:49:02.000000",
		"session_duration": 0,
		"num_messages": 1,
		"num_participants": 1,
		"conversation_mood": -0.8518,
		"incident_types_detected": [
			"identity_hate_language",
			"profanity",
			"identity_hate",
			"chat_verbal_abuse"
		],
		"incidents_by_severity": {
			"high": 1
		}
	},
	"recommendations": {
		"user989": [
			{
				"action": "session-mute",
				"trigger_message": "fucking retards everywhere",
				"trigger_time": "2022-06-02 16:49:02.000000",
				"duration": 3600
			}
		]
	},
	"request_index": "1"
}
```

* 잘못된 페이로드일 때

```json
잘못된 입력 키: <INPUT KEY>. 문서를 참조하세요
```

* 잘못된 경로일 때(잘못된 `service`, `version`, 및/또는 `action`)

```json
{'success': False, 'msg': '잘못된 동작'}
```

* 400
  * 잘못되었거나 형식이 올바르지 않은 요청입니다. 가능한 원인:
    * &#x20;잘못된 JSON 본문 입력
    * &#x20;5KB를 초과하거나 허용되지 않은 키를 포함하는 메타데이터를 포함한 잘못된 헤더
    * &#x20;필수 필드 누락: `user_id`, `session_id`,  `message`
    * &#x20;잘못된 입력 형식: 잘못된 타임스탬프 형식, 메시지 글자 수 제한 초과 등.&#x20;
* 403
  * 웹소켓 연결 시
    * 유효하지 않거나 누락된 API 키
    * 잘못됨 `x-api-config`
* 500
  * 내부 서버 오류
