Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Event System

The Event enum

All real-time notifications are modeled as variants of a single Event enum defined in src/core_layer/types.rs. Every event flows through the broadcast channel from the iMessage layer to all consumers (webhook dispatcher and WebSocket clients).

#![allow(unused)]
fn main() {
pub enum Event {
    MessageReceived(Message),
    MessageSent(Message),
    ReactionAdded(Reaction),
    ReactionRemoved(Reaction),
}
}

When serialized for delivery (webhook payloads, WebSocket frames), events use a type string field:

Enum varianttype string
MessageReceived"message.received"
MessageSent"message.sent"
ReactionAdded"reaction.added"
ReactionRemoved"reaction.removed"

Event types

message.received

Fired when an incoming message (not sent by the local account) is detected in chat.db.

message.sent

Fired when an outgoing message appears in chat.db. This happens after Messages.app confirms the send — typically within a second of the send_message API call completing.

reaction.added

Fired when a Tapback reaction is added to any message in a conversation. The data payload includes the reaction type and the GUID of the message being reacted to.

reaction.removed

Fired when a previously added Tapback reaction is removed.


How reactions are stored in chat.db

Reactions are not stored as a separate table in chat.db. They appear as ordinary message rows with special values in the associated_message_type and associated_message_guid columns.

associated_message_type mapping

Value rangeMeaning
2000Heart (love) — added
2001Thumbs up — added
2002Thumbs down — added
2003Ha ha — added
2004Exclamation — added
2005Question mark — added
3000Heart (love) — removed
3001Thumbs up — removed
3002Thumbs down — removed
3003Ha ha — removed
3004Exclamation — removed
3005Question mark — removed

Values in the 2000–2005 range indicate a reaction being added; values in 3000–3005 indicate removal. The associated_message_guid column holds the GUID of the message that was reacted to.

AiMessage’s poller inspects associated_message_type on every new message row. Rows with a non-zero value in this column are classified as reactions and published as ReactionAdded or ReactionRemoved events rather than message events.