DCAS handbook

Message Acknowledge

General notes

  • Acks has common global version, called just version:
    • incremened by server each time client acks any channel;
    • sent to client at start-up in ready / read_state dict;
    • updated on client via MESSAGE_ACK dispatch event;
  • Each channel may also have last_viewed:
    • sent by client during automatic ack;
    • appears to be calculated as last view day since discord epoch + 1;
    • dunno why +1 tho;

Observed behavior

Captured at: Feb 2025

READY event

READY gateway event contains read_state dict that seems to be related to message acknowledgement procedure. Its entries field contains a lot of records, most of it looks like type #1 or #2 shown in json below:

{
    "t": "READY",
    "s": 1,
    "op": 0,
    "d": {
        "read_state": {
            "version": 413391,
            "partial": false,
            "entries": [
                {
                    "mention_count": 0,
                    "last_viewed": 3695,
                    "last_pin_timestamp": "1970-01-01T00:00:00+00:00",
                    "last_message_id": "{message}",
                    "id": "{channel}",
                    "flags": 1
                },
                {
                    "mention_count": 0,
                    "last_pin_timestamp": "2021-01-01T12:00:00+00:00",
                    "last_message_id": "{message_2}",
                    "id": "{channel_2}",
                    "flags": 0
                },
                {
                    "read_state_type": 1,
                    "last_acked_id": "1210241532813246524",
                    "id": "{guild_id}",
                    "badge_count": 0
                },
                {
                    "read_state_type": 2,
                    "last_acked_id": "1260630723572793344",
                    "id": "{@me_id}",
                    "badge_count": 0
                },
            ]
        }
    }
}

Entries types:

  • type #1 is the most common entry in the list.
    • last_viewed differs between entries;
    • flags meaning is unknown. Seen values to presumend meaning:
      • 0: DM;
      • 1: guild channel;
      • 2: threads;
  • type #2 is much like type #1, but has last_viewed field absent;
  • type #3 is quite rare – two items in my case;
  • type #4 ocurred once in the list and has the same id as my user_id;

Automatic ACK

Happens when client hops into channel w/ new messages and scrolls it to the bottom or clicks on the blue line “Mark as read” on top of the chat.

Client do:

POST /api/v9/channels/{channel}/messages/{message}/ack
BODY { "token": null, "last_viewed": 3695 }

Server’s http response:

CODE 200 OK
BODY { "token": null }

Gateway responds:

{
    "t": "MESSAGE_ACK",
    "s": 34,
    "op": 0,
    "d": {
        "version": 413392,
        "channel_id": "{channel}",
        "message_id": "{message}",
        "last_viewed": 3695,
        "flags": 1,
    }
}

Manual ACK

Then, user manually “Marked Unread” some earlier message in that chat.

Client do:

POST /api/v9/channels/{channel}/messages/{message}/ack
BODY { "manual": true, "mention_count": 1 }

Server’s http response:

CODE 200 OK
BODY { "token": null }

Gateways responds:

{
    "t": "MESSAGE_ACK",
    "s": 35,
    "op": 0,
    "d": {
        "version": 413393,
        "channel_id": "{channel}",
        "message_id": "{message}",
        "last_viewed": null,
        "flags": 1,

        "manual": true,
        "mention_count": 1,
        "ack_type": 0
    }
}