Skip to main content

Documentation Index

Fetch the complete documentation index at: https://whatsapp-rust.jlucaso.com/llms.txt

Use this file to discover all available pages before exploring further.

The ChatActions feature provides methods for managing chat organization through archiving, pinning, muting, starring messages, marking chats as read, deleting chats, and deleting individual messages. These operations sync across all your devices via WhatsApp’s app state sync mechanism.

Access

Access chat action operations through the client:
let chat_actions = client.chat_actions();

Archive

archive_chat

Archive a chat to hide it from the main chat list.
pub async fn archive_chat(
    &self,
    jid: &Jid,
    message_range: Option<SyncActionMessageRange>,
) -> Result<()>
Parameters:
  • jid - The chat JID to archive
  • message_range - Optional message range for multi-device conflict resolution. Pass None in most cases
Example:
let jid: Jid = "15551234567@s.whatsapp.net".parse()?;
client.chat_actions().archive_chat(&jid, None).await?;

unarchive_chat

Unarchive a chat to show it in the main chat list.
pub async fn unarchive_chat(
    &self,
    jid: &Jid,
    message_range: Option<SyncActionMessageRange>,
) -> Result<()>
Parameters:
  • jid - The chat JID to unarchive
  • message_range - Optional message range for multi-device conflict resolution. Pass None in most cases
Example:
client.chat_actions().unarchive_chat(&jid, None).await?;

Pin

pin_chat

Pin a chat to keep it at the top of the chat list.
pub async fn pin_chat(&self, jid: &Jid) -> Result<()>
Parameters:
  • jid - The chat JID to pin
Example:
let jid: Jid = "15551234567@s.whatsapp.net".parse()?;
client.chat_actions().pin_chat(&jid).await?;
WhatsApp limits the number of pinned chats. Attempting to pin too many chats may fail.

unpin_chat

Unpin a chat.
pub async fn unpin_chat(&self, jid: &Jid) -> Result<()>
Parameters:
  • jid - The chat JID to unpin
Example:
client.chat_actions().unpin_chat(&jid).await?;

Mute

mute_chat

Mute a chat indefinitely.
pub async fn mute_chat(&self, jid: &Jid) -> Result<()>
Parameters:
  • jid - The chat JID to mute
Example:
let jid: Jid = "15551234567@s.whatsapp.net".parse()?;
client.chat_actions().mute_chat(&jid).await?;

mute_chat_until

Mute a chat until a specific time.
pub async fn mute_chat_until(
    &self,
    jid: &Jid,
    mute_end_timestamp_ms: i64
) -> Result<()>
Parameters:
  • jid - The chat JID to mute
  • mute_end_timestamp_ms - Unix timestamp in milliseconds when mute expires (must be in the future)
Example:
use chrono::{Utc, Duration};

let jid: Jid = "15551234567@s.whatsapp.net".parse()?;

// Mute for 8 hours
let mute_until = Utc::now() + Duration::hours(8);
client.chat_actions()
    .mute_chat_until(&jid, mute_until.timestamp_millis())
    .await?;

// Mute for 1 week
let mute_until = Utc::now() + Duration::weeks(1);
client.chat_actions()
    .mute_chat_until(&jid, mute_until.timestamp_millis())
    .await?;

unmute_chat

Unmute a chat.
pub async fn unmute_chat(&self, jid: &Jid) -> Result<()>
Parameters:
  • jid - The chat JID to unmute
Example:
client.chat_actions().unmute_chat(&jid).await?;

Star messages

star_message

Star a message to mark it as important.
pub async fn star_message(
    &self,
    chat_jid: &Jid,
    participant_jid: Option<&Jid>,
    message_id: &str,
    from_me: bool
) -> Result<()>
Parameters:
  • chat_jid - The chat containing the message
  • participant_jid - For group messages from others, pass Some(&sender_jid). For 1-on-1 chats or your own messages, pass None
  • message_id - The message ID to star
  • from_me - Whether the message was sent by you
Example:
// Star your own message in a 1-on-1 chat
client.chat_actions()
    .star_message(&chat_jid, None, "MESSAGE_ID", true)
    .await?;

