client

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package client wraps go.mau.fi/whatsmeow and persists messages to the local message cache in internal/store. All logs are written to stderr.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewStderrLogger

func NewStderrLogger(module string, level string, colorful bool) waLog.Logger

NewStderrLogger returns a waLog.Logger that writes to os.Stderr. The API mirrors waLog.Stdout so callers can substitute it freely.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client wraps a whatsmeow.Client together with the message cache and logger.

func New

func New(ctx context.Context, cfg Config) (*Client, error)

New constructs a Client. It sets the latest WhatsApp version best-effort, opens the whatsmeow sqlstore, and loads the first device. The returned Client is NOT connected; call Login or Connect.

func (*Client) AddLoggedOutHandler

func (c *Client) AddLoggedOutHandler(fn func(*events.LoggedOut))

AddLoggedOutHandler registers a callback that fires when whatsmeow emits an events.LoggedOut event (i.e. the remote device has revoked this session). The callback runs in whatsmeow's event goroutine; keep it non-blocking.

func (*Client) BlockContact

func (c *Client) BlockContact(ctx context.Context, jidRaw string) error

BlockContact blocks the given contact JID or phone number.

func (*Client) Connect

func (c *Client) Connect(ctx context.Context, opts ConnectOpts) error

Connect opens the whatsmeow WebSocket. By default it refuses to proceed when the device has no stored session; set AllowUnpaired to bypass that guard (e.g. during the QR pairing flow).

func (*Client) CreateGroup

func (c *Client) CreateGroup(ctx context.Context, name string, participants []string) (string, string, error)

CreateGroup creates a new group with the given name and initial participants. Returns the new group JID as a string and its info serialised as JSON.

func (*Client) DeleteMessage

func (c *Client) DeleteMessage(ctx context.Context, chatJID, messageID, senderJID string) error

DeleteMessage revokes a message for everyone. senderJID is required only when revoking someone else's message as a group admin; for your own messages pass "".

func (*Client) Disconnect

func (c *Client) Disconnect()

Disconnect gracefully disconnects the underlying client.

func (*Client) Download

func (c *Client) Download(ctx context.Context, messageID, chatJID string) DownloadResult

Download fetches media for a previously-cached message and writes it under <StoreDir>/<chat_sanitized>/<filename>.

func (*Client) EditMessage

func (c *Client) EditMessage(ctx context.Context, chatJID, messageID, newBody string) error

EditMessage edits a previously-sent message. The new body becomes the new conversation text.

func (*Client) GetBlocklist

func (c *Client) GetBlocklist(ctx context.Context) (string, error)

GetBlocklist returns the user's current blocklist as JSON.

func (*Client) GetChatName

func (c *Client) GetChatName(jid types.JID, chatJID string, conversation *waHistorySync.Conversation, sender string) string

GetChatName determines the appropriate name for a chat. It checks the existing database entry first, then falls back to conversation metadata (for history sync), contact store lookups, and finally the JID. The conversation parameter is the typed whatsmeow Conversation from a history-sync payload; pass nil for live messages.

func (*Client) GetGroupInfoJSON

func (c *Client) GetGroupInfoJSON(ctx context.Context, chatJID string) (string, error)

GetGroupInfoJSON returns a JSON-encoded types.GroupInfo for the given chat.

func (c *Client) GetGroupInviteLink(ctx context.Context, chatJID string, reset bool) (string, error)

GetGroupInviteLink returns the group's current invite link. If reset is true, the previous link is revoked and a new one is generated.

func (*Client) GetPollResults

func (c *Client) GetPollResults(ctx context.Context, chatJID, pollMessageID string) (*PollResults, error)

GetPollResults returns the tally of votes on a poll we have metadata for. Returns sql.ErrNoRows wrapped if the poll is not in the local cache yet. Does not require an active connection — reads strictly from the local cache.

func (*Client) GetPrivacySettings

func (c *Client) GetPrivacySettings(ctx context.Context) (string, error)

GetPrivacySettings returns the current privacy settings as JSON.

func (*Client) IsConnected

func (c *Client) IsConnected() bool

IsConnected reports whether the underlying whatsmeow client currently holds a live WebSocket to WhatsApp. Used by the daemon state machine to skip a second Connect call after a pairing-driven connect has already established the session.

func (*Client) IsLoggedIn

func (c *Client) IsLoggedIn() bool

IsLoggedIn reports whether the underlying whatsmeow device has a stored session. A false return means the next Connect call will emit QR pairing events instead of reconnecting.

func (*Client) IsOnWhatsApp

func (c *Client) IsOnWhatsApp(ctx context.Context, phones []string) (map[string]bool, error)

IsOnWhatsApp checks whether each phone number (digits only) is registered on WhatsApp. Returns a map keyed by the input phone string.

