icloud

package
v0.0.0-...-1c138a3 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2026 License: MIT Imports: 18 Imported by: 1

Documentation

Index

Constants

View Source
const (
	ProtocolVersion = "QH5B2"
	OAuthClientID   = "d39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d"
)
View Source
const (
	HdrContentType       = "Content-Type"
	HdrXRequestedWith    = "X-Requested-With"
	HdrXAppleWidgetKey   = "X-Apple-Widget-Key"
	HdrAccept            = "Accept"
	HdrXAppleIDSessionID = "X-Apple-ID-Session-Id"
	HdrScnt              = "scnt"
)

Variables

View Source
var (
	ErrIncorrectUsernamePassword = errors.New("incorrect username or password")
	ErrRequiredPrivacyAck        = errors.New("sign in to https://appleid.apple.com and acknowledge the Apple ID and Privacy agreement")
	ErrUnexpectedSigninResponse  = errors.New("unexpected sign in response")
	ErrNotImplemented            = errors.New("not implemented")
	ErrSeverErrorOrInvalidCreds  = errors.New("apple server error or invalid credentials")
	ErrFindMySessionExpired      = errors.New("find my session expired: please call Login() again")
	ErrSessionExpired            = errors.New("icloud session expired: please call Login() again")
	ErrContactEtagMismatch       = errors.New("contact etag mismatch: contact was modified")
)

Functions

This section is empty.

Types

type AuthCompleteReq

type AuthCompleteReq struct {
	AccountName string   `json:"accountName"`
	RememberMe  bool     `json:"rememberMe"`
	TrustTokens []string `json:"trustTokens"`
	M1          string   `json:"m1"`
	C           string   `json:"c"`
	M2          string   `json:"m2"`
}

type AuthInitReq

type AuthInitReq struct {
	A           string   `json:"a"`
	AccountName string   `json:"accountName"`
	Protocols   []string `json:"protocols"`
}

type AuthInitResp

type AuthInitResp struct {
	Iteration int    `json:"iteration"`
	Salt      string `json:"salt"`
	Protocol  string `json:"protocol"`
	B         string `json:"b"`
	C         string `json:"c"`
}

type BIMI

type BIMI struct {
	Status string `json:"status"`
}

type Client

type Client struct {
	HttpClient tls_client.HttpClient

	Username string
	Password string
	// contains filtered or unexported fields
}

func NewClient

func NewClient(username, password string, sniff bool) (*Client, error)

* NewClient intializes a new http client and returns a new icloud client

func (*Client) CreateContact

func (c *Client) CreateContact(contact Contact) (*Contact, error)

CreateContact creates a new contact in iCloud. A contactId UUID is generated automatically by the client. Returns the created contact with etag populated.

func (*Client) DeactivateHME

func (c *Client) DeactivateHME(anonymousId string) (bool, error)

* DeactivateHME() Deactivates an HME from the user's account, using the given anonymousId. Can be reactivated later

func (*Client) DeleteContact

func (c *Client) DeleteContact(contactID, etag string) error

func (*Client) DeleteHME

func (c *Client) DeleteHME(anonymousId string) (bool, error)

* DeleteHME() Deletes an HME from the user's account, using the given anonymousId. Can not be recovered later

func (*Client) DeleteMail

func (c *Client) DeleteMail(uid string) (bool, error)

* DeleteMail() deletes an email from the user's inbox using the uid

func (*Client) DraftMail

func (c *Client) DraftMail(fromEmail, toEmail, subject, textBody, body string) (string, error)

* DraftMail() drafts and saves an email to the user's draft folder. fromName is the name of the sender, fromEmail is the email of the sender, toName is the name of the recipient, toEmail is the email of the recipient, subject is the subject of the email, textBody is the text body of the email, body is the full html body of the email

func (*Client) GetContact

func (c *Client) GetContact(contactID string) (*Contact, error)

func (*Client) GetContacts

func (c *Client) GetContacts() ([]Contact, error)

GetContacts fetches all contacts from iCloud. On first call, this automatically initializes the contacts session by calling startup. Returns the full contact list.

func (*Client) GetDevice

func (c *Client) GetDevice(id string) (*FMDevice, error)