// Star someone else's message in a 1-on-1 chat
client.chat_actions()
    .star_message(&chat_jid, None, "MESSAGE_ID", false)
    .await?;

// Star someone else's message in a group
let sender_jid: Jid = "15559876543@s.whatsapp.net".parse()?;
client.chat_actions()
    .star_message(&group_jid, Some(&sender_jid), "MESSAGE_ID", false)
    .await?;
For group messages not sent by you, participant_jid is required. The method will return an error if it’s not provided.

unstar_message

Remove the star from a message.
pub async fn unstar_message(
    &self,
    chat_jid: &Jid,
    participant_jid: Option<&Jid>,
    message_id: &str,
    from_me: bool
) -> Result<()>
Parameters: Same as star_message. Example:
client.chat_actions()
    .unstar_message(&chat_jid, None, "MESSAGE_ID", true)
    .await?;

Mark chat as read

mark_chat_as_read

Mark a chat as read or unread. This is distinct from mark_as_read (IQ receipts) — it syncs the read/unread state across all linked devices.
pub async fn mark_chat_as_read(
    &self,
    jid: &Jid,
    read: bool,
    message_range: Option<SyncActionMessageRange>,
) -> Result<()>
Parameters:
  • jid - The chat JID to mark
  • read - true to mark as read, false to mark as unread
  • message_range - Optional message range for multi-device conflict resolution. Pass None in most cases
Example:
let jid: Jid = "15551234567@s.whatsapp.net".parse()?;

// Mark chat as read
client.chat_actions().mark_chat_as_read(&jid, true, None).await?;

// Mark chat as unread
client.chat_actions().mark_chat_as_read(&jid, false, None).await?;
This syncs the read/unread badge across linked devices via app state sync (regular_low collection). To send read receipts to the sender, use client.mark_as_read() instead.

Delete chat

delete_chat

Delete a chat from the chat list across all linked devices.
pub async fn delete_chat(
    &self,
    jid: &Jid,
    delete_media: bool,
    message_range: Option<SyncActionMessageRange>,
) -> Result<()>
Parameters:
  • jid - The chat JID to delete
  • delete_media - Whether to also delete downloaded media files
  • message_range - Optional message range for multi-device conflict resolution. Pass None in most cases
Example:
let jid: Jid = "15551234567@s.whatsapp.net".parse()?;

// Delete chat and its media
client.chat_actions().delete_chat(&jid, true, None).await?;

// Delete chat but keep media files
client.chat_actions().delete_chat(&jid, false, None).await?;
This operation is not reversible. The chat and optionally its media will be removed from all linked devices.

Delete message for me

delete_message_for_me

Delete a specific message locally (not for the other party). This is different from revoke_message which deletes for everyone.
pub async fn delete_message_for_me(
    &self,
    chat_jid: &Jid,
    participant_jid: Option<&Jid>,
    message_id: &str,
    from_me: bool,
    delete_media: bool,
    message_timestamp: Option<i64>,
) -> Result<()>
Parameters:
  • chat_jid - The chat containing the message
  • participant_jid - For group messages from others, pass Some(&sender_jid). For 1-on-1 chats or your own messages, pass None
  • message_id - The ID of the message to delete
  • from_me - Whether the message was sent by you
  • delete_media - Whether to also delete the associated media file
  • message_timestamp - Optional timestamp of the message
Example:
// Delete your own message in a 1-on-1 chat
client.chat_actions()
    .delete_message_for_me(&chat_jid, None, "MESSAGE_ID", true, true, None)
    .await?;

// Delete someone else's message in a group
let sender_jid: Jid = "15559876543@s.whatsapp.net".parse()?;
client.chat_actions()
    .delete_message_for_me(&group_jid, Some(&sender_jid), "MESSAGE_ID", false, true, None)
    .await?;
For group messages not sent by you, participant_jid is required. The method will return an error if it’s not provided.
This only removes the message from your own devices. The other party can still see the message. To delete for everyone, use client.revoke_message() instead.

Helper functions

message_range