func (c *Client) JoinGroupWithLink(ctx context.Context, linkOrCode string) (string, error)

JoinGroupWithLink joins a group given either a full invite URL or a bare invite code. Returns the joined group's JID as a string.

func (*Client) LeaveGroup

func (c *Client) LeaveGroup(ctx context.Context, chatJID string) error

LeaveGroup leaves the given group chat.

func (*Client) ListJoinedGroups

func (c *Client) ListJoinedGroups(ctx context.Context) (string, error)

ListJoinedGroups returns JSON of all groups the user is in.

func (*Client) Log

func (c *Client) Log() waLog.Logger

Log returns the logger used by this client.

func (*Client) Login

func (c *Client) Login(ctx context.Context, qrOut io.Writer) error

Login runs the QR-code pairing flow. Writes the QR code to qrOut (stdout for the `login` subcommand). Blocks until pairing completes or ctx is done.

func (*Client) Logout

func (c *Client) Logout(ctx context.Context) error

Logout drops the currently paired device from WhatsApp's server and clears the local session. After this call, IsLoggedIn returns false and the next Connect will start a fresh pairing flow.

func (*Client) MarkChatRead

func (c *Client) MarkChatRead(ctx context.Context, chatJID string, limit int) (int, error)

MarkChatRead acks recent incoming messages in a chat so the phone stops showing unread badges. Returns the number of messages acked.

func (*Client) MarkRead

func (c *Client) MarkRead(ctx context.Context, chatJID string, messageIDs []string, senderJID string) error

MarkRead marks messageIDs as read for the given chat. senderJID is the original sender (required by WhatsApp for group reads); empty string is treated as the chat JID itself.

func (*Client) QRChannel

func (c *Client) QRChannel(ctx context.Context) (<-chan whatsmeow.QRChannelItem, error)

QRChannel exposes whatsmeow's pairing QR channel. Must be called before Connect when the device is not yet paired. The channel emits QRChannelItem events while pairing is in progress and closes on success.

func (*Client) RequestHistorySync

func (c *Client) RequestHistorySync(ctx context.Context, chatJID string, fromTimestamp time.Time) (string, error)

RequestHistorySync asks WhatsApp to backfill messages for chatJID. When fromTimestamp is zero the newest cached message is used as the anchor; otherwise the provided timestamp is used. Returns a human-readable status.

func (*Client) Send

func (c *Client) Send(ctx context.Context, recipient, message string) SendResult

Send sends a text message.

func (*Client) SendContactCard

func (c *Client) SendContactCard(ctx context.Context, recipient, name, phone, vcardOverride string) SendResult

SendContactCard sends a contact vCard. If vcardOverride is non-empty, it is sent verbatim; otherwise buildVCard(name, phone) synthesises a vCard 3.0.

func (*Client) SendMedia

func (c *Client) SendMedia(ctx context.Context, recipient, caption, mediaPath string) SendResult

SendMedia uploads mediaPath and sends it with optional caption.

func (*Client) SendMediaWithOptions

func (c *Client) SendMediaWithOptions(ctx context.Context, opts SendMediaOptions) SendResult

SendMediaWithOptions is the extensible entry point for media sends.

func (*Client) SendPoll

func (c *Client) SendPoll(ctx context.Context, recipient, question string, options []string, selectableCount int) SendResult

SendPoll sends a poll message. options are presented in the order given. selectableCount is clamped to 1 when <= 0.

func (*Client) SendPollVote

func (c *Client) SendPollVote(ctx context.Context, chatJID, pollMessageID string, options []string) SendResult

SendPollVote casts a vote on a previously-seen poll. pollMessageID is the original poll's message ID. options must exactly match the option names on the poll creation message.

func (*Client) SendPresence

func (c *Client) SendPresence(ctx context.Context, state string) error

SendPresence sets the user's own online availability. state must be "available" or "unavailable".

func (*Client) SendReaction

func (c *Client) SendReaction(ctx context.Context, chatJID, messageID, senderJID, emoji string) error

SendReaction adds (or clears, if emoji is empty) a reaction to a message.

func (*Client) SendReply

func (c *Client) SendReply(ctx context.Context, chatJID, targetMessageID, targetSenderJID, body string) error

SendReply sends a text reply that quotes targetMessageID from chatJID.

func (*Client) SendTyping

func (c *Client) SendTyping(ctx context.Context, chatJID string, active bool, kind string) error

SendTyping sets chat presence to "composing" when active is true, or "paused" when false. kind may be "audio" to indicate a voice recording.

func (*Client) SetGroupAnnounce

func (c *Client) SetGroupAnnounce(ctx context.Context, chatJID string, announceOnly bool) error

SetGroupAnnounce toggles announce-only mode (only admins can send messages).

func (*Client) SetGroupLocked

