-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathREADME.txt
More file actions
295 lines (202 loc) · 12 KB
/
README.txt
File metadata and controls
295 lines (202 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
NAME
WebService::GoogleAPI::Client - Google API Discovery and SDK
VERSION
version 0.21
SYNOPSIS
Access Google API Services Version 1 using an OAUTH2 User Agent.
Includes Discovery, validation authentication and API Access.
assumes gapi.json configuration in working directory with scoped Google
project redentials and user authorization created by _goauth_
use WebService::GoogleAPI::Client;
my $gapi_client = WebService::GoogleAPI::Client->new( debug => 1, gapi_json => 'gapi.json', user=> 'peter@pscott.com.au' );
say $gapi_client->list_of_available_google_api_ids();
my @gmail_endpoint_list = $gapi_client->methods_available_for_google_api_id('gmail')
if $gapi_agent->has_scope_to_access_api_endpoint( 'gmail.users.settings.sendAs.get' ) {
say 'User has Access to GMail Method End-Point gmail.users.settings.sendAs.get';
}
Internal User Agent provided be property
WebService::GoogleAPI::Client::UserAgent dervied from Mojo::UserAgent
Package includes go_auth CLI Script to collect initial end-user
authorisation to scoped services
EXAMPLES
AUTOMATIC API REQUEST CONSTRUCTION - SEND EMAL
## using dotted API Endpoint id to invoke helper validation and default value interpolations etc to send email to self
use Email::Simple; ## RFC2822 formatted messages
use MIME::Base64;
my $my_email_address = 'peter@shotgundriver.com'
my $raw_email_payload = encode_base64( Email::Simple->create( header => [To => $my_email_address,
From => $my_email_address,
Subject =>"Test email from '$my_email_address' ",],
body => "This is the body of email to '$my_email_address'",
)->as_string
);
$gapi_client->api_query(
api_endpoint_id => 'gmail.users.messages.send',
options => { raw => $raw_email_payload },
);
MANUAL API REQUEST CONSTRUCTION - GET CALENDAR LIST
## Completely manually constructed API End-Point Request to obtain Perl Data Structure converted from JSON response.
my $res = $gapi_client->api_query(
method => 'get',
path => 'https://www.googleapis.com/calendar/users/me/calendarList',
)->json;
METHODS
new
WebService::GoogleAPI::Client->new( user => 'peter@pscott.com.au', gapi_json => '/fullpath/gapi.json' );
PARAMETERS
user :: the email address that identifies key of credentials in the
config file
gapi_json :: Location of the configuration credentials - default
gapi.json
debug :: if '1' then diagnostics are send to STDERR - default false
chi :: an instance to a CHI persistent storage case object - if none
provided FILE is used
api_query
query Google API with option to validate request before submitting
handles user auth token inclusion in request headers and refreshes
token if required and possible
Required params: method, route
Optional params: api_endpoint_id cb_method_discovery_modify
$self->access_token must be valid
$gapi->api_query({
method => 'get',
path => 'https://www.googleapis.com/calendar/users/me/calendarList',
});
$gapi->api_query({
method => 'post',
path => 'https://www.googleapis.com/calendar/v3/calendars/'.$calendar_id.'/events',
options => { key => value }
}
## if provide the Google API Endpoint to inform pre-query validation
say $gapi_agent->api_query(
api_endpoint_id => 'gmail.users.messages.send',
options => { raw => encode_base64(
Email::Simple->create( header => [To => $user, From => $user, Subject =>"Test email from $user",],
body => "This is the body of email from $user to $user", )->as_string
),
},
)->to_string; ##
print $gapi_agent->api_query(
api_endpoint_id => 'gmail.users.messages.list', ## auto sets method to GET, path to 'https://www.googleapis.com/calendar'
)->to_string;
#print pp $r;
if the pre-query validation fails then a 418 - I'm a Teapot error response is returned with the
body containing the specific description of the errors ( Tea Leaves ;^) ).
NB: If you pass a 'path' parameter this takes precendence over the API
Discovery Spec. Any parameters defined in the path of the format
{VARNAME} will be filled in with values within the options=>{ VARNAME
=> 'value '} parameter structure. This is the simplest way of
addressing issues where the API discovery spec is inaccurate. ( See
dev_sheets_example.pl as at 14/11/18 for illustration )
To allow the user to fix discrepencies in the Discovery Specification
the cb_method_discovery_modify callback can be used which must accept
the method specification as a parameter and must return a (potentially
modified) method spec.
eg.
my $r = $gapi_client->api_query( api_endpoint_id => "sheets:v4.spreadsheets.values.update",
options => {
spreadsheetId => '1111111111111111111',
valueInputOption => 'RAW',
range => 'Sheet1!A1:A2',
'values' => [[99],[98]]
},
cb_method_discovery_modify => sub {
my $meth_spec = shift;
$meth_spec->{parameters}{valueInputOption}{location} = 'path';
$meth_spec->{path} = "v4/spreadsheets/{spreadsheetId}/values/{range}?valueInputOption={valueInputOption}";
return $meth_spec;
}
);
Returns Mojo::Message::Response object
has_scope_to_access_api_endpoint
Given an API Endpoint such as 'gmail.users.settings.sendAs.get' returns
1 iff user has scope to access
say 'User has Access' if $gapi_agent->has_scope_to_access_api_endpoint( 'gmail.users.settings.sendAs.get' );
Returns 0 if scope to access is not available to the user.
warns and returns 0 on error ( eg user or config not specified etc )
METHODS DELEGATED TO WebService::GoogleAPI::Client::Discovery
discover_all
Return details about all Available Google APIs as provided by Google or in CHI Cache
On Success: Returns HASHREF containing items key => list of hashes describing each API
On Failure: Warns and returns empty hashref
my $client = WebService::GoogleAPI::Client->new; ## has discovery member WebService::GoogleAPI::Client::Discovery
$d = $client->discover_all();
$d = $client->discover_all(1); ## NB if include a parameter that evaluates to true such as '1' then the cache is flushed with a new version
## OR
$d = $client->discovery-> discover_all();
$d = WebService::GoogleAPI::Client::Discovery->discover_all();
print Dumper $d;
$VAR1 = {
'items' => [
{
'preferred' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
'id' => 'abusiveexperiencereport:v1',
'icons' => {
'x32' => 'https://www.gstatic.com/images/branding/product/1x/googleg_32dp.png',
'x16' => 'https://www.gstatic.com/images/branding/product/1x/googleg_16dp.png'
},
'version' => 'v1',
'documentationLink' => 'https://developers.google.com/abusive-experience-report/',
'kind' => 'discovery#directoryItem',
'discoveryRestUrl' => 'https://abusiveexperiencereport.googleapis.com/$discovery/rest?version=v1',
'title' => 'Abusive Experience Report API',
'name' => 'abusiveexperiencereport',
'description' => 'Views Abusive Experience Report data, and gets a list of sites that have a significant number of abusive experiences.'
}, ...
## NB because the structure isn't indexed on the api name it can be convenient to post-process it
##
my $new_hash = {};
foreach my $api ( @{ %{$client->discover_all()}{items} } )
{
# convert JSON::PP::Boolean to true|false strings
$api->{preferred} = "$api->{preferred}" if defined $api->{preferred};
$api->{preferred} = $api->{preferred} eq '0' ? 'false' : 'true';
$new_hash->{ $api->{name} } = $api;
}
print dump $new_hash->{gmail};
get_api_discovery_for_api_id
returns the cached version if avaiable in CHI otherwise retrieves
discovery data via HTTP, stores in CHI cache and returns as a Perl data
structure.
my $hashref = $self->get_api_discovery_for_api_id( 'gmail' );
my $hashref = $self->get_api_discovery_for_api_id( 'gmail:v3' );
returns the api discovery specification structure ( cached by CHI ) for
api id ( eg 'gmail ')
returns the discovery data as a hashref, an empty hashref on certain
failing conditions or croaks on critical errors.
methods_available_for_google_api_id
Returns a hashref keyed on the Google service API Endpoint in dotted
format. The hashed content contains a structure representing the
corresponding discovery specification for that method ( API Endpoint ).
methods_available_for_google_api_id('gmail')
extract_method_discovery_detail_from_api_spec
$my $api_detail = $gapi->discovery->extract_method_discovery_detail_from_api_spec( 'gmail.users.settings' );
returns a hashref representing the discovery specification for the
method identified by $tree in dotted API format such as
texttospeech.text.synthesize
returns an empty hashref if not found
list_of_available_google_api_ids
Returns an array list of all the available API's described in the API
Discovery Resource that is either fetched or cached in CHI locally for
30 days.
my $r = $agent->list_of_available_google_api_ids();
print "List of API Services ( comma separated): $r\n";
my @list = $agent->list_of_available_google_api_ids();
FEATURES
* API Discovery requests cached with CHI ( Default File )
* OAUTH app and user credentials (client_id, client_secret, scope,
users access_token and refresh_tokens) stored in local file (default
name = gapi.json)
* access_token auto-refreshes when expires (if user has
refresh_token) saving refreshed token back to json file
* helper api_query to streamline request composition without
preventing manual construction if preferred.
* CLI tool (goauth) with lightweight Mojo HTTP server to simplify
OAuth2 configuration, sccoping, authorization and obtaining access_
and refresh_ tokens from users
AUTHOR
Peter Scott <localshop@cpan.org>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2017-2018 by Peter Scott and others.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004