The CreatorCon Call for Content is officially open! Get started here.

Google Calendarとの統合で、カレンダーの作成が反映されない

Ereshkigal
Tera Contributor

コミュニティの皆様
いつもお世話になっております。

私はGoogle Cloud Platformのサービスアカウントキーを使用して、
ServiceNowからGoogle Calaendarへの接続調査が完了し、
追加でServiceNowからカレンダーが作成できるかを調査しています。

私はServiceNow上で以下のScheduled Job(を作成し、
新しいカレンダーとイベントの作成を試みました。
※テストとログ確認のためにバックグラウンドスクリプトで実行しています。

ServiceNowのログを見る限りでは、成功されているように感じますが、
実際のGoogle Calendarには反映されていませんでした。

原因についてお心当たりがある方はいらっしゃいますでしょうか。
また以下気になっている箇所がありますが、これらの原因と関係ありますでしょうか。
お手数ですが、知見がある方はご教示をお願いいたします。

  • Google Cloud Platformでは個人アカウント(Gmail)を使用している
  • Gsuiteアカウント(管理者アカウント)を持っていない
  • 認証情報にSub属性を追加していない(Sub属性にはGsuiteアカウントが必要?)

皆様のご協力よろしくお願いいたします。

Scheduled Job:

function createCalendar() {
    var calendar = {
        'summary': "ServiceNow",
        'timeZone': 'Asia/Tokyo'
    };

    var rm = new sn_ws.RESTMessageV2('Google Calendar JSON', 'Calendar');
    rm.setRequestBody(JSON.stringify(calendar));
    var res = rm.execute();
    return res;
}

function extractCalendarID(c) {
    var res = c.getBody(); //作成したカレンダー情報を抽出する
    gs.info("res:" + res);
    var rem = JSON.parse(res);
    var ram = rem.id;
	gs.lnfo("ram.id:" + ram.id);
    return ram;
}

function createEvent(cid) {
    var event = {
        "summary": "テスト",
        'description': '予定を作成できるか',
        "start": {
			"dateTime":"2022-06-28T09:00:00-07:00"
        },
		"end":{
			"dateTime": "2022-06-28T17:00:00-07:00"
		}
    };
	
	var rm = new sn_ws.RESTMessageV2('Google Calendar JSON', 'Calendar');
	rm.setRequestBody(JSON.stringify(event));
	rm.setEndpoint("https://www.googleapis.com/calendar/v3/calendars/" + cid + "/events");
	var response = rm.execute();
	var responseBody = response.getBody();
	var httpStatus = response.getStatusCode();
	gs.info("responseBody:" + responseBody);
	gs.info("HTTPSTATUS" + httpStatus);
}
var c = createCalendar();
var cid = extractCalendarID(c);
createEvent(cid);

 

Result:

*** Script: res:{
 "kind": "calendar#calendar",
 "etag": "\"5x0OFcSKv08yoFIPbccYDwt0IsU\"",
 "id": "o36pu1f62hhpiomf2chdkm63ak@group.calendar.google.com",
 "summary": "ServiceNow",
 "timeZone": "Asia/Tokyo"
}
*** Script: responseBody:{
 "kind": "calendar#event",
 "etag": "\"3312927523576000\"",
 "id": "a3ojp01nessc78kmqrqc3cov2o",
 "status": "confirmed",
 "htmlLink": "https://www.google.com/calendar/event?eid=YTNvanAwMW5lc3NjNzhrbXFycWMzY292Mm8gbzM2cHUxZjYyaGhwaW9tZjJjaGRrbTYzYWtAZw",
 "created": "2022-06-29T00:49:21.000Z",
 "updated": "2022-06-29T00:49:21.788Z",
 "summary": "テスト",
 "description": "予定を作成できるか",
 "creator": {
  "email": "galendar@instant-land-353301.iam.gserviceaccount.com"
 },
 "organizer": {
  "email": "o36pu1f62hhpiomf2chdkm63ak@group.calendar.google.com",
  "displayName": "ServiceNow",
  "self": true
 },
 "start": {
  "dateTime": "2022-06-29T01:00:00+09:00",
  "timeZone": "UTC"
 },
 "end": {
  "dateTime": "2022-06-29T09:00:00+09:00",
  "timeZone": "UTC"
 },
 "iCalUID": "a3ojp01nessc78kmqrqc3cov2o@google.com",
 "sequence": 0,
 "reminders": {
  "useDefault": true
 },
 "eventType": "default"
}
*** Script: HTTPSTATUS200

Google Calendar

find_real_file.png

 

1 ACCEPTED SOLUTION

  1. Q、 こちらは仕様になるのでしょうか。(ServiceNowで共有設定してもカレンダーが自動で表示されるわけではない?)
    1. A、 仕様だと思います。私も試しましたが自動ではなく、カレンダーが共有設定されたことのメール通知がきて、そのリンクをクリックすることで追加するかどうかの選択肢が出てきて『追加』の選択をすると他のカレンダーに追加できました。『〇〇〇さんがあなたとカレンダーを共有しました』のメールです。
      Googleカレンダーの予定共有方法を解説!トラブルシューティングから他ツール・デバイスとの同期方法まで - NotePM
  2. Q、 共有設定に加えて、ServiceNowもしくはGoogle Calendarの設定でカレンダーを自動で表示させることは可能でしょうか。
    1. A、 他人が設定したカレンダーの共有を自動で自分のカレンダーリストに登録する機能は、調べてみた限りはなさそうです。これらはGoogle カレンダーの使い方になるので、別で有識者に聞いたほうが良いかもしれません。
      なお、送られてきた予定を自動で追加する方法ならあるようです。
      『Google カレンダーの設定で [Gmail からの予定] に移動し、[Gmail から自動的に作成された予定をカレンダーに表示する] チェックボックスをオンにします。』
      Gmail から予定を自動的に追加する - Google Workspace ラーニング センター
    2. 『〇〇〇さんがあなたとカレンダーを共有しました』のメールで、明確にユーザーの確認を取ってから追加するのが良い仕様だと思います。
    3. 今回のサービスアカウントを使用した方法では、カレンダー所有ユーザーのリソースにアクセス権があればCalendarAPIで自動でリストに追加して表示できます。
      カレンダーユーザーが組織やグループに所属するなら、サービスアカウントに組織全体やグループにアクセスする権限を設定できます。
      これらは Google Workspace を利用になります。
      API アクセスをドメイン全体の委任で制御する - Google Workspace 管理者 ヘルプ
      管理コンソールについて - Google Workspace 管理者 ヘルプ

      Google Workspace ではない、個人としてカレンダー所有ユーザーのアクセスするには、そのユーザーとしてOAuth認証することで、カレンダーリストに追加できます。
      1. ウェブサーバーアプリケーション
        OAuth 2.0 を使用した Google API へのアクセス  |  Google Identity Platform  |  Google Developers
        認証シーケンスは、アプリケーションがブラウザを Google URL にリダイレクトするときに始まります。URL には、リクエストされているアクセスの種類を示すクエリ パラメータが含まれています。Google がユーザー認証、セッション選択、ユーザーの同意を処理します。その結果、アプリケーションがアクセス トークンや更新トークンと交換できる認証コードが生成されます。

      2. カレンダーリスト: |の挿入Google カレンダー API |グーグルデベロッパー
        既存の予定表をユーザーの予定表リストに挿入します。

 

View solution in original post

6 REPLIES 6

iwai
Giga Sage

表示しているカレンダー(ユーザーのリソース)にアクセスするには”sub”を使用します。

Googleの公式ページに記載があります。

サーバー間アプリケーションに OAuth 2.0 を使用する  |  Google Identity Platform  |  Google Developers

その他の申し立て

企業によっては、アプリケーションがドメイン全体の委任を使用して、組織内の特定のユーザーのために動作することもできます。別のユーザーに成り代わる権限は、アプリケーションがユーザーになりすます前に付与する必要があります。通常は特権管理者が処理します。詳しくは、ドメイン全体の委任で API アクセスを制御するをご覧ください。

リソースへの委任アクセス権をアプリケーションに付与するアクセス トークンを取得するには、JWT クレームのユーザーのメールアドレスを sub フィールドの値として設定します。

名前 Description
sub アプリケーションが委任アクセスをリクエストしているユーザーのメールアドレス。

ユーザーに成り代わる権限がアプリケーションにない場合、sub フィールドを含むアクセス トークン リクエストに対するレスポンスはエラーになります。

Ereshkigal
Tera Contributor

ご回答ありがとうございます。

ドメイン全体の委任の設定は管理者アカウントが必要だと記載がありますが、どのようにアカウントを取得するのでしょうか。(どこにも記載がなかったです。。Google Work Spaceが必要?)

よろしくお願いいたします。

 

もし Google Workspace をご利用ではない、個人としてGoogle Cloudを利用でしたら、ドメイン全体の委任は出来ないと思います。
組織であるなら、サービスアカウントに組織全体の委任をして、組織内の別のユーザーのリソースにアクセスできます。

個人のカレンダーを変更したいのであれば、サービスアカウントではなく、ユーザーとしてOAuth認証をすると良いです。これで明確に個人として認証され個人のリソースにアクセスできます。

もうひとつの方法は、サービスアカウントの所有するカレンダーの共有設定をする。この方法なら、サービスアカウントが所有するのでアクセスできますし、共有設定に第三者を追加していけばみんなで見ることができます。共有設定を変更する方法は公式ページを参照してください。Acl: insert  |  Google Calendar API  |  Google Developers

例えば下記のようなScriptになります。AccessTokenやCalendarIDは環境に合わせて設定してください。(CalendarIDはサービスアカウントで作成したカレンダーのIDを使います。質問投稿時のログにもCalendarIDは記載されています)

var calendarACL = {
    'role': 'reader', // 読み取り権限
    'scope': {
        'type': 'user',
        'value': '*********@example.com' // 特定のユーザーを共有に追加する
    }
}
var accessToken = '*********'; // アクセストークン
var calendarId = '********@group.calendar.google.com'; // カレンダーID
var request = new sn_ws.RESTMessageV2();
request.setEndpoint('https://www.googleapis.com/calendar/v3/calendars/' + calendarId + '/acl');
request.setHttpMethod('POST');
request.setRequestHeader("Authorization", "Bearer " + accessToken);
request.setRequestBody(JSON.stringify(calendarACL));
var response = request.execute();
responseBody = response.getBody();
gs.info(responseBody);

Ereshkigal
Tera Contributor

上記についてご連携頂き、ありがとうございます。
大変役立ちました!

>サービスアカウントの所有するカレンダーの共有設定をする。

こちらの方法をHTTPメソッドのTESTで試験的に実施してみました。
find_real_file.png

Result:
find_real_file.png

ただこれだけでは私のGoogle Calendarにカレンダーは作成されませんでした。Google Calendar側で「カレンダーに追加」>「カレンダーに登録」でカレンダーIDを入力すると、カレンダーが追加されました。
→2点確認ですが、

  1. こちらは仕様になるのでしょうか。(ServiceNowで共有設定してもカレンダーがj自動で表示されるわけではない?)
  2. 共有設定に加えて、ServiceNowもしくはGoogle Calendarの設定でカレンダーを自動で表示させることは可能でしょうか。

find_real_file.png

find_real_file.png

 

お手数をおかけして、大変恐縮ではございますが、
何卒宜しくお願い致します。