mark_as_read
Send read receipts for one or more messages. Read receipts inform the sender that you’ve read their message(s). For group messages, you must pass the original sender’s JID as thesender parameter.
message_ids is a borrowed slice &[&str] to avoid per-call allocations — pass &["ID"] or &["ID_1", "ID_2"].Chat JID where the messages were received. Can be:
- Direct message:
15551234567@s.whatsapp.net - Group:
120363040237990503@g.us
Message sender JID. Required for group messages,
None for direct messages.- For DMs: Pass
None - For groups: Pass the JID of the user who sent the message(s)
List of message IDs to mark as read. Can be a single ID or multiple IDs.If empty, this function returns immediately without sending anything.
Example: mark DM as read
Example: mark group message as read
Example: mark multiple messages as read
Read receipts are not sent automatically by the library. You must explicitly call
mark_as_read() when you want to notify the sender that messages have been read.mark_as_read adapts the wire shape to the chat, matching WhatsApp Web. A newsletter read is sent as read-self. A status@broadcast read carries context="status". When the status author is a LID, it also adds peer_participant_pn (the resolved LID→PN). The same call handles all three cases — you don’t pass anything extra.mark_as_played
Send played receipts for one or more voice notes or video notes. Played receipts tell the sender that you’ve listened to their voice note or watched their video note — they’re the equivalent of “read” for playable media. Call this only after the user has actually played the media; if you just want to acknowledge that the message was opened, usemark_as_read instead.
message_ids is a borrowed slice &[&str], matching mark_as_read.Chat JID where the media message was received. Can be a direct message, group, broadcast list, or newsletter JID.
Original sender JID.
- For DMs: pass
None(theparticipantattribute is dropped on the wire, matching WhatsApp Web). - For groups, broadcast lists, and status broadcasts: pass the JID of the user who sent the media.
- For newsletters: the receipt is sent as
played-self;senderis ignored.
Message IDs of the voice or video notes to mark as played. The first ID becomes the receipt’s
id attribute; any additional IDs are batched into a <list><item/></list> child, the same shape as mark_as_read.If empty, this function returns immediately without sending anything.Example: mark a DM voice note as played
Example: mark a group voice note as played
Example: mark multiple voice notes as played
Played receipts are not sent automatically — call
mark_as_played() from your media player when the user finishes (or starts) playing the audio or video note. The library does not gate this call on the recipient’s read-receipts privacy setting, matching mark_as_read.send_delivery_receipt (Internal)
Sends a delivery receipt to the sender of a message. This is an internal method called automatically by the library when messages are received. You typically don’t need to call this directly.Message metadata containing:
id- Message IDsource.chat- Chat JIDsource.sender- Sender JIDsource.is_from_me- Whether this is your own messagesource.is_group- Whether this is a group message
Behavior
Delivery receipts are automatically sent for all incoming messages except:- Your own messages (
is_from_me = true) - Messages without an ID
- Status broadcast messages (
status@broadcast) - Newsletter messages
participant attribute identifying the sender.
Delivery receipts are sent automatically. Unlike other receipt types (e.g.,
type="read", type="played"), delivery receipts have no type attribute on the wire — delivery is the implicit default. The library omits the type attribute from ack responses to delivery receipts accordingly, since including an explicit type="delivery" would cause <stream:error> disconnections from the server. This is different from read receipts (type="read"), which you send manually with mark_as_read().Wire format
Internally, delivery receipts pass JID references directly to the.attr() method, avoiding allocations on the hot path:
v0.6 split the
to attribute by addressing case. Earlier versions always used info.source.chat, which strips the device byte (to_non_ad). For multi-device LID senders that arrived with from="USER:DEV@lid", the device-less receipt was rejected by the LID server: it replayed the stanza from the offline queue and eventually closed the stream with <stream:error><ack class="message"/></stream:error>. Matching whatsmeow’s buildBaseReceipt (which echoes node.Attrs["from"] verbatim) and WA Web’s sendDeliveryReceiptsAfterDecryption resolves the issue.mark_as_read) batch multiple message IDs using a <list> child node with <item> elements:
Receipt Types
WhatsApp supports multiple receipt types:Delivery receipt (type=
""). Confirms message was delivered to the recipient’s device. Sent automatically by the library.Read receipt (type=
"read"). Confirms message was read by the recipient. Sent manually via mark_as_read().Read receipt from your own device (type=
"read-self"). Received when you read a message on another device.Played receipt (type=
"played"). Confirms media (audio/video) was played by the recipient.Played receipt from your own device (type=
"played-self"). Received when you play media on another device.Retry receipt (type=
"retry"). Recipient failed to decrypt the message and is requesting a retry. Automatically handled by the library.VoIP call encryption re-keying retry receipt (type=
"enc_rekey_retry"). Sent when a peer fails to decrypt VoIP call encryption data and needs the sender to re-key. Uses an <enc_rekey> child element (with call-creator, call-id, count attributes) instead of the standard <retry> child. Automatically handled by the library.Sender receipt (type=
"sender"). Acknowledges message was sent.Server error receipt (type=
"server-error"). Message delivery failed on server.Receipt Events
You can listen for receipt events to track message delivery and read status using the Bot event handler:Receipt event structure
Source information:
chat- Chat JID where the receipt originatedsender- JID of the user who sent the receiptis_group- Whether this is from a group
true when the receipt carried the offline attribute. That means it was drained from the server’s offline queue on reconnect rather than delivered live. Use it to tell a backlog of receipts received at login apart from real-time ones.List of message IDs this receipt applies to. Usually contains a single ID, but can have multiple.
When the receipt was received (local time)
Type of receipt (Delivered, Read, Played, etc.)
Message tracking example
Track message delivery and read status:Played receipts (media)
For voice notes and video notes, send played receipts withmark_as_played once the user has played the media. Newsletters send played-self; everything else sends played. The wire shape mirrors read receipts:
Event::Receipt event with ReceiptType::Played or ReceiptType::PlayedSelf.