回答編集履歴

2

固有情報の記載変更

2019/01/07 14:04

投稿

退会済みユーザー
test CHANGED
@@ -76,7 +76,7 @@
76
76
 
77
77
  // Client ID and API key from the Developer Console
78
78
 
79
- var CLIENT_ID = '<CIENT_ID>';
79
+ var CLIENT_ID = '<CLIENT ID>';
80
80
 
81
81
  var API_KEY = '<API KEY>';
82
82
 
@@ -262,7 +262,7 @@
262
262
 
263
263
  gapi.client.calendar.events.list({
264
264
 
265
- 'calendarId': 'netachilbr@gmail.com',
265
+ 'calendarId': '<カレンダーID>',
266
266
 
267
267
  'showDeleted': false,
268
268
 
@@ -366,7 +366,7 @@
366
366
 
367
367
  var claims = {
368
368
 
369
- iss: 'fdsafdsafdsafdsa@fabled-orbit-227923.iam.gserviceaccount.com',
369
+ iss: '<サービスアカウントのメールアドレス>',
370
370
 
371
371
  scope: driveScope,
372
372
 

1

コード記載

2019/01/07 14:04

投稿

退会済みユーザー
test CHANGED
@@ -1,7 +1,5 @@
1
1
  興味本位で作ってみました。
2
2
 
3
- [javascript&サービスアカウントでグーグルカレンダーにアクセス](https://drive.google.com/drive/folders/10SglBm7ep6ZjuwQPVVrNF5HkdGLNQwZP?usp=sharing)
4
-
5
3
 
6
4
 
7
5
  このやり方はサービスアカウントの情報(秘密鍵とか)丸見えです。
@@ -33,3 +31,421 @@
33
31
  一応動作確認出来たので紹介します。
34
32
 
35
33
  (gasで実装するのが一番楽だと思います。)
34
+
35
+
36
+
37
+ ```html
38
+
39
+ ファイル名:index.html
40
+
41
+ <!DOCTYPE html>
42
+
43
+ <html>
44
+
45
+ <head>
46
+
47
+ <title>Google Calendar API Quickstart</title>
48
+
49
+ <meta charset="utf-8" />
50
+
51
+ </head>
52
+
53
+ <body>
54
+
55
+ <p>Google Calendar API Quickstart</p>
56
+
57
+
58
+
59
+ <!--Add buttons to initiate auth sequence and sign out-->
60
+
61
+ <button id="authorize_button" style="display: none;">Authorize</button>
62
+
63
+ <button id="signout_button" style="display: none;">Sign Out</button>
64
+
65
+
66
+
67
+ <pre id="content" style="white-space: pre-wrap;"></pre>
68
+
69
+ <script src="bundle.js"></script>
70
+
71
+
72
+
73
+ <script type="text/javascript">
74
+
75
+
76
+
77
+ // Client ID and API key from the Developer Console
78
+
79
+ var CLIENT_ID = '<CIENT_ID>';
80
+
81
+ var API_KEY = '<API KEY>';
82
+
83
+
84
+
85
+ // Array of API discovery doc URLs for APIs used by the quickstart
86
+
87
+ var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
88
+
89
+
90
+
91
+ // Authorization scopes required by the API; multiple scopes can be
92
+
93
+ // included, separated by spaces.
94
+
95
+ var SCOPES = "https://www.googleapis.com/auth/calendar.readonly";
96
+
97
+
98
+
99
+ var authorizeButton = document.getElementById('authorize_button');
100
+
101
+ var signoutButton = document.getElementById('signout_button');
102
+
103
+
104
+
105
+ /**
106
+
107
+ * On load, called to load the auth2 library and API client library.
108
+
109
+ */
110
+
111
+ function handleClientLoad() {
112
+
113
+ gapi.load('client:auth2', initClient);
114
+
115
+ }
116
+
117
+
118
+
119
+ /**
120
+
121
+ * Initializes the API client library and sets up sign-in state
122
+
123
+ * listeners.
124
+
125
+ */
126
+
127
+ function initClient() {
128
+
129
+ gapi.client.init({
130
+
131
+ apiKey: API_KEY,
132
+
133
+ clientId: CLIENT_ID,
134
+
135
+ discoveryDocs: DISCOVERY_DOCS,
136
+
137
+ scope: SCOPES
138
+
139
+ }).then(function () {
140
+
141
+ // Listen for sign-in state changes.
142
+
143
+ //gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
144
+
145
+ gapi.client.setToken(window.accessToken);
146
+
147
+ listUpcomingEvents();
148
+
149
+
150
+
151
+ // Handle the initial sign-in state.
152
+
153
+ //updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
154
+
155
+ //authorizeButton.onclick = handleAuthClick;
156
+
157
+ //signoutButton.onclick = handleSignoutClick;
158
+
159
+ }, function(error) {
160
+
161
+ appendPre(JSON.stringify(error, null, 2));
162
+
163
+ });
164
+
165
+ }
166
+
167
+
168
+
169
+ /**
170
+
171
+ * Called when the signed in status changes, to update the UI
172
+
173
+ * appropriately. After a sign-in, the API is called.
174
+
175
+ */
176
+
177
+ function updateSigninStatus(isSignedIn) {
178
+
179
+ if (isSignedIn) {
180
+
181
+ authorizeButton.style.display = 'none';
182
+
183
+ signoutButton.style.display = 'block';
184
+
185
+ listUpcomingEvents();
186
+
187
+ } else {
188
+
189
+ authorizeButton.style.display = 'block';
190
+
191
+ signoutButton.style.display = 'none';
192
+
193
+ }
194
+
195
+ }
196
+
197
+
198
+
199
+ /**
200
+
201
+ * Sign in the user upon button click.
202
+
203
+ */
204
+
205
+ function handleAuthClick(event) {
206
+
207
+ gapi.auth2.getAuthInstance().signIn();
208
+
209
+ }
210
+
211
+
212
+
213
+ /**
214
+
215
+ * Sign out the user upon button click.
216
+
217
+ */
218
+
219
+ function handleSignoutClick(event) {
220
+
221
+ gapi.auth2.getAuthInstance().signOut();
222
+
223
+ }
224
+
225
+
226
+
227
+ /**
228
+
229
+ * Append a pre element to the body containing the given message
230
+
231
+ * as its text node. Used to display the results of the API call.
232
+
233
+ *
234
+
235
+ * @param {string} message Text to be placed in pre element.
236
+
237
+ */
238
+
239
+ function appendPre(message) {
240
+
241
+ var pre = document.getElementById('content');
242
+
243
+ var textContent = document.createTextNode(message + '\n');
244
+
245
+ pre.appendChild(textContent);
246
+
247
+ }
248
+
249
+
250
+
251
+ /**
252
+
253
+ * Print the summary and start datetime/date of the next ten events in
254
+
255
+ * the authorized user's calendar. If no events are found an
256
+
257
+ * appropriate message is printed.
258
+
259
+ */
260
+
261
+ function listUpcomingEvents() {
262
+
263
+ gapi.client.calendar.events.list({
264
+
265
+ 'calendarId': 'netachilbr@gmail.com',
266
+
267
+ 'showDeleted': false,
268
+
269
+ 'singleEvents': true,
270
+
271
+ 'maxResults': 10,
272
+
273
+ 'orderBy': 'startTime'
274
+
275
+ }).then(function(response) {
276
+
277
+ var events = response.result.items;
278
+
279
+ appendPre('Upcoming events:');
280
+
281
+
282
+
283
+ if (events.length > 0) {
284
+
285
+ for (i = 0; i < events.length; i++) {
286
+
287
+ var event = events[i];
288
+
289
+ var when = event.start.dateTime;
290
+
291
+ if (!when) {
292
+
293
+ when = event.start.date;
294
+
295
+ }
296
+
297
+ appendPre(event.summary + ' (' + when + ')')
298
+
299
+ }
300
+
301
+ } else {
302
+
303
+ appendPre('No upcoming events found.');
304
+
305
+ }
306
+
307
+ });
308
+
309
+ }
310
+
311
+
312
+
313
+ </script>
314
+
315
+
316
+
317
+ <script async defer src="https://apis.google.com/js/api.js"
318
+
319
+ onload="this.onload=function(){};handleClientLoad()"
320
+
321
+ onreadystatechange="if (this.readyState === 'complete') this.onload()">
322
+
323
+ </script>
324
+
325
+ </body>
326
+
327
+ </html>
328
+
329
+ ```
330
+
331
+
332
+
333
+ ```Node.js
334
+
335
+ ファイル名:token.js
336
+
337
+ var request = require('superagent');
338
+
339
+ var crypto = require('crypto');
340
+
341
+ var fs = require('fs');
342
+
343
+ var privateKey = require('./key.json'); // private key generated on Developer Console.
344
+
345
+ var driveScope = 'https://www.googleapis.com/auth/calendar';
346
+
347
+ var tokenEndpoint = 'https://www.googleapis.com/oauth2/v3/token';
348
+
349
+ var grantType = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
350
+
351
+
352
+
353
+ var now = Math.floor( new Date().getTime() / 1000 );
354
+
355
+
356
+
357
+ var header = {
358
+
359
+ alg: 'RS256',
360
+
361
+ typ: 'JWT'
362
+
363
+ };
364
+
365
+
366
+
367
+ var claims = {
368
+
369
+ iss: 'fdsafdsafdsafdsa@fabled-orbit-227923.iam.gserviceaccount.com',
370
+
371
+ scope: driveScope,
372
+
373
+ aud: tokenEndpoint,
374
+
375
+ exp: now + 3600, // maximum expiry date is 1 hour after the issued time.
376
+
377
+ iat: now
378
+
379
+ };
380
+
381
+
382
+
383
+ var body = {
384
+
385
+ assertion: createJWT(header, claims),
386
+
387
+ grant_type: grantType
388
+
389
+ }
390
+
391
+
392
+
393
+ // send request to get access token
394
+
395
+ window.accessToken;
396
+
397
+ request.post(tokenEndpoint)
398
+
399
+ .set('Content-Type', 'application/x-www-form-urlencoded') // you must set this header.
400
+
401
+ .send(body)
402
+
403
+ .end(function(err, res){
404
+
405
+ accessToken= res.body.access_token;
406
+
407
+ });
408
+
409
+
410
+
411
+
412
+
413
+ function createJWT(header, claims) {
414
+
415
+ var encodedHeader = new Buffer(JSON.stringify(header)).toString('base64');
416
+
417
+ var encodedClaims = new Buffer(JSON.stringify(claims)).toString('base64');
418
+
419
+ var sign = crypto.createSign('RSA-SHA256');
420
+
421
+ var data = new Buffer(encodedHeader + '.' + encodedClaims);
422
+
423
+
424
+
425
+ sign.update(data);
426
+
427
+ signature = sign.sign(new Buffer(privateKey.private_key), 'base64');
428
+
429
+
430
+
431
+ // JWT format is '{base64 encoded header}.{base64 encoded claims}.{signature}'
432
+
433
+ return [encodedHeader, encodedClaims, signature].join('.');
434
+
435
+ }
436
+
437
+
438
+
439
+ ```
440
+
441
+ ```json
442
+
443
+ ファイル名:key.json
444
+
445
+ サービスアカウント作成でダウンロードできる秘密鍵情報
446
+
447
+ ```
448
+
449
+ ノードモジュール:crypto, superagent
450
+
451
+ 補足:token.jsは次のコマンドで変換「browserify token.js -o bundle.js」