Documentation ¶
Overview ¶
Package jmap implements JMAP Core protocol as defined in RFC 8620 published on July 2019.
Documentation strings for most of the protocol objects are taken from (or based on) contents of RFC 8620 and is subject to the IETF Trust Provisions. See https://trustee.ietf.org/license-info for details.
Example ¶
Basic usage of the client, with chaining of methods
// Create a new client. The SessionEndpoint must be specified for // initial connections. client := &jmap.Client{ SessionEndpoint: "https://api.fastmail.com/jmap/session", } // Set the authentication mechanism. This also sets the HttpClient of // the jmap client client.WithAccessToken("my-access-token") // Authenticate the client. This gets a Session object. Session objects // are cacheable, and have their own state string clients can use to // decide when to refresh. The client can be initialized with a cached // Session object. If one isn't available, the first request will also // authenticate the client if err := client.Authenticate(); err != nil { // Handle the error } // Get the account ID of the primary mail account id := client.Session.PrimaryAccounts[mail.URI] // Create a new request req := &jmap.Request{} // Invoke a method. The CallID of this method will be returned to be // used when chaining calls req.Invoke(&mailbox.Get{ Account: id, }) // Invoke a changes call, let's save the callID and pass it to a Get // method callID := req.Invoke(&email.Changes{ Account: id, SinceState: "some-known-state", }) // Invoke a result reference call req.Invoke(&email.Get{ Account: id, ReferenceIDs: &jmap.ResultReference{ ResultOf: callID, // The CallID of the referenced method Name: "Email/changes", // The name of the referenced method Path: "/created", // JSON pointer to the location of the reference }, }) // Make the request resp, err := client.Do(req) if err != nil { // Handle the error } // Loop through the responses to invidividual invocations for _, inv := range resp.Responses { // Our result to individual calls is in the Args field of the // invocation switch r := inv.Args.(type) { case *mailbox.GetResponse: // A GetResponse contains a List of the objects // retrieved for _, mbox := range r.List { fmt.Printf("Mailbox name: %s", mbox.Name) fmt.Printf("Total email: %d", mbox.TotalEmails) fmt.Printf("Unread email: %d", mbox.UnreadEmails) } case *email.GetResponse: for _, eml := range r.List { fmt.Printf("Email subject: %s", eml.Subject) } } // There is a response in here to the Email/changes call, but we // don't care about the results since we passed them to the // Email/get call }
Output:
Example (Eventsource) ¶
Example usage of an eventsource push notification connection
client := &jmap.Client{ SessionEndpoint: "https://api.fastmail.com/jmap/session", } myHandlerFunc := func(change *jmap.StateChange) { // handle the change } // If we don't set the Events field, all events will be subscribed to stream := &push.EventSource{ Client: client, Handler: myHandlerFunc, } if err := stream.Listen(); err != nil { // error occurs if the stream couldn't connect. Listen will // return when stream.Close is called }
Output:
Index ¶
- Constants
- func RegisterCapability(c Capability)
- func RegisterMethod(name string, factory MethodResponseFactory)
- type Account
- type AddedItem
- type Capability
- type Client
- func (c *Client) Authenticate() error
- func (c *Client) Do(req *Request) (*Response, error)
- func (c *Client) Download(accountID ID, blobID ID) (io.ReadCloser, error)
- func (c *Client) Upload(accountID ID, blob io.Reader) (*UploadResponse, error)
- func (c *Client) WithAccessToken(token string) *Client
- func (c *Client) WithBasicAuth(username string, password string) *Client
- type CollationAlgo
- type EventType
- type ID
- type Invocation
- type Method
- type MethodError
- type MethodResponse
- type MethodResponseFactory
- type Operator
- type Patch
- type Request
- type RequestError
- type Response
- type ResultReference
- type Session
- type SetError
- type StateChange
- type TypeState
- type URI
- type UploadResponse
Examples ¶
Constants ¶
const ( // The ASCIINumeric collation is a simple collation intended for use // with arbitrary sized unsigned decimal integer numbers stored as octet // strings. US-ASCII digits (0x30 to 0x39) represent digits of the numbers. // Before converting from string to integer, the input string is truncated // at the first non-digit character. All input is valid; strings which do // not start with a digit represent positive infinity. // // Defined in RFC 4790. ASCIINumeric CollationAlgo = "i;ascii-numeric" // The ASCIICasemap collation is a simple collation which operates on // octet strings and treats US-ASCII letters case-insensitively. It provides // equality, substring and ordering operations. All input is valid. Note that // letters outside ASCII are not treated case- insensitively. // // Defined in RFC 4790. ASCIICasemap = "i;ascii-casemap" // The "i;unicode-casemap" collation is a simple collation which is // case-insensitive in its treatment of characters. It provides equality, // substring, and ordering operations. The validity test operation returns "valid" // for any input. // // This collation allows strings in arbitrary (and mixed) character sets, // as long as the character set for each string is identified and it is // possible to convert the string to Unicode. Strings which have an // unidentified character set and/or cannot be converted to Unicode are not // rejected, but are treated as binary. // // Defined in RFC 5051. UnicodeCasemap = "i;unicode-casemap" )
Variables ¶
This section is empty.
Functions ¶
func RegisterMethod ¶
func RegisterMethod(name string, factory MethodResponseFactory)
Register a method. The Name parameter will be used when unmarshalling responses to call the responseConstructor, which should generate a pointer to an empty Response object of that method. This object will be returned in the result set (unless there is an error)
Types ¶
type Account ¶
type Account struct { // The ID of the account ID string `json:"-"` // A user-friendly string to show when presenting content from this // account, e.g. the email address representing the owner of the account. Name string `json:"name"` // This is true if the account belongs to the authenticated user, rather // than a group account or a personal account of another user that has been // shared with them. IsPersonal bool `json:"isPersonal"` // This is true if the entire account is read-only. IsReadOnly bool `json:"isReadOnly"` // The set of capability URIs for the methods supported in this account. // Each key is a URI for a capability that has methods you can use with // this account. The value for each of these keys is an object with further // information about the account’s permissions and restrictions with // respect to this capability, as defined in the capability’s // specification. Capabilities map[URI]Capability `json:"-"` // The raw JSON of accountCapabilities RawCapabilities map[URI]json.RawMessage `json:"accountCapabilities"` }
An account is a collection of data. A single account may contain an arbitrary set of data types, for example a collection of mail, contacts and calendars.
See RFC 8620 section 1.6.2 for details.
func (*Account) UnmarshalJSON ¶
type AddedItem ¶
The id and index in the query results (in the new state) for every Foo that has been added to the results since the old state AND every Foo in the current results that was included in the removed array (due to a filter or sort based upon a mutable property).
If the sort and filter are both only on immutable properties and an upToId is supplied and exists in the results, any ids that were added but have a higher index than upToId SHOULD be omitted.
The array MUST be sorted in order of index, with the lowest index first.
type Capability ¶
type Capability interface { // The URI of the capability, eg "urn:ietf:params:jmap:core" URI() URI // Generates a pointer to a new Capability object New() Capability }
A Capability broadcasts that the server supports underlying methods
type Client ¶
type Client struct { sync.Mutex // The HttpClient.Client to use for requests. The HttpClient.Client should handle // authentication. Calling WithBasicAuth or WithAccessToken on the // Client will set the HttpClient to one which uses authentication HttpClient *http.Client // The JMAP Session Resource Endpoint. If the client detects the Session // object needs refetching, it will automatically do so. SessionEndpoint string // the JMAP Session object Session *Session }
A JMAP Client
func (*Client) Authenticate ¶
Authenticate authenticates the client and retrieves the Session object. Authenticate will be called automatically when Do is called if the Session object hasn't already been initialized. Call Authenticate before any requests if you need to access information from the Session object prior to the first request
func (*Client) Upload ¶
Upload sends binary data to the server and returns blob ID and some associated meta-data.
There are some caveats to keep in mind: - Server may return the same blob ID for multiple uploads of the same blob. - Blob ID may become invalid after some time if it is unused. - Blob ID is usable only by the uploader until it is used, even for shared accounts.
func (*Client) WithAccessToken ¶
Set the HttpClient to a client which authenticates using the provided Access Token
type CollationAlgo ¶
type CollationAlgo string
type EventType ¶
type EventType string
An EventType is the name of a Type provided by a capability which may be subscribed to using a PushSubscription or an EventSource connection. Each specification may define their own types and events
const AllEvents EventType = "*"
Subscribe to all events
type ID ¶
type ID string
ID is a unique identifier assigned by the server. The character set must contain only ASCII alphanumerics, hyphen, or underscore and the ID must be between 1 and 255 octets long.
func (ID) MarshalJSON ¶
type Invocation ¶
type Invocation struct { // The name of the method call or response Name string // Object containing the named arguments for the method or response Args interface{} // Arbitrary string set by client, echoed back with responses CallID string }
An Invocation represents method calls and responses
func (*Invocation) MarshalJSON ¶
func (i *Invocation) MarshalJSON() ([]byte, error)
func (*Invocation) UnmarshalJSON ¶
func (i *Invocation) UnmarshalJSON(data []byte) error
type Method ¶
type Method interface { // The name of the method, ie "Core/echo" Name() string // The JMAP capabilities required for the method, ie "urn:ietf:params:jmap:core" Requires() []URI }
A JMAP method. The method object will be marshaled as the arguments to an invocation.
type MethodError ¶
type MethodError struct { // The type of error that occurred. Always present Type string `json:"type,omitempty"` // Description is available on some method errors (notably, // invalidArguments) Description *string `json:"description,omitempty"` }
A MethodError is returned when an error occurred while the server was processing a method. Instead of the Response of that method, a MethodError invocation will be in it's place
func (*MethodError) Error ¶
func (m *MethodError) Error() string
type MethodResponseFactory ¶
type MethodResponseFactory func() MethodResponse
A Factory function which produces a new MethodResponse object
type Operator ¶
type Operator string
Operator is used when constructing FilterOperator. It MUST be "AND", "OR", or "NOT"
type Patch ¶
type Patch map[string]interface{}
Patch represents a patch which can be used in a set.Update call. All paths MUST also conform to the following restrictions; if there is any violation, the update MUST be rejected with an invalidPatch error:
The pointer MUST NOT reference inside an array (i.e., you MUST NOT insert/delete from an array; the array MUST be replaced in its entirety instead). All parts prior to the last (i.e., the value after the final slash) MUST already exist on the object being patched. There MUST NOT be two patches in the Patch where the pointer of one is the prefix of the pointer of the other, e.g., “alerts/1/offset” and “alerts”.
The keys are a JSON pointer path, and the value is the value to set the path to
type Request ¶
type Request struct { // The context to make the request with Context context.Context `json:"-"` // The JMAP capabilities the request should use Using []URI `json:"using"` // A slice of methods the server will process. These will be processed // sequentially Calls []*Invocation `json:"methodCalls"` // A map of (client-specified) creation ID to the ID the server assigned // when a record was successfully created. CreatedIDs map[ID]ID `json:"createdIds,omitempty"` }
type RequestError ¶
type RequestError struct { // The type of request error, eg "urn:ietf:params:jmap:error:limit" Type string `json:"type"` // The HTTP status code of the response Status int `json:"status"` // The description of the error Detail string `json:"detail"` // If the error is of type ErrLimit, Limit will contain the name of the // limit the request would have exceeded Limit *string `json:"limit,omitempty"` }
A RequestError occurs when there is an error with the HTTP request
func (*RequestError) Error ¶
func (e *RequestError) Error() string
type Response ¶
type Response struct { // An array of responses, in the same format as the Calls on the // Request object. The output of the methods will be added to the // methodResponses array in the same order as the methods are processed. Responses []*Invocation `json:"methodResponses"` // A map of (client-specified) creation id to the id the server assigned // when a record was successfully created. CreatedIDs map[ID]ID `json:"createdIds,omitempty"` // The current value of the “state” string on the JMAP Session object, as // described in section 2. Clients may use this to detect if this object // has changed and needs to be refetched. SessionState string `json:"sessionState"` }
type ResultReference ¶
type ResultReference struct { // The method call id (see Section 3.1.1) of a previous method call in // the current request. ResultOf string `json:"resultOf"` // The required name of a response to that method call. Name string `json:"name"` // A pointer into the arguments of the response selected via the name // and resultOf properties. This is a JSON Pointer [@!RFC6901], except // it also allows the use of * to map through an array (see the // description below). Path string `json:"path"` }
To allow clients to make more efficient use of the network and avoid round trips, an argument to one method can be taken from the result of a previous method call in the same request.
To do this, the client prefixes the argument name with # (an octothorpe). The value is a ResultReference object as described below. When processing a method call, the server MUST first check the arguments object for any names beginning with #. If found, the result reference should be resolved and the value used as the “real” argument. The method is then processed as normal. If any result reference fails to resolve, the whole method MUST be rejected with an invalidResultReference error. If an arguments object contains the same argument name in normal and referenced form (e.g., foo and #foo), the method MUST return an invalidArguments error.
type Session ¶
type Session struct { // An object specifying the capabilities of this server. Each key is a URI // for a capability supported by the server. The value for each of these // keys is an object with further information about the server’s // capabilities in relation to that capability. Capabilities map[URI]Capability `json:"-"` RawCapabilities map[URI]json.RawMessage `json:"capabilities"` // A map of account id to Account object for each account the user has // access to. Accounts map[ID]Account `json:"accounts"` // A map of capability URIs (as found in Capabilities) to the // account id to be considered the user’s main or default account for data // pertaining to that capability. PrimaryAccounts map[URI]ID `json:"primaryAccounts"` // The username associated with the given credentials, or the empty string // if none. Username string `json:"username"` // The URL to use for JMAP API requests. APIURL string `json:"apiUrl"` // The URL endpoint to use when downloading files, in RFC 6570 URI // Template (level 1) format. DownloadURL string `json:"downloadUrl"` // The URL endpoint to use when uploading files, in RFC 6570 URI // Template (level 1) format. UploadURL string `json:"uploadUrl"` // The URL to connect to for push events, as described in section 7.3, in // RFC 6570 URI Template (level 1) format. EventSourceURL string `json:"eventSourceUrl"` // A string representing the state of this object on the server. If the // value of any other property on the session object changes, this string // will change. // // The current value is also returned on the API Response object, allowing // clients to quickly determine if the session information has changed // (e.g. an account has been added or removed) and so they need to refetch // the object. State string `json:"state"` }
func (*Session) UnmarshalJSON ¶
type SetError ¶
type SetError struct { // The type of SetError Type string `json:"type,omitempty"` // A description of the error to help with debugging that includes an // explanation of what the problem was. This is a non-localised string // and is not intended to be shown directly to end users. Description *string `json:"description,omitempty"` // Properties is available on InvalidProperties SetErrors and lists the // individual properties were Properties *[]string `json:"properties,omitempty"` }
A SetError is returned in set calls for individual record changes
type StateChange ¶
type StateChange struct { // This MUST be the string "StateChange" Type string `json:"@type"` // Map of AccountID to TypeState. Only changed values will be in the map Changed map[ID]TypeState `json:"changed"` }
A StateChange object is sent to the client via Push mechanisms. It communicates when a change has occurred
type TypeState ¶
TypeState is a map of Foo object names ("Mailbox", "Email", etc) to state property which would be returned by a call to Foo/get
type UploadResponse ¶
type UploadResponse struct { // The id of the account used for the call. Account ID `json:"accountId"` // The id representing the binary data uploaded. The data for this id is // immutable. The id only refers to the binary data, not any metadata. ID ID `json:"blobId"` // The media type of the file (as specified in RFC 6838, section 4.2) as // set in the Content-Type header of the upload HTTP request. Type string `json:"type"` // The size of the file in octets. Size uint64 `json:"size"` }
UploadResponse is the object returned in response to blob upload.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package mail is an implementation of JSON Metal Application Protocol (JMAP) for MAIL (RFC 8621)
|
Package mail is an implementation of JSON Metal Application Protocol (JMAP) for MAIL (RFC 8621) |
mdn
Package mdn is an implementation of RFC 9007: Handling Message Disposition Notification with the JSON Meta Application Protocol (JMAP).
|
Package mdn is an implementation of RFC 9007: Handling Message Disposition Notification with the JSON Meta Application Protocol (JMAP). |