GetDevice fetches all devices and returns the one matching the given ID. Returns an error if the device is not found.

func (*Client) GetDevices

func (c *Client) GetDevices() ([]FMDevice, error)

GetDevices fetches the full list of Find My devices for the account (including family members). It must be called at least once before PlaySound to initialize the server context.

func (*Client) GetMessage

func (c *Client) GetMessage(uid string) (Message, error)

* GetMessage() retrieves the message from the user's inbox using the uid, and returns the full body html of the email

func (*Client) GetMessageMetadata

func (c *Client) GetMessageMetadata(threadId string) (MessageMetadata, error)

* GetMessage() retrieves the message metadata from the user's inbox using the threadId

func (*Client) KeepAlive

func (c *Client) KeepAlive(ctx context.Context, interval time.Duration) error

KeepAlive keeps the iCloud session alive by calling ValidateSession on the given interval. It blocks until the context is cancelled or the session expires. Intended to be run in a goroutine:

go func() {
    if err := client.KeepAlive(ctx, 5*time.Minute); err != nil {
        // session expired — call Login() again
    }
}()

func (*Client) Login

func (c *Client) Login(otpProvider OTPProvider) error

Login logs in to iCloud and authenticates the user to access any iCloud web app/service. The otpProvider callback is called when two-factor authentication is required.

func (*Client) PlaySound

func (c *Client) PlaySound(deviceID string, channels []string) (*FMDevice, error)

PlaySound triggers a sound alert on the device with the given ID.

For AirPods and other multi-channel accessories, pass the audio channel names (e.g. []string{"left", "right"}). For all other devices (iPhone, Watch, Mac, etc.), pass nil or an empty slice.

GetDevices must be called at least once before PlaySound to establish the server context. Returns the updated device state as reported by the server.

func (*Client) ReactivateHME

func (c *Client) ReactivateHME(anonymousId string) (bool, error)

* ReactivateHME() Reactivates an HME for a user's account, using the given anonymousId

func (*Client) ReserveHME

func (c *Client) ReserveHME(label, note string) (string, error)

* ReserveHME() Generates a new HME and reserves it, if successful it returns the email to user

func (*Client) RetrieveHMEList

func (c *Client) RetrieveHMEList() ([]HmeEmail, error)

* RetrieveHMEList() Retrieves a list of HMEs from the user's account

func (*Client) RetrieveMailInbox

func (c *Client) RetrieveMailInbox(maxResults, beforeTs int) (MailInboxResp, error)

* RetrieveMailInbox() retrieves the user's inbox from their iCloud account, maxResults is the maximum number of emails to retrieve, beforeTs is the timestamp to retrieve emails before

func (*Client) SendDraft

func (c *Client) SendDraft(uid string) (bool, error)

* SendDraft() sends an email from the user's draft folder using the uid

func (*Client) UpdateContact

func (c *Client) UpdateContact(contact Contact) (*Contact, error)

UpdateContact updates an existing contact. Requires ContactID and Etag to be set. Returns the updated contact with new Etag.

func (*Client) ValidateSession

func (c *Client) ValidateSession() (bool, error)

ValidateSession checks whether the current iCloud session is still valid. Returns true if the session is active, false if it has expired. Call Login() again if this returns false.

type Contact

type Contact struct {
	ContactID   string           `json:"contactId,omitempty"`
	Etag        string           `json:"etag,omitempty"`
	FirstName   string           `json:"firstName,omitempty"`
	LastName    string           `json:"lastName,omitempty"`
	MiddleName  string           `json:"middleName,omitempty"`
	NamePrefix  string           `json:"namePrefix,omitempty"`
	NameSuffix  string           `json:"nameSuffix,omitempty"`
	Nickname    string           `json:"nickname,omitempty"`
	Phones      []ContactPhone   `json:"phones,omitempty"`
	Emails      []ContactEmail   `json:"emails,omitempty"`
	Addresses   []ContactAddress `json:"addresses,omitempty"`
	URLs        []ContactURL     `json:"urls,omitempty"`
	Birthday    string           `json:"birthday,omitempty"`
	CompanyName string           `json:"companyName,omitempty"`
	JobTitle    string           `json:"jobTitle,omitempty"`
	Department  string           `json:"department,omitempty"`
	Notes       string           `json:"notes,omitempty"`
	IsCompany   bool             `json:"isCompany"`
}