func (c *Client) SetGroupLocked(ctx context.Context, chatJID string, locked bool) error

SetGroupLocked toggles locked mode (only admins can change metadata).

func (*Client) SetGroupName

func (c *Client) SetGroupName(ctx context.Context, chatJID, name string) error

SetGroupName changes a group's display name.

func (*Client) SetGroupTopic

func (c *Client) SetGroupTopic(ctx context.Context, chatJID, topic string) error

SetGroupTopic changes a group's description/topic. The previous and new topic IDs are left empty so whatsmeow auto-fetches/generates them.

func (*Client) SetPrivacySetting

func (c *Client) SetPrivacySetting(ctx context.Context, name, value string) (string, error)

SetPrivacySetting changes a single privacy setting. Returns the resulting privacy settings as JSON. name and value must be one of whatsmeow's known constants; invalid input is rejected with a message listing the allowed values for the offending argument.

func (*Client) SetStatusMessage

func (c *Client) SetStatusMessage(ctx context.Context, text string) error

SetStatusMessage updates the user's "About" text.

func (*Client) StartEventHandler

func (c *Client) StartEventHandler()

StartEventHandler registers the event handler on the underlying whatsmeow client. Must be called before Connect().

func (*Client) Store

func (c *Client) Store() *store.Store

Store returns the message cache.

func (*Client) UnblockContact

func (c *Client) UnblockContact(ctx context.Context, jidRaw string) error

UnblockContact unblocks the given contact JID or phone number.

func (*Client) UpdateGroupParticipants

func (c *Client) UpdateGroupParticipants(ctx context.Context, chatJID string, participants []string, action string) (string, error)

UpdateGroupParticipants applies the given action to the participants of a group. Returns the resulting participant list as JSON.

func (*Client) ValidateMediaPath

func (c *Client) ValidateMediaPath(userPath string) (string, error)

ValidateMediaPath is a bound convenience wrapper around security.ValidateMediaPath that uses the client's configured allowlist root. Callers inside internal/client and internal/mcp should prefer this over calling the package-level helper directly.

func (*Client) WA

func (c *Client) WA() *whatsmeow.Client

WA exposes the underlying whatsmeow client for advanced callers.

type Config

type Config struct {
	StoreDir         string             // directory holding messages.db and whatsapp.db
	Store            *store.Store       // initialized message store
	Logger           waLog.Logger       // optional; defaults to stderr at INFO
	AllowedMediaRoot string             // absolute path; media_path args must live under this
	Redactor         *security.Redactor // optional; defaults to a redacting instance
}

Config configures a new Client.

type ConnectOpts

type ConnectOpts struct {
	// AllowUnpaired skips the "must be paired" guard so that the QR
	// pairing state machine can start. Normal callers leave this false.
	AllowUnpaired bool
}

ConnectOpts controls the behaviour of Connect.

type DownloadResult

type DownloadResult struct {
	Success   bool
	Message   string
	MediaType string
	Filename  string
	Path      string
}

DownloadResult is the public return value from Download.

type MediaDownloader

type MediaDownloader struct {
	URL           string
	DirectPath    string
	MediaKey      []byte
	FileLength    uint64
	FileSHA256    []byte
	FileEncSHA256 []byte
	MediaType     whatsmeow.MediaType
}

MediaDownloader implements whatsmeow.DownloadableMessage for cached media.

func (*MediaDownloader) GetDirectPath

func (d *MediaDownloader) GetDirectPath() string

func (*MediaDownloader) GetFileEncSHA256

func (d *MediaDownloader) GetFileEncSHA256() []byte

func (*MediaDownloader) GetFileLength

func (d *MediaDownloader) GetFileLength() uint64

func (*MediaDownloader) GetFileSHA256

func (d *MediaDownloader) GetFileSHA256() []byte

func (*MediaDownloader) GetMediaKey

func (d *MediaDownloader) GetMediaKey() []byte

func (*MediaDownloader) GetMediaType

func (d *MediaDownloader) GetMediaType() whatsmeow.MediaType

func (*MediaDownloader) GetURL

func (d *MediaDownloader) GetURL() string

type PollResults

type PollResults struct {
	PollMessageID string         `json:"poll_message_id"`
	ChatJID       string         `json:"chat_jid"`
	Tally         map[string]int `json:"tally"` // option name -> vote count
}

PollResults is the shape returned by GetPollResults.

type SendMediaOptions

type SendMediaOptions struct {
	Recipient string
	Caption   string
	MediaPath string
	ViewOnce  bool
}

SendMediaOptions bundles the inputs to SendMediaWithOptions so callers can add per-message flags (view_once, etc.) without growing the argument list.

type SendResult

type SendResult struct {
	Success bool
	Message string
	ID      string
}

SendResult is the public return value from Send/SendMedia.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL