> 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/api-docs-chat/standard-package/websocket.md).

# Websocket

\[ Base URL: `ws.ggwp.com`]

## **Event**

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

## **Description**

The GGWP Chat API includes a Websocket endpoint that allow developers to build near real-time chat filtering and sanctioning functionality into their applications. This Websocket endpoint support the same functionality output as the RESTful APIs detailed above.

## **Headers**

Please refer to `Headers` section above for `/chat/v2/message` endpoint, this websocket endpoint uses the same `x-api-config` header above to configure the chat filters.

## **Protocols**

The GGWP websocket endpoint only supports the Websocket Secure (`wss`) protocol.

## **Constraints**

* The websocket endpoint has a hard limit of 2 hours max connection duration. It disconnects automatically after this and needs re-connection to continue using the services.
* If the websocket endpoint connect stays idle for 10 min (i.e., no messages are sent to it) then it disconnects automatically and requires re-connection.

## **Parameters**

`payload`: Dictionary containing the following fields:

* **session\_id:** Unique identifier for the conversation channel. For gameplay messages, this could identify a conversation that unfolds over a single match. On forums or message boards, this could represent a distinct thread or discussion. If your platform contains various channel types (eg: lobby, match, direct message, etc.), we recommend that you include this information in the session\_id to enable further analysis by conversation type. This is the suggested format:

  ```json
    session_id = "channelType_numericID"
  ```
* **message:** Message sent by a user during the conversation. Cannot exceed 1,000 characters.
* **user\_id:** Unique identifier for a player or user who sent the message.
* (OPTIONAL) **username**: String with the friendly display name picked by the user.
* (OPTIONAL) **timestamp:** Time the message took place in *YYYY-MM-DD HH:MM:SS.SSS or YYYY-MM-DD HH:MM:SS* format, in UTC. If not added, then server side UTC timestamp is added in its place.
* (OPTIONAL) **language**: Language of the message to be processed. If omitted, the API will attempt to detect the language from the message content and prior user history. Accepts standard English language names (eg: `"english"` or `"spanish"`), and ISO 639-1 two-letter language codes (eg:  `"en"` or `"es"`). Full locale tags such as `"en-US"`, `"en-GB"`, `"pt-BR"`, and `"es-MX"` are not currently supported; send `"en"`, `"pt"`, or `"es"` instead.
* (OPTIONAL) **message\_index**: String field to track the message sent. Will be included in the output under `message_details` if passed.
* (OPTIONAL) **request\_index:** String field to track the asynchronous request sent.
* (OPTIONAL) **message\_url**: String field to track the url tagged to the message. Only http or https schemes are valid. Will be visible in the dashboard if valid and passed.
* (OPTIONAL) **metadata**: Dict field to track any metadata associated with the message. Must be under 5KB.  Only permitted keys and corresponding types are valid. Supported keys:

  * channel (string) - communication space that the message is passed to. E.g. dm, party, guild, local
  * participants (array\<string>) - the user\_ids participating in the channel
  * map (string) - identifier or name of the world, level, or environment where the message originates
  * map\_version (string) - version identifier of the map, used to track changes in layout, etc.
  * zone (string) - subsection or named region within a map used for finer-grained location context
  * coordinates (object) - spatial position within the map or zone
    * x (float) - position along the X-axis
    * y (float) - position along the Y-axis
    * z (float) - position along the Z-axis

  Example:

  ```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
      }
    }
  }
  ```

  Note: Additional metadata keys can be supported. Please work with your customer representative to define the specific keys that will be applicable to your platform.

Example

```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"
	}
}
```

Sample call:

The follow example uses [wscat](https://www.npmjs.com/package/wscat) as an application client to connect to the websocket endpoint:

```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"
	}
}'
```

## **Response**

* On Success

Dictionary containing the following fields:

* **message\_details**: details pertaining to the message passed in the payload
  * message\_details.message\_id: Unique identifier assigned to the message.
  * message\_details.original\_message: The raw message sent by the user.
  * message\_details.flag: Indicates whether the message was flagged.
  * message\_details.severity: Severity of the toxicity (none, low, medium, high).
  * message\_details.filtered\_message: Version of the message with flagged terms filtered.&#x20;
    * For space-delimited languages (e.g., English), entire words are filtered. E.g. `You are a shithead` --> `You are a *****`
    * For languages without explicit word boundaries (e.g., Korean, Japanese, Chinese), only the detected term itself is filtered." E.g. `좆까고 있네`--> `*****고 있네`
  * message\_details.replaced\_message: Safe or humorous alternative generated to replace the original message.
  * message\_details.recommended\_message: Suggested version of the message to be passed to the client. For active users, this value defaults to `filtered_message`. For muted users, the `recommended_message` will be an empty string.
  * message\_details.language: Detected language of the message.
  * message\_details.violence: true if the message contains violence.
  * message\_details.verbal\_abuse: true if the message contains verbal abuse.
  * message\_details.profanity: true if the message contains profanity.
  * message\_details.sexual\_content: true if the message contains sexual content.
  * message\_details.identity\_hate: true if the message contains identity hate.
  * message\_details.drugs: true if the message contains drug references.
  * message\_details.self\_harm: true if the message contains self harm.
  * message\_details.custom: true if the message contains custom blocklist terms.
  * message\_details.spam: true if the message contains spam.
  * message\_details.link: true if the message contains external links.
  * message\_details.pii: true if the message contains personally identifiable information.
* **player\_details**: Dictionary containing details pertaining to the `user_id` of the payload within the `session_id`
  * player\_details.user\_id: Unique identifier for the user.
  * player\_details.username: Display name of the user.
  * player\_details.num\_messages: Total number of messages sent.
  * player\_details.num\_incidents: Number of incidents.
  * player\_details.cumulative\_mood: Overall sentiment for the user's messages.
  * player\_details.min\_mood: Lowest sentiment observed for the user’s messages.
  * player\_details.max\_mood: Highest sentiment observed for the user’s messages.
  * player\_details.incident\_types\_detected: List of incident types associated with the user.
  * player\_details.incidents\_by\_severity: Breakdown of incidents grouped by severity level.
  * player\_details.reputation\_score: Overall user reputation score derived from behavior history.
  * player\_details.languages: Languages detected from the user’s messages.
  * player\_details.user\_status: Current moderation state of the user (e.g., active, muted).
  * player\_details.user\_status.status: Specific moderation action applied (muted, etc.).
  * player\_details.user\_status.expiry\_at: Time when the moderation action expires.
* **conversation\_summary**: Dictionary containing details pertaining to the `session_id` of the payload
  * conversation\_summary.start\_time: Timestamp when the conversation session began.
  * conversation\_summary.session\_duration: Total duration of the conversation (in seconds).
  * conversation\_summary.num\_messages: Total number of messages in the conversation.
  * conversation\_summary.num\_participants: Number of users in the conversation.
  * conversation\_summary.num\_incidents: Total count of incidents.
  * conversation\_summary.conversation\_mood: Overall sentiment for the entire conversation.
  * conversation\_summary.incident\_types\_detected: List of incident types found across the conversation.
  * conversation\_summary.incidents\_by\_severity: Breakdown of incidents grouped by severity level.
* **recommendations**: Dictionary containing the recommended action to perform on the `user_id`
  * recommendations.\<user\_id>.action: Suggested moderation action (e.g., mute).
  * recommendations.\<user\_id>.trigger\_message: Offending message that triggered the recommendation.
  * recommendations.\<user\_id>.trigger\_time: Timestamp of the triggering message.
  * recommendations.\<user\_id>.duration: Length of time (in seconds) the action should remain in effect.
* **request\_index**: index to track the asynchronous request sent.

Sample Output:

```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"
}
```

* On Invalid Payload

```json
Invalid Input Keys: <INPUT KEY>. Please refer to the documentation
```

* On Invalid Route (either invalid `service`, `version`, and/or `action`)

```json
{'success': False, 'msg': 'Invalid action'}
```

* 400
  * Invalid or malformed request. Possible causes:
    * &#x20;Invalid JSON body Input
    * &#x20;Invalid headers, including metadata that exceeds 5KB or contains disallowed keys
    * &#x20;Missing required fields: `user_id`, `session_id`,  `message`
    * &#x20;Invalid Input format: Invalid timestamp format, exceeding message character limit, etc.&#x20;
* 403
  * On WebSocket Connection
    * Invalid or missing API key
    * Invalid `x-api-config`
* 500
  * Internal Server Error