type ContactAddress

type ContactAddress struct {
	Label      string `json:"label,omitempty"`
	Street     string `json:"street,omitempty"`
	City       string `json:"city,omitempty"`
	State      string `json:"state,omitempty"`
	PostalCode string `json:"postalCode,omitempty"`
	Country    string `json:"country,omitempty"`
}

type ContactEmail

type ContactEmail struct {
	Label string `json:"label"`
	Field string `json:"field"`
}

type ContactPhone

type ContactPhone struct {
	Label string `json:"label"`
	Field string `json:"field"`
}

type ContactURL

type ContactURL struct {
	Label string `json:"label"`
	Field string `json:"field"`
}

type ContactsResponse

type ContactsResponse struct {
	Contacts  []Contact `json:"contacts"`
	SyncToken string    `json:"syncToken,omitempty"`
	PrefToken string    `json:"prefToken,omitempty"`
}

type ContactsStartupResp

type ContactsStartupResp struct {
	Contacts      []Contact `json:"contacts"`
	SyncToken     string    `json:"syncToken"`
	PrefToken     string    `json:"prefToken"`
	ContactsOrder []string  `json:"contactsOrder"`
	MeCardId      string    `json:"meCardId"`
}

type FMAudioChannel

type FMAudioChannel struct {
	Name      string `json:"name"`
	Available int    `json:"available"`
	Playing   bool   `json:"playing"`
	Muted     bool   `json:"muted"`
}

FMAudioChannel represents a single audio channel on an AirPods device.

type FMDevice

type FMDevice struct {
	ID                string           `json:"id"`
	Name              string           `json:"name"`
	DeviceDisplayName string           `json:"deviceDisplayName"`
	DeviceClass       string           `json:"deviceClass"`
	DeviceModel       string           `json:"deviceModel"`
	RawDeviceModel    string           `json:"rawDeviceModel"`
	ModelDisplayName  string           `json:"modelDisplayName"`
	DeviceColor       string           `json:"deviceColor"`
	DeviceStatus      string           `json:"deviceStatus"`
	BatteryLevel      *float64         `json:"batteryLevel"`
	BatteryStatus     *string          `json:"batteryStatus"`
	LocationCapable   bool             `json:"locationCapable"`
	LocationEnabled   bool             `json:"locationEnabled"`
	IsLocating        bool             `json:"isLocating"`
	LostModeCapable   bool             `json:"lostModeCapable"`
	LostModeEnabled   bool             `json:"lostModeEnabled"`
	ActivationLocked  bool             `json:"activationLocked"`
	PasscodeLength    int              `json:"passcodeLength"`
	CanWipeAfterLock  bool             `json:"canWipeAfterLock"`
	WipeInProgress    bool             `json:"wipeInProgress"`
	IsMac             bool             `json:"isMac"`
	ThisDevice        bool             `json:"thisDevice"`
	FmlyShare         bool             `json:"fmlyShare"`
	LowPowerMode      bool             `json:"lowPowerMode"`
	DeviceWithYou     bool             `json:"deviceWithYou"`
	PendingRemove     bool             `json:"pendingRemove"`
	DarkWake          bool             `json:"darkWake"`
	MaxMsgChar        int              `json:"maxMsgChar"`
	BaUUID            string           `json:"baUUID"`
	DeviceDiscoveryId string           `json:"deviceDiscoveryId"`
	CommandLookupId   string           `json:"commandLookupId"`
	LostTimestamp     string           `json:"lostTimestamp"`
	BrassStatus       string           `json:"brassStatus"`
	Features          FMDeviceFeatures `json:"features"`
	AudioChannels     []FMAudioChannel `json:"audioChannels"`
	Snd               *FMSndStatus     `json:"snd"`
	Msg               *FMMsgStatus     `json:"msg"`
	LostDevice        *FMLostDevice    `json:"lostDevice"`
	Location          interface{}      `json:"location"`
	TrackingInfo      interface{}      `json:"trackingInfo"`
	RemoteWipe        interface{}      `json:"remoteWipe"`
	RemoteLock        interface{}      `json:"remoteLock"`
	WipedTimestamp    interface{}      `json:"wipedTimestamp"`
	LockedTimestamp   interface{}      `json:"lockedTimestamp"`
	RepairStatus      interface{}      `json:"repairStatus"`
	EncodedDeviceId   interface{}      `json:"encodedDeviceId"`
	PrsId             interface{}      `json:"prsId"`
}

