Sending an Oracle Radio WebSocket Text Message
Send a TEXT_MESSAGE message to deliver a normal or critical text message to a Radio channel.
Permissions and Prerequisites
The following permissions and prerequisites apply to this operation.
| Requirement | Value |
|---|---|
| Authentication | Complete the supported authentication path for the client before sending this operation. See authentication. |
| Radio permission | A normal message requires radio.message.send. A critical message also requires radio.message.critical. |
| Channel access | The user must have message access to the channel. A critical message also requires critical-message access to the channel. |
| Session state | The WebSocket connection must be open, and the user must be subscribed to the target channel. |
Request
Send the TEXT_MESSAGE message as a JSON text message.
| Name | Data type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
type | string | Yes | None | Must be TEXT_MESSAGE. | Identifies the text-message operation. |
channel | string | No | default | Channel name. | Channel to which the message is sent. |
text | string | Yes | None | From 1 through 4096 characters. | Message content. |
user | string | No | None | No additional schema constraint. | Optional sender display name in the message schema. The service ignores this value and identifies the sender from the authenticated session. |
critical | boolean | No | false | true or false. | Whether to send the message as a critical alert. |
clientMessageId | string | No | None | Client-generated identifier. | Correlates a success or error response with this request and enables replay of a cached result. Reuse the same value only for the same logical request, not for changed content or a new attempt after correcting a confirmed rejection. |
{
"type": "TEXT_MESSAGE",
"channel": "operations",
"text": "All units stand by for briefing at 1400",
"user": "dispatcher1",
"critical": false,
"clientMessageId": "message-123"
}
Responses
The following table lists the messages the client can receive and explains their purpose.
| Message type | Kind | Description |
|---|---|---|
TEXT_MESSAGE_SENT | Direct response | Confirms the send to the initiating connection and reports the channel and delivery summary. |
TEXT_MESSAGE_RECEIVED | Asynchronous event | Delivers the message to eligible other WebSocket connections subscribed to the channel. The initiating connection doesn't receive this event for its own message. |
ERROR | Error | Terminates the request with an error and echoes clientMessageId when supplied. Authenticated authorization, channel-access, membership, and resource-absence failures use NotAuthorizedOrNotFound without identifying which condition caused the failure. Invalid text and processing failures also use ERROR. |
Use
TEXT_MESSAGE_SENT to confirm the send and delivery result on the initiating connection. It doesn't confirm that the message was durably saved to communication history. Don't wait for that connection to receive its own TEXT_MESSAGE_RECEIVED event. Match a success or error to the pending request by clientMessageId, not by channel alone.Repeating an identifier can return the cached success or error without processing the message again, even if the body or permissions have changed. After correcting a confirmed validation or authorization rejection, use a new identifier for a deliberate new attempt. Don't change identifiers automatically after an internal error or missing response: delivery can be indeterminate.
Retry protection is bounded and process-local, with no fixed protection period or guarantee across service restarts or replicas. For an indeterminate result after a disconnect, retain the unchanged request and reuse its original clientMessageId if retrying. After the cached result is lost, the same identifier can be processed again. See session recovery and message troubleshooting.
ERROR Response
An authenticated access or resource-absence failure returns the following response. The channel and reason properties are omitted so the response doesn't disclose channel existence, membership, or the missing permission.
{
"type": "ERROR",
"message": "Authorization failed or requested resource not found.",
"code": "NotAuthorizedOrNotFound",
"clientMessageId": "message-123"
}
The clientMessageId property is omitted when the request doesn't supply it. Missing, empty, or oversized text returns a correlated ERROR that can include the requested channel. Text must still contain from 1 through 4096 characters. For recovery, see WebSocket errors.
TEXT_MESSAGE_SENT Response
The following table describes the response properties, their data types, and whether they are required.
| Name | Data type | Required | Description |
|---|---|---|---|
type | string | Yes | Response type. The value is TEXT_MESSAGE_SENT. |
channel | string | Yes | Channel to which the message was sent. |
critical | boolean | No | Whether the message was sent as a critical alert. |
recipientCount | integer | No | Number of WebSocket connections that received the message. |
timestamp | string | No | Server date and time in ISO 8601 format. |
clientMessageId | string | No | Client-generated identifier from the request, when supplied. |
{
"type": "TEXT_MESSAGE_SENT",
"channel": "operations",
"critical": false,
"recipientCount": 5,
"timestamp": "2024-01-15T10:30:00Z",
"clientMessageId": "message-123"
}
TEXT_MESSAGE_RECEIVED Event
The following table describes the event properties, their data types, and whether they are required.
| Name | Data type | Required | Description |
|---|---|---|---|
type | string | Yes | Event type. The value is TEXT_MESSAGE_RECEIVED. |
channel | string | Yes | Channel on which the message was received. |
text | string | Yes | Message content. |
user | string | Yes | Username of the authenticated sender. |
senderDisplayName | string | Yes | Display name of the authenticated sender. |
critical | boolean | No | Whether the message is a critical alert. |
timestamp | string | No | Message date and time in ISO 8601 format. |
{
"type": "TEXT_MESSAGE_RECEIVED",
"channel": "operations",
"text": "All units stand by for briefing at 1400",
"user": "dispatcher1",
"senderDisplayName": "Dispatcher One",
"critical": false,
"timestamp": "2024-01-15T10:30:00Z"
}