Documentation
¶
Index ¶
- Constants
- Variables
- func ClearSession()
- func DescribeCapture(rec CaptureRecord) string
- func KnownEvents() []string
- func NewHTTPHandler(service *Service) http.Handler
- func NormalizePhone(input string) string
- type ActionResult
- type AmbiguousReferenceError
- type AppLogRecord
- type AudioRequest
- type AutoReplyRule
- type BulkSendItem
- type BulkSendResult
- type CallInfo
- type CallStatusInfo
- type CaptureRecord
- type ChatRecord
- type ContactRecord
- type ContactUpdate
- type GroupParticipant
- type GroupSummary
- type MessageRecord
- type MessageSearchOptions
- type OnWhatsAppResult
- type PlaceCallOptions
- type QueueStatus
- type ReceiptRecord
- type ResolveOptions
- type ResolvedTarget
- type Service
- func (s *Service) AnswerWithAudio(ref string, req AudioRequest) (string, error)
- func (s *Service) BulkSend(ctx context.Context, items []BulkSendItem, interval time.Duration) ([]BulkSendResult, error)
- func (s *Service) CallQueueStatus() QueueStatus
- func (s *Service) CallStatus(ref string) (CallStatusInfo, error)
- func (s *Service) CheckOnWhatsApp(ctx context.Context, phones []string) ([]OnWhatsAppResult, error)
- func (s *Service) Client() *whatsmeow.Client
- func (s *Service) Close() error
- func (s *Service) Connect() error
- func (s *Service) CreateGroup(ctx context.Context, name string, participantRefs []string) (GroupSummary, error)
- func (s *Service) CurrentUserJID() string
- func (s *Service) CurrentUserLID() string
- func (s *Service) Disconnect()
- func (s *Service) DownloadMedia(ctx context.Context, messageID, chatJID string) (string, error)
- func (s *Service) EditMessage(ctx context.Context, chatRef, messageID, newText string) (MessageRecord, error)
- func (s *Service) EndCall(ctx context.Context, ref, reason string) (CallInfo, error)
- func (s *Service) GroupInfo(ctx context.Context, ref string) (GroupSummary, error)
- func (s *Service) GroupInfoFromLink(ctx context.Context, link string) (GroupSummary, error)
- func (s *Service) GroupInviteLink(ctx context.Context, ref string, reset bool) (string, error)
- func (s *Service) HangupMedia(callID string) error
- func (s *Service) HistoryMarker() int
- func (s *Service) IsConnected() bool
- func (s *Service) JoinGroupWithLink(ctx context.Context, link string) (GroupSummary, error)
- func (s *Service) LatestRingingCall() (CallInfo, bool)
- func (s *Service) LeaveGroup(ctx context.Context, ref string) error
- func (s *Service) ListCalls(activeOnly bool) []CallInfo
- func (s *Service) ListGroups(ctx context.Context) ([]GroupSummary, error)
- func (s *Service) MarkChatRead(ctx context.Context, chatRef string) error
- func (s *Service) MessageReceipts(messageID string) ([]ReceiptRecord, error)
- func (s *Service) PlaceCall(ctx context.Context, recipient string, opts PlaceCallOptions) (CallInfo, error)
- func (s *Service) ReactToMessage(ctx context.Context, chatRef, messageID, emoji string) error
- func (s *Service) RefreshMissingChatNames(ctx context.Context, limit int) error
- func (s *Service) RejectIncomingCall(ctx context.Context, ref string) (CallInfo, error)
- func (s *Service) ReplayDelivery(deliveryID int64) (WebhookDeliveryRecord, error)
- func (s *Service) RequestHistorySync(ctx context.Context, count int) error
- func (s *Service) ResolveBestTarget(ref, kind string, allowDirect bool) (ResolvedTarget, error)
- func (s *Service) ResolveTargets(ref, kind string, limit int, allowDirect bool) ([]ResolvedTarget, error)
- func (s *Service) RevokeMessage(ctx context.Context, chatRef, messageID string) error
- func (s *Service) RunTriggers(event string, chat ChatRecord, message MessageRecord, dryRun bool) []TriggerResult
- func (s *Service) SearchMessages(chatRef, senderRef, query string, limit int, mediaOnly bool, fromMe string) ([]MessageRecord, *ResolvedTarget, *ResolvedTarget, error)
- func (s *Service) SearchMessagesAdvanced(chatRef, senderRef, query string, limit int, mediaOnly bool, fromMe string, ...) ([]MessageRecord, *ResolvedTarget, *ResolvedTarget, error)
- func (s *Service) SendMessage(ctx context.Context, recipient, text, mediaPath string) (MessageRecord, error)
- func (s *Service) SendMessageReplying(ctx context.Context, recipient, text, mediaPath, replyToID string) (MessageRecord, error)
- func (s *Service) SendStory(ctx context.Context, text, mediaPath string) error
- func (s *Service) SetGroupName(ctx context.Context, ref, name string) error
- func (s *Service) SetGroupTopic(ctx context.Context, ref, topic string) error
- func (s *Service) SetPresence(ctx context.Context, available bool) error
- func (s *Service) SetTyping(ctx context.Context, chatRef string, typing bool, recording bool) error
- func (s *Service) StartCallCapture() error
- func (s *Service) StartConnectionWatchdog()
- func (s *Service) StopCallCapture() error
- func (s *Service) Store() *Store
- func (s *Service) SyncContacts(ctx context.Context) error
- func (s *Service) TestTrigger(id int64, chatRef, text string) (TriggerResult, error)
- func (s *Service) TestWebhook(webhookID int64) (WebhookDeliveryRecord, error)
- func (s *Service) UpdateGroupParticipants(ctx context.Context, ref, action string, participantRefs []string) ([]GroupParticipant, error)
- func (s *Service) WaitForBootstrapSync(maxWait, quietPeriod time.Duration) bool
- func (s *Service) WaitForHistoryQuiet(marker int, maxWait, quietPeriod time.Duration) bool
- type StatusSnapshot
- type Store
- func (s *Store) AddAppLog(level, category, message string, details any) error
- func (s *Store) AddAutoReply(rule AutoReplyRule) (AutoReplyRule, error)
- func (s *Store) AddWebhook(record WebhookRecord) (WebhookRecord, error)
- func (s *Store) BuildStatus(connected bool, userJID string) (StatusSnapshot, error)
- func (s *Store) Close() error
- func (s *Store) ConfigureInitialAccess(unlockedJIDs []string) error
- func (s *Store) CreateTrigger(t Trigger) (Trigger, error)
- func (s *Store) DeleteAutoReply(id int64) error
- func (s *Store) DeleteTrigger(id int64) error
- func (s *Store) DeleteWebhook(id int64) error
- func (s *Store) EnsureChat(jid, name string, isGroup bool, messageTime time.Time, preview string, ...) (ChatRecord, error)
- func (s *Store) FinishWebhookDelivery(id int64, status string, httpStatus int, lastError, responseBody string) error
- func (s *Store) FinishWebhookDeliveryAttempt(id int64, status string, httpStatus int, lastError, responseBody string, ...) error
- func (s *Store) GetBoolSetting(key string, defaultValue bool) (bool, error)
- func (s *Store) GetChat(jid string) (ChatRecord, error)
- func (s *Store) GetContact(jid string) (ContactRecord, error)
- func (s *Store) GetDNDMode() (bool, error)
- func (s *Store) GetMessage(messageID, chatJID string) (MessageRecord, error)
- func (s *Store) GetTrigger(id int64) (Trigger, error)
- func (s *Store) GetWebhook(id int64) (WebhookRecord, error)
- func (s *Store) GetWebhookDelivery(id int64) (WebhookDeliveryRecord, error)
- func (s *Store) InitialAccessConfigured() (bool, error)
- func (s *Store) JIDForNumber(number, preferChatJID string) string
- func (s *Store) LastHistorySync() (*time.Time, error)
- func (s *Store) LatestMessage() (MessageRecord, error)
- func (s *Store) ListAppLogs(limit int, level, category, query string) ([]AppLogRecord, error)
- func (s *Store) ListAutoReplies() ([]AutoReplyRule, error)
- func (s *Store) ListChats(filter string, limit int, query string) ([]ChatRecord, error)
- func (s *Store) ListContacts(limit int, query string) ([]ContactRecord, error)
- func (s *Store) ListMessages(chatJID string, limit int) ([]MessageRecord, error)
- func (s *Store) ListReceipts(messageID string) ([]ReceiptRecord, error)
- func (s *Store) ListTriggers() ([]Trigger, error)
- func (s *Store) ListWebhookDeliveries(limit int, status, event, query string) ([]WebhookDeliveryRecord, error)
- func (s *Store) ListWebhooks() ([]WebhookRecord, error)
- func (s *Store) MarkMessageDeleted(messageID, chatJID string) error
- func (s *Store) RecordWebhookRetry(id int64, attempts int, lastError string, httpStatus int, nextRetry time.Time) error
- func (s *Store) SearchMessages(opts MessageSearchOptions) ([]MessageRecord, error)
- func (s *Store) SetBoolSetting(key string, value bool) error
- func (s *Store) SetChatLocked(jid string, locked bool) error
- func (s *Store) SetDNDMode(enabled bool) error
- func (s *Store) SetInitialAccessConfigured(enabled bool) error
- func (s *Store) SetLastHistorySync(ts time.Time) error
- func (s *Store) SetTriggerEnabled(id int64, enabled bool) (Trigger, error)
- func (s *Store) StartWebhookDelivery(webhookID int64, url, event, chatJID, messageID, requestBody string) (int64, error)
- func (s *Store) StoreMessage(record MessageRecord) error
- func (s *Store) StoreReceipt(rec ReceiptRecord) error
- func (s *Store) UpdateMessageContent(messageID, chatJID, content string) error
- func (s *Store) UpdateMessageMediaPath(messageID, chatJID, mediaPath string) error
- func (s *Store) UpdateTrigger(t Trigger) (Trigger, error)
- func (s *Store) UpsertContact(record ContactRecord) error
- func (s *Store) UpsertContactMemory(jid string, update ContactUpdate) (ContactRecord, error)
- type Trigger
- type TriggerAction
- type TriggerResult
- type WebhookDeliveryRecord
- type WebhookRecord
Constants ¶
const ( // CallStateQueued is a call that has been asked for but not yet dialled, because another call // holds the single call slot. See callqueue.go. CallStateQueued = "queued" CallStateRinging = "ringing" CallStateAccepted = "accepted" CallStateRejected = "rejected" CallStateEnded = "ended" CallStateFailed = "failed" CallDirectionOut = "outgoing" CallDirectionIn = "incoming" )
Call state machine. Calls only ever move forward through these states.
const ( MatchAlways = "always" MatchContains = "contains" MatchExact = "exact" MatchPrefix = "prefix" MatchSuffix = "suffix" MatchRegex = "regex" )
Trigger match types.
const ( ScopeAll = "all" ScopeDMs = "dms" ScopeGroups = "groups" ScopeList = "list" )
Trigger chat scopes.
const ( ActionSendText = "send_text" ActionSendMedia = "send_media" ActionReact = "react" ActionMarkRead = "mark_read" ActionWebhook = "webhook" ActionForward = "forward" )
Trigger action types.
const ( EventIncomingMessage = "incoming_message" EventOutgoingMessage = "outgoing_message" EventCallIncoming = "call.incoming" EventCallPlaced = "call.placed" EventCallAccepted = "call.accepted" EventCallEnded = "call.ended" EventCallRejected = "call.rejected" EventConnectionState = "connection_state" EventSyncComplete = "sync_complete" EventTriggerFired = "trigger_fired" )
Event kinds a trigger can select. These are the same strings webhooks are subscribed to, so a trigger and a webhook can react to exactly the same things.
Variables ¶
var ( DataDir string MediaDir string CapturePath string SessionDBPath string AppDBPath string QRPath string HTTPAddr string // InitErr reports a failure to prepare the data directory. A library must not exit the process, // so init records the problem and OpenStore/NewService refuse to start with it. InitErr error )
Paths and settings for this wacli instance, resolved once from the environment.
WACLI_HOME lets several independent instances share one OS user, each with its own WhatsApp session, database and media; pair it with WACLI_HTTP_ADDR so each daemon binds its own port.
Functions ¶
func ClearSession ¶
func ClearSession()
func DescribeCapture ¶
func DescribeCapture(rec CaptureRecord) string
DescribeCapture renders one captured stanza as an indented tree, with binary content shown as hex plus an ASCII gloss. This is the view you want when working out what an unknown node means: it makes no assumptions about the protocol and hides nothing.
func KnownEvents ¶
func KnownEvents() []string
KnownEvents lists every event kind wacli emits, for validation and for tooling that wants to present the choices.
func NewHTTPHandler ¶
func NormalizePhone ¶
Types ¶
type ActionResult ¶
type ActionResult struct {
Type string `json:"type"`
OK bool `json:"ok"`
Detail string `json:"detail,omitempty"`
Error string `json:"error,omitempty"`
}
ActionResult reports one action's outcome.
type AmbiguousReferenceError ¶
type AmbiguousReferenceError struct {
Reference string
Candidates []ResolvedTarget
}
func (*AmbiguousReferenceError) Error ¶
func (e *AmbiguousReferenceError) Error() string
type AppLogRecord ¶
type AudioRequest ¶
type AudioRequest struct {
// Say is spoken with the system speech synthesiser.
Say string
// Voice picks the synthesiser voice; empty means the system default.
Voice string
// File is a .wav/.mp3/.opus to play instead of Say.
File string
// Repeat restarts the audio when it finishes instead of hanging up.
Repeat bool
// Record is a path to write the other party's voice to, as a 16 kHz mono WAV.
Record string
}
AudioRequest describes a call's audio in both directions. Say and File are mutually exclusive.
type AutoReplyRule ¶
type AutoReplyRule struct {
ID int64 `json:"id"`
Name string `json:"name"`
MatchType string `json:"match_type"`
Pattern string `json:"pattern,omitempty"`
ReplyText string `json:"reply_text,omitempty"`
MediaPath string `json:"media_path,omitempty"`
Enabled bool `json:"enabled"`
ApplyToDMs bool `json:"apply_to_dms"`
ApplyToGroups bool `json:"apply_to_groups"`
Priority int `json:"priority"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type BulkSendItem ¶
type BulkSendResult ¶
type BulkSendResult struct {
To string `json:"to"`
Resolved ResolvedTarget `json:"resolved,omitempty"`
Success bool `json:"success"`
Error string `json:"error,omitempty"`
Message MessageRecord `json:"message,omitempty"`
}
type CallInfo ¶
type CallInfo struct {
// ShortID is a compact handle for this call — "c1", "c2", and so on — assigned when the call
// enters the registry. WhatsApp's own call IDs are 22-character hex strings, which are awkward to
// read back and easy to mistype or truncate; every command that takes a call accepts this
// instead. It is unique for the lifetime of the daemon, which is also the lifetime of the
// registry: calls are not persisted, so a restart starts again from c1.
ShortID string `json:"short_id"`
CallID string `json:"call_id"`
PeerJID string `json:"peer_jid"`
PeerName string `json:"peer_name,omitempty"`
Direction string `json:"direction"`
State string `json:"state"`
Video bool `json:"video"`
StartedAt time.Time `json:"started_at"`
EndedAt time.Time `json:"ended_at,omitempty"`
Reason string `json:"reason,omitempty"`
// RecordPath is the absolute path the other party's voice is being written to, set when the call
// was placed or answered with --record. Empty means recording was never asked for.
RecordPath string `json:"record_path,omitempty"`
// RecordedSeconds is how much inbound audio was actually captured, filled in when the call ends.
// Zero on a finished call that had a RecordPath means no inbound audio ever arrived.
RecordedSeconds float64 `json:"recorded_seconds"`
// CallKey is the hex-encoded e2e media master key. Decrypting it out of the offer is not
// something upstream whatsmeow does, and the media stack keeps its own key material, so nothing
// populates this today; it is kept so the field does not vanish from the API.
CallKey string `json:"call_key,omitempty"`
// contains filtered or unexported fields
}
CallInfo is a single call, incoming or outgoing.
type CallStatusInfo ¶
type CallStatusInfo struct {
CallInfo
// MediaLive reports whether the media stack still holds this call open.
MediaLive bool `json:"media_live"`
// DurationSeconds counts from the call starting, to now or to when it ended.
DurationSeconds int `json:"duration_seconds"`
}
CallStatusInfo is a call plus the live media state the registry alone cannot report.
type CaptureRecord ¶
type CaptureRecord struct {
At time.Time `json:"at"`
Direction string `json:"direction"` // "recv" or "send"
Node json.RawMessage `json:"node"`
XML string `json:"xml"`
}
CaptureRecord is one captured call stanza.
func LoadCaptures ¶
func LoadCaptures(path string) ([]CaptureRecord, error)
LoadCaptures reads the capture file. Records that fail to parse are skipped.
type ChatRecord ¶
type ContactRecord ¶
type ContactRecord struct {
JID string `json:"jid"`
Phone string `json:"phone"`
FullName string `json:"full_name"`
FirstName string `json:"first_name"`
PushName string `json:"push_name"`
BusinessName string `json:"business_name"`
Found bool `json:"found"`
Bio string `json:"bio,omitempty"`
Notes string `json:"notes,omitempty"`
Memory string `json:"memory,omitempty"`
MetadataJSON string `json:"metadata_json,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
type ContactUpdate ¶
type GroupParticipant ¶ added in v0.3.0
type GroupParticipant struct {
JID string `json:"jid"`
IsAdmin bool `json:"is_admin"`
IsSuperAdmin bool `json:"is_super_admin"`
}
GroupParticipant is one member and what they may do.
type GroupSummary ¶ added in v0.3.0
type GroupSummary struct {
JID string `json:"jid"`
Name string `json:"name"`
Topic string `json:"topic,omitempty"`
Owner string `json:"owner,omitempty"`
Created string `json:"created,omitempty"`
IsAnnounce bool `json:"is_announce"`
IsLocked bool `json:"is_locked"`
Participants []GroupParticipant `json:"participants,omitempty"`
}
GroupSummary is a group as wacli reports it. It is whatsmeow's GroupInfo flattened to the fields a caller acts on, so the JSON stays stable if the protocol struct grows.
type MessageRecord ¶
type MessageRecord struct {
ID string `json:"id"`
ChatJID string `json:"chat_jid"`
SenderJID string `json:"sender_jid"`
Content string `json:"content"`
Timestamp time.Time `json:"timestamp"`
IsFromMe bool `json:"is_from_me"`
MessageType string `json:"message_type"`
// MentionsMe = this message @-mentions THIS account (the bot). QuotedIsFromMe
// = it is a reply/quote to a message THIS account sent. Both let a consumer
// (e.g. KARMAX) tell that the bot is being directly addressed — generically,
// from the account's own identity, with no hardcoded numbers.
MentionsMe bool `json:"mentions_me,omitempty"`
QuotedIsFromMe bool `json:"quoted_is_from_me,omitempty"`
// MentionCount is how many JIDs this message @-mentioned in total, so a
// consumer can tell a direct mention from an "@all"-style mass mention.
// wacli deliberately doesn't judge that itself — that policy lives in the
// consumer (e.g. the KARMAX wa-monitor loop).
MentionCount int `json:"mention_count,omitempty"`
MediaType string `json:"media_type,omitempty"`
MimeType string `json:"mime_type,omitempty"`
FileName string `json:"file_name,omitempty"`
MediaPath string `json:"media_path,omitempty"`
URL string `json:"url,omitempty"`
DirectPath string `json:"direct_path,omitempty"`
FileLength uint64 `json:"file_length,omitempty"`
MediaKey []byte `json:"-"`
FileSHA256 []byte `json:"-"`
FileEncSHA256 []byte `json:"-"`
}
type MessageSearchOptions ¶
type OnWhatsAppResult ¶ added in v0.3.0
type OnWhatsAppResult struct {
Query string `json:"query"`
JID string `json:"jid,omitempty"`
IsRegistered bool `json:"is_registered"`
VerifiedName string `json:"verified_name,omitempty"`
}
OnWhatsAppResult reports whether a number has WhatsApp.
type PlaceCallOptions ¶
type PlaceCallOptions struct {
// Video places a video call instead of a voice call.
Video bool
// RingFor is how long to keep ringing before hanging up automatically. Zero means 45s.
// A negative value disables the timeout, leaving the call up until EndCall is called.
RingFor time.Duration
// Audio is played into the call once the peer answers and media comes up.
Audio AudioRequest
}
PlaceCallOptions are the knobs for PlaceCall.
type QueueStatus ¶
type QueueStatus struct {
ActiveCallID string `json:"active_call_id,omitempty"`
Busy bool `json:"busy"`
Waiting []string `json:"waiting"`
}
QueueStatus describes the call slot and everything waiting on it.
type ReceiptRecord ¶
type ReceiptRecord struct {
MessageID string `json:"message_id"`
ChatJID string `json:"chat_jid"`
RecipientJID string `json:"recipient_jid"`
Type string `json:"type"`
Timestamp time.Time `json:"timestamp"`
}
ReceiptRecord is a delivery/read receipt for a message from one recipient.
type ResolveOptions ¶
type ResolvedTarget ¶
type ResolvedTarget struct {
Input string `json:"input"`
JID string `json:"jid"`
Name string `json:"name"`
Phone string `json:"phone,omitempty"`
IsGroup bool `json:"is_group"`
Locked bool `json:"locked"`
ExistsInChats bool `json:"exists_in_chats"`
ExistsInContacts bool `json:"exists_in_contacts"`
MatchType string `json:"match_type"`
Score int `json:"score"`
Chat *ChatRecord `json:"chat,omitempty"`
Contact *ContactRecord `json:"contact,omitempty"`
}
func ResolveBestTarget ¶
func ResolveBestTarget(store *Store, ref string, opts ResolveOptions) (ResolvedTarget, error)
func ResolveTargets ¶
func ResolveTargets(store *Store, ref string, opts ResolveOptions) ([]ResolvedTarget, error)
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func (*Service) AnswerWithAudio ¶
func (s *Service) AnswerWithAudio(ref string, req AudioRequest) (string, error)
AnswerWithAudio accepts a ringing call and speaks into it.
func (*Service) BulkSend ¶
func (s *Service) BulkSend(ctx context.Context, items []BulkSendItem, interval time.Duration) ([]BulkSendResult, error)
func (*Service) CallQueueStatus ¶
func (s *Service) CallQueueStatus() QueueStatus
CallQueueStatus reports the current slot and queue.
func (*Service) CallStatus ¶
func (s *Service) CallStatus(ref string) (CallStatusInfo, error)
CallStatus reports one call by short handle, full ID, or unique prefix.
It reads through to the media layer as well as the registry: the registry knows the signalling state, but only meowcaller knows whether the call is still carrying media, and the two can disagree — a call the peer has torn down stays "accepted" in the registry until the terminate stanza lands.
func (*Service) CheckOnWhatsApp ¶ added in v0.3.0
CheckOnWhatsApp reports which of the given phone numbers are reachable on WhatsApp.
Worth calling before a bulk send: sending to a number with no account fails per-message, and the answer is cheap to get for the whole list at once.
func (*Service) Client ¶
Client exposes the underlying whatsmeow client for callers that need to drive login or reach a protocol feature wacli does not wrap.
func (*Service) CreateGroup ¶ added in v0.3.0
func (s *Service) CreateGroup(ctx context.Context, name string, participantRefs []string) (GroupSummary, error)
CreateGroup creates a group with the given members.
func (*Service) CurrentUserJID ¶
func (*Service) CurrentUserLID ¶
CurrentUserLID returns this device's LID, which call media needs: the peer derives the SSRC it expects from the LID, not from the phone-number JID (see ssrc.go).
func (*Service) Disconnect ¶
func (s *Service) Disconnect()
func (*Service) DownloadMedia ¶
func (*Service) EditMessage ¶
func (s *Service) EditMessage(ctx context.Context, chatRef, messageID, newText string) (MessageRecord, error)
EditMessage edits a previously-sent message's text (WhatsApp shows "edited").
func (*Service) GroupInfoFromLink ¶ added in v0.3.0
GroupInfoFromLink previews a group behind an invite link without joining it.
func (*Service) GroupInviteLink ¶ added in v0.3.0
GroupInviteLink returns the group's invite link, optionally revoking the old one first.
func (*Service) HangupMedia ¶
HangupMedia ends a live media call.
func (*Service) HistoryMarker ¶
func (*Service) IsConnected ¶
func (*Service) JoinGroupWithLink ¶ added in v0.3.0
JoinGroupWithLink joins a group from an invite link or bare code.
func (*Service) LatestRingingCall ¶
LatestRingingCall returns the most recent incoming call still ringing, if any.
func (*Service) LeaveGroup ¶ added in v0.3.0
LeaveGroup leaves a group.
func (*Service) ListGroups ¶ added in v0.3.0
func (s *Service) ListGroups(ctx context.Context) ([]GroupSummary, error)
ListGroups returns every group this account belongs to.
func (*Service) MarkChatRead ¶
MarkChatRead sends read receipts for a chat's unread messages, which is what clears the unread badge on the other devices of this account.
func (*Service) MessageReceipts ¶
func (s *Service) MessageReceipts(messageID string) ([]ReceiptRecord, error)
MessageReceipts returns the delivery/read receipts recorded for a message.
func (*Service) PlaceCall ¶
func (s *Service) PlaceCall(ctx context.Context, recipient string, opts PlaceCallOptions) (CallInfo, error)
PlaceCall rings the given contact, and carries audio if the options ask for it.
The offer goes out through meowcaller rather than whatsmeow's OfferCall: a call we place gets its relay allocation in <ack class="call" type="offer">, which whatsmeow drops unhandled, so an offer it builds can ring but never carry media. See callmedia.go.
func (*Service) ReactToMessage ¶
ReactToMessage sends an emoji reaction to a message. An empty emoji removes an existing reaction, which is how WhatsApp itself models "un-react".
func (*Service) RefreshMissingChatNames ¶
func (*Service) RejectIncomingCall ¶
RejectIncomingCall declines a call that is currently ringing.
func (*Service) ReplayDelivery ¶ added in v0.3.0
func (s *Service) ReplayDelivery(deliveryID int64) (WebhookDeliveryRecord, error)
ReplayDelivery re-sends a recorded delivery, body unchanged.
Useful when a consumer was down, or was fixed after the fact: the event is still on disk, so it does not have to be recreated by hand.
func (*Service) RequestHistorySync ¶
func (*Service) ResolveBestTarget ¶
func (s *Service) ResolveBestTarget(ref, kind string, allowDirect bool) (ResolvedTarget, error)
func (*Service) ResolveTargets ¶
func (*Service) RevokeMessage ¶
RevokeMessage deletes/revokes a message for everyone.
func (*Service) RunTriggers ¶
func (s *Service) RunTriggers(event string, chat ChatRecord, message MessageRecord, dryRun bool) []TriggerResult
RunTriggers evaluates every trigger against an event and runs the ones that match.
Exported so an embedding caller can feed it events wacli did not generate itself. dryRun evaluates and reports without sending anything, which is what /triggers/test uses.
func (*Service) SearchMessages ¶
func (s *Service) SearchMessages(chatRef, senderRef, query string, limit int, mediaOnly bool, fromMe string) ([]MessageRecord, *ResolvedTarget, *ResolvedTarget, error)
func (*Service) SearchMessagesAdvanced ¶
func (s *Service) SearchMessagesAdvanced(chatRef, senderRef, query string, limit int, mediaOnly bool, fromMe string, before, after *time.Time) ([]MessageRecord, *ResolvedTarget, *ResolvedTarget, error)
func (*Service) SendMessage ¶
func (*Service) SendMessageReplying ¶
func (s *Service) SendMessageReplying(ctx context.Context, recipient, text, mediaPath, replyToID string) (MessageRecord, error)
SendMessageReplying sends a message that, when replyToID is a message ID in the same chat, is delivered as a WhatsApp REPLY quoting that message — so the recipient sees which message it answers.
func (*Service) SetGroupName ¶ added in v0.3.0
SetGroupName renames a group.
func (*Service) SetGroupTopic ¶ added in v0.3.0
SetGroupTopic sets a group's description.
func (*Service) SetPresence ¶ added in v0.3.0
SetPresence announces this account as available or unavailable.
Presence is also a prerequisite rather than a nicety: WhatsApp only delivers some events to a device that has announced itself.
func (*Service) SetTyping ¶ added in v0.3.0
SetTyping shows or clears the typing indicator in a chat, so an automated reply that takes a moment looks like someone composing rather than dead air.
func (*Service) StartCallCapture ¶
StartCallCapture begins recording raw call stanzas to the capture file.
func (*Service) StartConnectionWatchdog ¶
func (s *Service) StartConnectionWatchdog()
StartConnectionWatchdog guards against the failure mode where the WhatsApp socket stops delivering messages while still reporting "connected" — the daemon looks healthy but silently receives nothing. It reconnects when the client reports disconnected, or when nothing at all has arrived for watchdogStaleAfter (receipts/presence make a truly silent window unusual on an active account). Idempotent: only the first call starts the loop.
func (*Service) StopCallCapture ¶
StopCallCapture stops recording call stanzas.
func (*Service) Store ¶
Store exposes the local database: chats, messages, contacts, webhooks, triggers and settings.
func (*Service) TestTrigger ¶
func (s *Service) TestTrigger(id int64, chatRef, text string) (TriggerResult, error)
TestTrigger evaluates one trigger against a hypothetical message without sending anything.
func (*Service) TestWebhook ¶ added in v0.3.0
func (s *Service) TestWebhook(webhookID int64) (WebhookDeliveryRecord, error)
TestWebhook sends a synthetic event so an endpoint can be verified — reachability, status code and signature — without waiting for something real to happen.
func (*Service) UpdateGroupParticipants ¶ added in v0.3.0
func (s *Service) UpdateGroupParticipants(ctx context.Context, ref, action string, participantRefs []string) ([]GroupParticipant, error)
UpdateGroupParticipants adds, removes, promotes or demotes members.
action is add, remove, promote or demote. The per-participant outcome is returned rather than a single error, because WhatsApp routinely accepts some changes and refuses others in one request — a number that is not on WhatsApp, or someone who left.
func (*Service) WaitForBootstrapSync ¶
type StatusSnapshot ¶
type StatusSnapshot struct {
Connected bool `json:"connected"`
UserJID string `json:"user_jid,omitempty"`
UserLID string `json:"user_lid,omitempty"`
DNDMode bool `json:"dnd_mode"`
InitialAccessConfigured bool `json:"initial_access_configured"`
ChatCount int `json:"chat_count"`
MessageCount int `json:"message_count"`
LastHistorySync *time.Time `json:"last_history_sync,omitempty"`
}
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) AddAutoReply ¶
func (s *Store) AddAutoReply(rule AutoReplyRule) (AutoReplyRule, error)
func (*Store) AddWebhook ¶
func (s *Store) AddWebhook(record WebhookRecord) (WebhookRecord, error)
func (*Store) BuildStatus ¶
func (s *Store) BuildStatus(connected bool, userJID string) (StatusSnapshot, error)
func (*Store) ConfigureInitialAccess ¶
func (*Store) CreateTrigger ¶
CreateTrigger validates and stores a new trigger.
func (*Store) DeleteAutoReply ¶
func (*Store) DeleteTrigger ¶
DeleteTrigger removes a trigger.
func (*Store) DeleteWebhook ¶
func (*Store) EnsureChat ¶
func (*Store) FinishWebhookDelivery ¶
func (*Store) FinishWebhookDeliveryAttempt ¶ added in v0.3.0
func (s *Store) FinishWebhookDeliveryAttempt(id int64, status string, httpStatus int, lastError, responseBody string, attempts int) error
FinishWebhookDeliveryAttempt closes a delivery, recording how many attempts it took.
func (*Store) GetBoolSetting ¶
func (*Store) GetContact ¶
func (s *Store) GetContact(jid string) (ContactRecord, error)
func (*Store) GetDNDMode ¶
func (*Store) GetMessage ¶
func (s *Store) GetMessage(messageID, chatJID string) (MessageRecord, error)
func (*Store) GetTrigger ¶
GetTrigger returns one trigger by ID.
func (*Store) GetWebhook ¶ added in v0.3.0
func (s *Store) GetWebhook(id int64) (WebhookRecord, error)
GetWebhook returns one webhook subscription.
func (*Store) GetWebhookDelivery ¶ added in v0.3.0
func (s *Store) GetWebhookDelivery(id int64) (WebhookDeliveryRecord, error)
GetWebhookDelivery returns one delivery record, including the body needed to replay it.
func (*Store) InitialAccessConfigured ¶
func (*Store) JIDForNumber ¶
JIDForNumber finds the real JID for a bare number (e.g. "150285251002514") from known history/contacts — crucial for mentions, since a number can belong to an "@lid" identity and defaulting it to "@s.whatsapp.net" makes WhatsApp fail to render the mention. Prefers a JID seen in a specific chat, then any message sender, then a contact. Returns "" if the number is unknown.
func (*Store) LatestMessage ¶
func (s *Store) LatestMessage() (MessageRecord, error)
func (*Store) ListAppLogs ¶
func (s *Store) ListAppLogs(limit int, level, category, query string) ([]AppLogRecord, error)
func (*Store) ListAutoReplies ¶
func (s *Store) ListAutoReplies() ([]AutoReplyRule, error)
func (*Store) ListContacts ¶
func (s *Store) ListContacts(limit int, query string) ([]ContactRecord, error)
func (*Store) ListMessages ¶
func (s *Store) ListMessages(chatJID string, limit int) ([]MessageRecord, error)
func (*Store) ListReceipts ¶
func (s *Store) ListReceipts(messageID string) ([]ReceiptRecord, error)
ListReceipts returns all receipts for a message, oldest first.
func (*Store) ListTriggers ¶
ListTriggers returns every trigger in evaluation order: enabled first, then by priority, then ID.
func (*Store) ListWebhookDeliveries ¶
func (s *Store) ListWebhookDeliveries(limit int, status, event, query string) ([]WebhookDeliveryRecord, error)
func (*Store) ListWebhooks ¶
func (s *Store) ListWebhooks() ([]WebhookRecord, error)
func (*Store) MarkMessageDeleted ¶
MarkMessageDeleted flags a message as revoked/deleted.
func (*Store) RecordWebhookRetry ¶ added in v0.3.0
func (s *Store) RecordWebhookRetry(id int64, attempts int, lastError string, httpStatus int, nextRetry time.Time) error
RecordWebhookRetry marks a delivery as awaiting another attempt, so an operator watching the delivery log can tell "retrying" apart from "given up".
func (*Store) SearchMessages ¶
func (s *Store) SearchMessages(opts MessageSearchOptions) ([]MessageRecord, error)
func (*Store) SetDNDMode ¶
func (*Store) SetInitialAccessConfigured ¶
func (*Store) SetTriggerEnabled ¶
SetTriggerEnabled flips a trigger on or off without rewriting it.
func (*Store) StartWebhookDelivery ¶
func (*Store) StoreMessage ¶
func (s *Store) StoreMessage(record MessageRecord) error
func (*Store) StoreReceipt ¶
func (s *Store) StoreReceipt(rec ReceiptRecord) error
StoreReceipt upserts a receipt (message + recipient + type is unique).
func (*Store) UpdateMessageContent ¶
UpdateMessageContent rewrites a message's content and flags it edited.
func (*Store) UpdateMessageMediaPath ¶
func (*Store) UpdateTrigger ¶
UpdateTrigger replaces a trigger's definition, keeping its fire statistics.
func (*Store) UpsertContact ¶
func (s *Store) UpsertContact(record ContactRecord) error
func (*Store) UpsertContactMemory ¶
func (s *Store) UpsertContactMemory(jid string, update ContactUpdate) (ContactRecord, error)
type Trigger ¶
type Trigger struct {
ID int64 `json:"id"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
// Priority orders evaluation, lowest first. Ties break by ID.
Priority int `json:"priority"`
// Events selects which event kinds fire this trigger. Empty means incoming_message, which is
// what almost every rule wants.
Events []string `json:"events"`
// MatchType and Pattern filter on message text.
MatchType string `json:"match_type"`
Pattern string `json:"pattern,omitempty"`
// Scope limits which chats apply; ChatJIDs is the allow-list when Scope is "list".
Scope string `json:"scope"`
ChatJIDs []string `json:"chat_jids,omitempty"`
// FromMe filters on message direction: nil matches either, false only inbound, true only our own.
FromMe *bool `json:"from_me,omitempty"`
// Actions run in order when the trigger matches.
Actions []TriggerAction `json:"actions"`
// StopOnMatch prevents lower-priority triggers from running once this one fires. Auto-replies
// behaved this way, so it defaults to true on migrated rules.
StopOnMatch bool `json:"stop_on_match"`
// CooldownSeconds suppresses re-firing for the same chat within the window, so a chatty rule
// cannot turn into a message loop.
CooldownSeconds int `json:"cooldown_seconds"`
FireCount int64 `json:"fire_count"`
LastFiredAt time.Time `json:"last_fired_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Trigger is one rule: what to match, and what to do about it.
func (*Trigger) Matches ¶
func (t *Trigger) Matches(event string, chat ChatRecord, message MessageRecord) bool
Matches reports whether the trigger fires for this event, chat and message.
Exported so a caller can dry-run a rule against a message without sending anything — which is what the /triggers/test endpoint and the trigger_test tool use.
type TriggerAction ¶
type TriggerAction struct {
Type string `json:"type"`
// Text is the message body for send_text/send_media, or the caption for media.
Text string `json:"text,omitempty"`
// MediaPath is an absolute path for send_media.
MediaPath string `json:"media_path,omitempty"`
// Emoji is the reaction for react.
Emoji string `json:"emoji,omitempty"`
// URL is the endpoint for webhook.
URL string `json:"url,omitempty"`
// To is the destination chat for forward, as a JID or a resolvable reference.
To string `json:"to,omitempty"`
}
TriggerAction is one thing to do when a trigger fires.
Text fields expand a small set of placeholders — {{text}}, {{sender}}, {{sender_name}}, {{chat}}, {{chat_name}} — so a rule can answer with something derived from what arrived.
type TriggerResult ¶
type TriggerResult struct {
TriggerID int64 `json:"trigger_id"`
TriggerName string `json:"trigger_name"`
Matched bool `json:"matched"`
Actions []ActionResult `json:"actions,omitempty"`
Skipped string `json:"skipped,omitempty"`
}
TriggerResult reports what one trigger did, for the API, the CLI and dry runs.
type WebhookDeliveryRecord ¶
type WebhookDeliveryRecord struct {
ID int64 `json:"id"`
WebhookID int64 `json:"webhook_id"`
URL string `json:"url"`
Event string `json:"event"`
ChatJID string `json:"chat_jid,omitempty"`
MessageID string `json:"message_id,omitempty"`
Status string `json:"status"`
HTTPStatus int `json:"http_status,omitempty"`
LastError string `json:"last_error,omitempty"`
ResponseBody string `json:"response_body,omitempty"`
RequestBody string `json:"request_body,omitempty"`
// Attempts is how many POSTs this delivery took. NextRetryAt is when the next one is due while
// the status is "retrying".
Attempts int `json:"attempts"`
NextRetryAt time.Time `json:"next_retry_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type WebhookRecord ¶
type WebhookRecord struct {
ID int64 `json:"id"`
URL string `json:"url"`
Secret string `json:"secret,omitempty"`
Events []string `json:"events"`
Scope string `json:"scope"`
ChatJIDs []string `json:"chat_jids,omitempty"`
MessageTypes []string `json:"message_types,omitempty"`
ContextLimit int `json:"context_limit"`
Enabled bool `json:"enabled"`
// IncludeMentions delivers messages from chats OUTSIDE this webhook's scope
// when they @-mention this account, so a consumer can react to being
// summoned anywhere. Pure transport: what to do with those events (e.g.
// ignoring "@all" blasts) is the consumer's policy, not wacli's.
IncludeMentions bool `json:"include_mentions"`
// MaxAttempts bounds delivery retries; TimeoutSeconds bounds one attempt. Zero means the
// defaults in webhookdelivery.go.
MaxAttempts int `json:"max_attempts"`
TimeoutSeconds int `json:"timeout_seconds"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}