FMDevice represents a single device returned by the Find My service.

type FMDeviceFeatures

type FMDeviceFeatures map[string]bool

FMDeviceFeatures maps feature flag codes (e.g. "SND", "LCK", "WIP") to their enabled state.

type FMDevicesResp

type FMDevicesResp struct {
	UserInfo        json.RawMessage `json:"userInfo"`
	Alert           interface{}     `json:"alert"`
	ServerContext   json.RawMessage `json:"serverContext"`
	Content         []FMDevice      `json:"content"`
	UserPreferences json.RawMessage `json:"userPreferences"`
	StatusCode      string          `json:"statusCode"`
}

FMDevicesResp is the response envelope from refreshClient and playSound. ServerContext is stored raw so it can be echoed back verbatim in subsequent requests.

type FMLostDevice

type FMLostDevice struct {
	StopLostMode    bool   `json:"stopLostMode"`
	EmailUpdates    bool   `json:"emailUpdates"`
	UserText        bool   `json:"userText"`
	Sound           bool   `json:"sound"`
	OwnerNbr        string `json:"ownerNbr"`
	Text            string `json:"text"`
	Email           string `json:"email"`
	CreateTimestamp int64  `json:"createTimestamp"`
	StatusCode      string `json:"statusCode"`
}

FMLostDevice holds lost-mode details when a device is in lost mode.

type FMMsgStatus

type FMMsgStatus struct {
	Vibrate         bool   `json:"vibrate"`
	Strobe          bool   `json:"strobe"`
	UserText        bool   `json:"userText"`
	PlaySound       bool   `json:"playSound"`
	CreateTimestamp int64  `json:"createTimestamp"`
	StatusCode      string `json:"statusCode"`
}

FMMsgStatus is the status of a message/alert command on a device.

type FMSndStatus

type FMSndStatus struct {
	AlertText           string `json:"alertText"`
	CancelButtonTitle   string `json:"cancelButtonTitle"`
	ContinueButtonTitle string `json:"continueButtonTitle"`
	CreateTimestamp     int64  `json:"createTimestamp"`
	StatusCode          string `json:"statusCode"`
	AlertTitle          string `json:"alertTitle"`
}

FMSndStatus is the status of a play-sound command on a device.

type HMEListResp

type HMEListResp struct {
	Success   bool   `json:"success"`
	Timestamp int    `json:"timestamp"`
	Result    Result `json:"result"`
}

type HmeEmail

type HmeEmail struct {
	Origin          string `json:"origin"`
	AnonymousID     string `json:"anonymousId"`
	Domain          string `json:"domain"`
	ForwardToEmail  string `json:"forwardToEmail"`
	Hme             string `json:"hme"`
	Label           string `json:"label"`
	Note            string `json:"note"`
	CreateTimestamp int64  `json:"createTimestamp"`
	IsActive        bool   `json:"isActive"`
	RecipientMailID string `json:"recipientMailId"`
	OriginAppName   string `json:"originAppName,omitempty"`
	AppBundleID     string `json:"appBundleId,omitempty"`
}

type MailDraftReq

type MailDraftReq struct {
	Jsonrpc string `json:"jsonrpc"`
	Method  string `json:"method"`
	Params  Params `json:"params"`
}

type MailInboxResp

type MailInboxResp struct {
	TotalThreadsReturned int            `json:"totalThreadsReturned"`
	ThreadList           []Thread       `json:"threadList"`
	SessionHeaders       SessionHeaders `json:"sessionHeaders"`
	Events               []any          `json:"events"`
}

type Message