Construct a SyncActionMessageRange for multi-device conflict resolution. In most cases you can pass None instead — only WhatsApp Web with a full message database populates this.
pub fn message_range(
    last_message_timestamp: i64,
    last_system_message_timestamp: Option<i64>,
    messages: Vec<(wa::MessageKey, i64)>,
) -> SyncActionMessageRange

message_key

Construct a MessageKey for use with message_range.
pub fn message_key(
    id: impl Into<String>,
    remote_jid: &Jid,
    from_me: bool,
    participant: Option<&Jid>,
) -> wa::MessageKey

App state sync

All chat actions are synced across devices using WhatsApp’s app state synchronization:
ActionCollection
Archiveregular_low
Pinregular_low
Mark chat as readregular_low
Muteregular_high
Starregular_high
Delete chatregular_high
Delete message for meregular_high
App state sync requires encryption keys to be available. These are typically obtained during initial sync after authentication. Actions may fail if called immediately after pairing before sync completes.

Events

Chat action changes are emitted as events that you can handle:
use wacore::types::events::Event;

.on_event(|event, _client| async move {
    match &*event {
        Event::MuteUpdate(update) => {
            println!("Chat {} muted: {:?}", update.jid, update.action.muted);
        }
        Event::PinUpdate(update) => {
            println!("Chat {} pinned: {:?}", update.jid, update.action.pinned);
        }
        Event::ArchiveUpdate(update) => {
            println!("Chat {} archived: {:?}", update.jid, update.action.archived);
        }
        Event::StarUpdate(update) => {
            println!("Message {} starred: {:?}", update.message_id, update.action.starred);
        }
        Event::MarkChatAsReadUpdate(update) => {
            println!("Chat {} marked as read: {:?}", update.jid, update.action.read);
        }
        Event::DeleteChatUpdate(update) => {
            println!("Chat {} deleted (media: {})", update.jid, update.delete_media);
        }
        Event::DeleteMessageForMeUpdate(update) => {
            println!("Message {} in {} deleted for me", update.message_id, update.chat_jid);
        }
        _ => {}
    }
})

Error handling

All methods return Result<(), anyhow::Error>. Common errors:
  • No app state sync key available (sync not complete)
  • Invalid timestamp for mute_chat_until
  • Missing participant_jid for group star/delete operations
  • Network errors
match client.chat_actions().mute_chat_until(&jid, 0).await {
    Ok(_) => println!("Muted"),
    Err(e) => eprintln!("Failed: {}", e), // Timestamp validation error
}

Complete example

use whatsapp_rust::Client;
use wacore_binary::jid::Jid;
use chrono::{Utc, Duration};
use std::sync::Arc;

async fn organize_chats(client: &Arc<Client>) -> anyhow::Result<()> {
    let important_chat: Jid = "15551234567@s.whatsapp.net".parse()?;
    let noisy_group: Jid = "123456789@g.us".parse()?;
    let old_chat: Jid = "15559876543@s.whatsapp.net".parse()?;
    
    // Pin important conversations
    client.chat_actions().pin_chat(&important_chat).await?;
    
    // Mute noisy group for 1 week
    let mute_until = Utc::now() + Duration::weeks(1);
    client.chat_actions()
        .mute_chat_until(&noisy_group, mute_until.timestamp_millis())
        .await?;
    
    // Archive old conversations
    client.chat_actions().archive_chat(&old_chat, None).await?;
    
    // Star an important message
    client.chat_actions()
        .star_message(&important_chat, None, "IMPORTANT_MSG_ID", false)
        .await?;
    
    // Mark chat as read across all devices
    client.chat_actions()
        .mark_chat_as_read(&important_chat, true, None)
        .await?;
    
    // Delete a message locally (not for everyone)
    client.chat_actions()
        .delete_message_for_me(&old_chat, None, "OLD_MSG_ID", false, true, None)
        .await?;
    
    // Delete an old chat and its media
    client.chat_actions().delete_chat(&old_chat, true, None).await?;
    
    Ok(())
}

See also

  • Events - Handle chat action update events
  • Groups - Group management operations
  • Client - Core client API