1Mail::JMAPTalk(3) User Contributed Perl Documentation Mail::JMAPTalk(3)
2
3
4
6 Mail::JMAPTalk - Basic interface to talk to JMAP Servers
7
9 Version 0.15
10
12 Mail::JMAPTalk was originally written as a very small wrapper around
13 HTTP::Tiny to talk to a JMAP server and mapping between Perl hashes and
14 JSON on the wire.
15
16 It doesn't do anything smart with specific JMAP objects.
17
18 Example:
19
20 use Mail::JMAPTalk;
21 use JSON;
22
23 # using basic auth
24 my $jtalk = Mail::JMAPTalk->new(
25 url => "https://jmap.example.com/",
26 user => "foo\@example.com",
27 password => "letmein",
28 );
29
30 # using non-standard JMAPAuth token establishment
31 my $jtalk = Mail::JMAPTalk->new(
32 url => "https://jmap.example.com/",
33 );
34 $jtalk->Login("foo\@example.com", "letmein");
35
36 my $res = $jtalk->Call('Mailbox/get');
37 my %byname = map { $_->{name} -> $_->{id} } @{$res->{ids});
38
39 my $data = $jtalk->Upload($emailbytes, 'message/rfc822');
40 $res = $jtalk->CallMethods([['Email/import', {
41 emails => {
42 "1" => {
43 blobId => $data->{blobId},
44 keywords => { '$seen' => JSON::true },
45 mailboxIds => { $byname{Inbox} => JSON::true },
46 },
47 },
48 }, "R1"], ["Email/get", { ids => ["#1"] }, "R2" ]]);
49 # all properties of the email in $res->[1][1]{list}[0]
50
51 my $response = $jtalk->Download($res->[1][1]{accountId}, $data->{blobId});
52
54 $class->new(%Options)
55 Create a new Mail::JMAPTalk object.
56
57 Takes options for a variety of purposes:
58
59 Override the UserAgent used for all connections:
60
61 * ua => HTTP::Tiny->new(...)
62
63 Host Options:
64
65 * scheme => 'http' or 'https' (default 'http')
66 * host => hostname (default 'localhost')
67 * port => port number (default 443 for https, otherwise 80)
68
69 URI Options: (absolute URI, or use options above to set the scope)
70
71 * authurl => auth endpoint (default '/jmap/auth/')
72 * uploadurl => upload endpoint (default '/jmap/upload/{accountId}/')
73 * downloadurl => download endpoint (default '/jmap/download/{accountId}/{blobId}/{name}')
74 * url => JMAP API endpoint (default '/jmap/')
75
76 Authentication Options: (basic auth)
77
78 * user => $username
79 * password => $password
80
81 Request Defaults:
82
83 * using => \@urns (default ['urn:ietf:params:jmap:core', 'urn:ietf:params:jmap:mail'])
84
85 my $ua = $Self->ua();
86 $Self->ua($setua);
87 Get or set the useragent (HTTP::Tiny or compatible) that will be used
88 to make the requests:
89
90 e.g.
91
92 my $ua = $Self->ua();
93
94 $Self->ua(HTTP::Tiny->new(agent => "MyAgent/1.0", timeout => 5));
95
96 my $header = $Self->auth_header();
97 Returns the basic-auth value for the 'Authentication' header.
98
99 my $uri = $Self->authuri();
100 Returns the URI for JMAPAuth authentication (non-standard). Default
101 depends on the parameters passed to new. Most simple would be:
102
103 http://localhost/jmap/auth/
104
105 my $uri = $Self->uploaduri($accountId);
106 Returns the URI for JMAP uploads. Default depends on the parameters
107 passed to new. Most simple would be:
108
109 http://localhost/jmap/upload/${accountId}/
110
111 my $uri = $Self->downloaduri($accountId, $blobId, $name);
112 Returns the URI for JMAP downloads. Default depends on the parameters
113 passed to new. Most simple would be:
114
115 http://localhost/jmap/download/${accountId}/${blobId}/{$name}
116
117 Where name is utf8 and uri encoded to be safe.
118
119 my $uri = $Self->uri()
120 Returns the URI for JMAP API Calls. Default depends on the parameters
121 passed to new. Most simple would be:
122
123 http://localhost/jmap/
124
125 my $uri = $Self->JSONPOST($Uri, $Request, %Headers)
126 Makes a POST request to the given URI with the body being the value of
127 $Request (which must be a reference) encoded as JSON, and with the
128 Headers added.
129
130 Will set Content-Type and Accept headers to 'application/json' unless
131 overridden.
132
133 Generally you won't call this directly, but through one of the helper
134 methods.
135
136 This method will die if the response is not successful or does not
137 contain valid json.
138
139 $Self->AuthRequest($Request, %Headers)
140 Makes a JSONPOST request to the authurl.
141
142 $Self->Login($Username, $Password)
143 Uses the non-standard JMAPAuth protocol to login.
144
145 On success will set the upload, download and api urls as well as a
146 token which is used to authenticate all further requests.
147
148 On failure will die.
149
150 $Self->Request($Request, %Headers)
151 Makes a JSONPOST request to the API url, authenticated with either the
152 basic auth parameters given at creation, or the token obtained via
153 Login.
154
155 my $using = $Self->DefaultUsing()
156 $Self->DefaultUsing(\@urns)
157 Returns or replaces the default 'using' value for method calls.
158
159 $Self->AddUsing(@urns)
160 Appends any urns given to the default 'using' if they aren't already
161 registered.
162
163 $Self->CallMethods($MethodCalls, $Using, %Headers)
164 Generates a JMAP request from the given method calls, optionally
165 overriding the using and header values.
166
167 MethodCalls is an array of arrays, each of the sub arrays is a single
168 "Invocation" per RFC8620 as follows:
169
170 3.2. The Invocation Data Type
171
172 Method calls and responses are represented by the *Invocation* data
173 type. This is a tuple, represented as a JSON array containing three
174 elements:
175
176 1. A "String" *name* of the method to call or of the response.
177
178 2. A "String[*]" object containing named *arguments* for that method
179 or response.
180
181 3. A "String" *method call id*: an arbitrary string from the client
182 to be echoed back with the responses emitted by that method call
183 (a method may return 1 or more responses, as it may make implicit
184 calls to other methods; all responses initiated by this method
185 call get the same method call id in the response).
186
187 In perl, this is [string, hashref, string].
188
189 Example:
190
191 my $res = $jtalk->CallMethods([
192 ['Email/query', { }, 'R1'],
193 ['Email/get', {
194 '#ids' => {
195 resultOf => 'R1',
196 name => 'Email/query',
197 path => '/ids'
198 },
199 properties => [ 'subject', 'header:x-mood:asText', 'from', 'to' ],
200 }, 'R2'],
201 ]);
202
203 The response is an arrayref containing the value of methodResponses
204 from the JSON reply defined in JMAP.
205
206 This method will die if the server returns an error or invalid JSON.
207
208 $Self->Call($Method, $Params, $Using, %Headers)
209 A convenience method to call a single method. This method generates a
210 single invocation with call id 'c1' and will return undef unless the
211 first response from the server has the same method name (i.e. is not an
212 error) and the same call id.
213
214 The return value is the response section (middle field) of the first
215 methodResponse Invocation object.
216
217 Example:
218
219 my $res = $jtalk->Call('Calendar/get', { properties => ['name'] });
220 my %byname = map { $_->{name} => $_->{id} } @{$res->{list}};
221
222 $Self->Upload($data, $mimetype, $accountId)
223 Uploads the bytes in $data with either the given mimetype or if the
224 mimetype is not given, the type picked by File::LibMagic.
225
226 The POST request is authenticated with either the basic auth parameters
227 given at creation, or the token obtained via Login.
228
229 If called in scalar context, will die unless the request was successful
230 - and returns a hashref with the content returned by the server as
231 defined in RFC8620:
232
233 A successful request MUST return a single JSON object with the
234 following properties as the response:
235
236 o accountId: "Id"
237
238 The id of the account used for the call.
239
240 o blobId: "Id"
241
242 The id representing the binary data uploaded. The data for this
243 id is immutable. The id *only* refers to the binary data, not any
244 metadata.
245
246 o type: "String"
247
248 The media type of the file (as specified in [RFC6838],
249 Section 4.2) as set in the Content-Type header of the upload HTTP
250 request.
251
252 o size: "UnsignedInt"
253
254 The size of the file in octets.
255
256 If called in array context, returns two values - the first is the raw
257 HTTP::Tiny response hash, and the second is the JSON as above.
258
259 Example:
260
261 my ($Response, $data) = $jtalk->Upload($bytes);
262 if ($Response->{success}) {
263 say "Uploaded $data->{size} bytes as $data->{blobId}";
264 ...
265 }
266
267 $Self->Download($cb?, $Headers?, $accountId, $blobId, $name)
268 Makes a GET request authenticated with either the basic auth parameters
269 given at creation, or the token obtained via Login.
270
271 If the first argument is a code reference, it will be shifted and used
272 as the data_callback (see HTTP::Tiny).
273
274 Then - if the first argument is a hash reference, it will be shifted
275 and used as additional headers.
276
277 Then - the remaining parameters are passed to $Self->downloadurl() to
278 generate the link to download.
279
280 The response is a HTTP::Tiny Response object.
281
282 Example:
283
284 my $res = $jtalk->Download($accountId, $data->{blobId}, "image.gif");
285 if ($res->{success}) {
286 open(FH, ">image.gif");
287 print FH $res->{content};
288 close(FH);
289 }
290
292 If the environment variable DEBUGJMAP is set to a true value, all API
293 requests and responses plus Upload responses will be warn()ed.
294
296 https://jmap.io/ - protocol documentation and client guide.
297
299 Bron Gondwana, <brong@>
300
302 Copyright (C) 2015-2020 by Fastmail Pty Ltd.
303
304 This library is free software; you can redistribute it and/or modify it
305 under the same terms as Perl itself, either Perl version 5.20.1 or, at
306 your option, any later version of Perl 5 you may have available.
307
308
309
310perl v5.32.0 2020-07-28 Mail::JMAPTalk(3)