type Message struct {
	GUID           string         `json:"guid"`
	LongHeader     string         `json:"longHeader"`
	To             []string       `json:"to"`
	From           []string       `json:"from"`
	Cc             []string       `json:"cc"`
	Bcc            []string       `json:"bcc"`
	ContentType    string         `json:"contentType"`
	Bimi           BIMI           `json:"bimi"`
	Smime          SMIME          `json:"smime"`
	Parts          []MsgPart      `json:"parts"`
	SessionHeaders SessionHeaders `json:"sessionHeaders"`
	Events         []any          `json:"events"`
}

type MessageMetadata

type MessageMetadata struct {
	UID       string   `json:"uid"`
	Date      int64    `json:"date"`
	Size      int      `json:"size"`
	Folder    string   `json:"folder"`
	Modseq    int64    `json:"modseq"`
	Flags     []any    `json:"flags"`
	SentDate  string   `json:"sentDate"`
	Subject   string   `json:"subject"`
	From      []string `json:"from"`
	To        []string `json:"to"`
	Cc        []any    `json:"cc"`
	Bcc       []any    `json:"bcc"`
	Bimi      BIMI     `json:"bimi"`
	Smime     SMIME    `json:"smime"`
	MessageID string   `json:"messageId"`
	Parts     []Part   `json:"parts"`
}

type MsgPart

type MsgPart struct {
	GUID    string `json:"guid"`
	Content string `json:"content"`
}

type OTPProvider

type OTPProvider func() (string, error)

OTPProvider is a callback function that prompts for and returns a 2FA code. It is called during Login when two-factor authentication is required.

type Params

type Params struct {
	From               string `json:"from"`
	To                 string `json:"to"`
	Subject            string `json:"subject"`
	TextBody           string `json:"textBody"`
	Body               string `json:"body"`
	Attachments        []any  `json:"attachments"`
	WebmailClientBuild string `json:"webmailClientBuild"`
}

type Part

type Part struct {
	JSONType    string `json:"jsonType"`
	ContentType string `json:"contentType"`
	Params      string `json:"params"`
	Encoding    string `json:"encoding"`
	Size        int    `json:"size"`
	PartID      string `json:"partId"`
	Lines       int    `json:"lines"`
	IsAttach    bool   `json:"isAttach"`
}

type PhoneNumberID

type PhoneNumberID struct {
	ID int `json:"id"`
}

type Result

type Result struct {
	ForwardToEmails   []string   `json:"forwardToEmails"`
	HmeEmails         []HmeEmail `json:"hmeEmails"`
	SelectedForwardTo string     `json:"selectedForwardTo"`
}

type SMIME

type SMIME struct {
	Status string `json:"status"`
}

type SecurityCode

type SecurityCode struct {
	Code string `json:"code"`
}

type ServiceError

type ServiceError struct {
	Code    string `json:"code,omitempty"`
	Title   string `json:"title,omitempty"`
	Message string `json:"message,omitempty"`
}

ServiceError represents a Apple service error.

type SessionHeaders

type SessionHeaders struct {
	Folder       string `json:"folder"`
	Modseq       int64  `json:"modseq"`
	Threadmodseq int64  `json:"threadmodseq"`
	Condstore    int    `json:"condstore"`
	Qresync      int    `json:"qresync"`
	Threadmode   int    `json:"threadmode"`
}

type Thread

type Thread struct {
	JSONType           string   `json:"jsonType"`
	ThreadID           string   `json:"threadId"`
	Timestamp          int64    `json:"timestamp"`
	Count              int      `json:"count"`
	FolderMessageCount int      `json:"folderMessageCount"`
	Flags              []string `json:"flags"`
	Senders            []string `json:"senders"`
	Subject            string   `json:"subject"`
	Preview            string   `json:"preview"`
	Modseq             int64    `json:"modseq"`
}

type TwoFactorCodeFromPhoneRequest

type TwoFactorCodeFromPhoneRequest struct {
	SecurityCode *SecurityCode  `json:"securityCode,omitempty"`
	PhoneNumber  *PhoneNumberID `json:"phoneNumber,omitempty"`
	Mode         string         `json:"mode,omitempty"`
}

Jump to

Keyboard shortcuts

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