message_new
message_new posts a message. It can carry text, embeds, attachments, or any mix of them, and can reply to another message. The same command name is used for the event that tells everyone about the new message.
Request
Section titled “Request”{ "cmd": "message_new", "channel": "general", "content": "Release notes are up: https://example.com/changelog", "reply_to": "0b6c7f55-4a0f-4f7e-9a53-1a8b0d3d52c1", "ping": false}| Field | Type | Required | Description |
|---|---|---|---|
channel |
string | One of channel or thread_id |
Channel name. Must be a text or voice channel. |
thread_id |
string | One of channel or thread_id |
Thread ID. Required for forum channels. If you also send channel, it must be the thread’s parent. |
content |
string | See below | Message text. At most limits.post_content characters (from the handshake; 2000 by default). |
embeds |
array | See below | Up to 10 embed objects. At most one can be a poll. |
attachments |
array | See below | Objects with the id of a file you uploaded first. See uploading attachments. |
reply_to |
string | No | ID of a message in the same channel or thread to reply to. |
ping |
boolean | No | Set false so a reply does not notify the author of the original message. Defaults to true. |
alias |
object | No | Show a different name on this message: name (required, up to 80 characters), avatar (URL, up to 2048 characters), and usercolor (up to 64 characters). An empty object means no alias. |
author_id |
string | No | Signing field. Your own user ID. |
key_id |
string | No | Signing field. Your Rotur signing key ID, starting with rotur_sk_. |
signature |
string | No | Signing field. The signature, 80 to 100 characters. |
timestamp |
number | No | Signing field. When you signed, in Unix seconds. Must be within 5 minutes of the server clock. |
The message must have non-empty content, at least one embed, or at least one attachment.
- Attachments. The server replaces each known attachment ID with the stored attachment record. It keeps
widthandheightfrom your object if they are numbers. An ID it doesn’t know is saved exactly as you sent it. - Polls. To create a poll, add an embed with
"type": "poll"and apollobject. The server creates the poll and replaces the embed’spollwith{ "id": "<poll id>" }. See polls. - Signing. Rotur accounts can sign messages so other clients can prove who wrote them. Send all four signing fields together. The server checks their format and the time window, then stores them on the message. Server-local accounts can’t sign; the server ignores these fields for them. See signing.
- Mentions. Write
@usernameto mention a user and@&roleto mention a role. You can only mention roles you are allowed to mention.
Response
Section titled “Response”The server sends this event to you and to every other connection that can view the channel:
{ "cmd": "message_new", "channel": "general", "message": { "id": "7d0e4c1a-5b8f-4b0e-8f55-2d3c9a61e7b4", "user": "alice", "author_id": "<alice's user ID>", "timestamp": 1788940000.31, "content": "Release notes are up: https://example.com/changelog", "reply_to": { "user": "bob", "id": "0b6c7f55-4a0f-4f7e-9a53-1a8b0d3d52c1", "preview": "When do the release notes go out?" }, "ping": false }}messageis the saved message object. Store itsid; the server makes it, not you.- A thread message has
thread_idon both the frame and the message, andchannelis the thread’s parent. reply_to.previewis the first 40 characters of the original message.- Only your copy carries your request’s
listener. Users severed from you don’t receive the event. A moderator can sever two users with the/severslash command so they no longer see each other.
Follow-up frames
Section titled “Follow-up frames”Some messages cause more frames after message_new:
- Sticky message. If the channel has a sticky message (set with the built-in
/stickyslash command), a new channel message moves it to the bottom. Everyone who can view the channel getsmessage_deletewith the sticky message’sid, thenmessage_newwith the sticky message and a newertimestamp. This doesn’t happen for thread messages. - Archived thread. Posting in an archived thread unarchives it.
- Push notifications. If the server has push notifications set up, it queues them for the message’s recipients. They go out through the push service, not the WebSocket. See notifications.
- Link previews. See below.
Link previews
Section titled “Link previews”When the handshake capabilities include server_side_embeds, the server builds link previews in the background. It looks at up to five http or https URLs in content. It skips URLs inside code blocks, inline code, and angle brackets such as <https://example.com>. Direct links to images, video, and audio become media embeds. For other pages, the server reads the page’s title, description, and image.
If this changes the message’s embeds, the server saves them and sends message_edit to every connection that can view the channel and reported the server_side_embeds capability:
{ "cmd": "message_edit", "id": "7d0e4c1a-5b8f-4b0e-8f55-2d3c9a61e7b4", "channel": "general", "message": { "id": "7d0e4c1a-5b8f-4b0e-8f55-2d3c9a61e7b4", "user": "alice", "author_id": "<alice's user ID>", "timestamp": 1788940000.31, "content": "Release notes are up: https://example.com/changelog", "embeds": [ { "id": "3f786850e387550fda", "type": "link", "url": "https://example.com/changelog", "generated": true, "title": "Changelog", "description": "Everything new in this release." } ] }}- A thread message’s frame also has
thread_id. - Generated embeds have
"generated": true. Your own embeds stay first, and the total never goes above 10. - The message is not marked as edited.
- The same process runs after a
message_editthat changes the content. Removing a link removes its preview. - Previews are best effort. The server skips private network addresses, gives up on slow pages, and drops the job if its queue is full.
Permissions
Section titled “Permissions”Your roles must allow view and send in the channel. In a thread you need the same on the parent channel, and the thread must be unlocked.
Slow mode applies when the channel has a slow_mode_cooldown. Admins and users with the manage_server permission are exempt. A user in a timeout can’t send messages.
Errors
Section titled “Errors”val |
When |
|---|---|
Channel not found |
The channel doesn’t exist, or you sent neither channel nor thread_id. |
Thread not found |
No thread has this ID. |
Thread does not belong to this channel |
channel is not the thread’s parent. |
Messages must be sent inside a thread in forum channels |
channel is a forum and you sent no thread_id. |
This channel does not support chat |
channel is a separator. |
Access denied to this channel |
You can’t view the channel. |
You do not have permission to send messages in this channel |
You can’t send in the channel. |
You do not have permission to send messages in this thread |
You can’t view or send in the parent channel, or the thread is locked. |
Signed message author does not match the authenticated user |
author_id is not your user ID. |
Message signature is invalid |
key_id doesn’t start with rotur_sk_, or signature is not 80 to 100 characters. |
Message signed timestamp is outside the allowed window |
timestamp is more than 5 minutes from the server clock. |
Cannot have more than 10 embeds |
embeds has more than 10 items. |
A message can only contain one poll |
More than one embed has "type": "poll". |
Embed <n>: <problem> |
Embed number n (counting from 1) is invalid. See the message schema for embed rules. |
Attachment <n>: id is required |
Attachment number n has no id. |
alias.name is required |
alias has fields but no name. Other alias. messages report a wrong type or length. |
Attachment storage is unavailable |
The server could not read its attachment records. |
Attachment <id> not found or expired |
The attachment has expired or its file is gone. |
Message must have content, attachments, or embeds |
The message would be empty. |
You do not have permission to mention the '@&<role>' role |
You mentioned a role you can’t mention. |
Message too long. Maximum length is <n> characters |
content is longer than limits.post_content. |
Replied message not found |
reply_to is not a message in this channel or thread. |
Message blocked by automod |
Automod matched the message. You may also be put in a timeout. |
Unable to save message |
The server could not save the message. |
Invalid poll data returns the poll validation message. A field with the wrong type returns a validation message.
Slow mode returns a rate_limit frame instead of an error:
{ "cmd": "rate_limit", "reason": "Slow mode is active in this channel. Wait 3.2 more seconds before sending another message.", "length": 3200, "cooldown": 10, "last_message_timestamp": 1788939996.8}length is the wait in milliseconds. A user in a timeout also gets a rate_limit frame; see the protocol model.
