適材適所

PowerShellやVBAなどのプログラミングに関すること、キャリア、子育ての3本で書いていきます

PowerShellでGoogle APIを使ってGoolgeカレンダーを操作する

Googleカレンダー、便利ですよね。

私はGoogleカレンダーでスケジュール管理をしています。

これがないと平気で用事を忘れ、妻に怒られます。

そんなGoogleカレンダーをPowerShellを使って操作できたらいいなと思いませんか?

そんなことできるわけ・・・いえ、できるんです。

そう、Google Calendar APIならね。

Google様は私みたいな愚民のために、色々なAPIを用意してくれています。

しかも無料で使えるものも多数!!

どんなAPIがあるか知りたい人は、Google APIのページをご覧ください。

っと、なんだかGoogleの宣伝みたいになってしまいましたが、決してGoogleの回し者ではありません。

Googleカレンダーに話を戻しましょう。

今回は、Google APIを使ってPowerShellからGoogleカレンダーを操作する方法を紹介したいと思います。

Googleカレンダー APIのページを見てみると、JavaやPythonなど、主要な言語でGoogleカレンダーAPIを使うためのサンプルが載っています。

サンプルは、Googleカレンダーから予定を10個参照し、コンソールに書き出すという単純なものです。

サンプルは単純なものですが、これさえ理解できれば、これを足掛かりにPowerShellでGoogleカレンダーを扱うちょっとしたアプリを作ることも可能です。

PowerShellの場合は、.NETの例を参考にします。

てっとり早くコードをだけ知りたい人は⇒コードの全体

事前準備

Google APIを使う場合、まず、Google APIのキーを取得する必要があります。

先ほどの.NETの例のページの「Enable the Google Calendar API」をクリックします。

f:id:shinmai_papa:20200630060140p:plain

保存したキーは、ここでは「credentials.json」という名前で、これから作るスクリプトと同じフォルダに保存します。

サンプルを参考にしてみる

先ほどの.NETの例を見てもらうと、コードはC#で書かれていますね。

そのため、PowerShellではこのサンプルにひと手間加え、PowerShell用に改造してあげる必要があります。

やらねばならぬことは次の3つ。

  1. Google API用のdllをダウンロードする
  2. ダウンロードしたdllをインポートする
  3. サンプルをPowerShellの文法で書き直す

ひとつずつ見ていきましょう。

環境

  1. OS Windows10 pro (10.0.18362)
  2. PSVersion 5.1.18362.145
  3. Google API Version 1.46.0(この記事を書いた時点(2020/6/29)の最新Version)
  4. .NET Version 4.5

Google API用のdllをダウンロードする

Google APIはパッケージマネージャのNugetからダウンロードします。

現時点(2020/6/29)の最新のGoogleカレンダー APIはv3になります。

Nuget GallaryのGoogle.Apis.Calendar.V3のページを見てみます。

インストールコマンドが載っていますが、これをそのまま実行してみても依存関係の解決で失敗するので、自分で依存関係を解決してある必要があります。

依存関係は先ほどのページのDependenciesに書いてます。

.NET4.5だとGoogle.ApisとGoogle Apis.Authに依存していることがわかります。

f:id:shinmai_papa:20200629140356p:plain

このようにどんどん辿っていくと、

  • Newtonsoft.Json
  • Google.Apis.Core
  • Google.Apis
  • Google.Apis.Auth
  • Google.Apis.Calendar.v3

という順番で依存していることがわかります。

あとは、先ほどの5つをInstall-Package コマンドでインストールすればOKです。

その際、バージョンの指定を忘れないでください。ここではさらにユーザーとダウンロード先のフォルダを指定しています。

管理者権限がある場合は、-Scope CurrentUser オプションは外しても大丈夫かと思います。

また、-SkipDependencies オプションについては、依存関係がうまく解決されないため加えています。

$dir="任意のディレクトリ"
Install-Package Newtonsoft.Json -Source nuget -Scope CurrentUser -SkipDependencies -Destination $dir -RequiredVersion "12.0.3"
Install-Package Google.Apis.Core -Source nuget -Scope CurrentUser -SkipDependencies -Destination $dir -RequiredVersion "1.46.0"
Install-Package Google.Apis -Source nuget -Scope CurrentUser -SkipDependencies -Destination $dir -RequiredVersion "1.46.0"
Install-Package Google.Apis.Auth -Source nuget -Scope CurrentUser -SkipDependencies -Destination $dir -RequiredVersion "1.46.0"
Install-Package Google.Apis.Calendar.v3 -Source nuget -Scope CurrentUser -SkipDependencies -Destination $dir -RequiredVersion "1.46.0.1986"

ダウンロードしたdllをインポートする

先ほどのdllたちをインポートしてあげます。

インポートには、Add-Typeコマンドを使います。

.NETのバージョンは4.5なので、ダウンロードされたフォルダの中のnet45のものを使います。

また、定数を使うことになるので、-ReferencedAssembliesオプションで、dllと同じフォルダにあるxmlも追加しておきます。

Add-Type -path (Join-Path $dir "Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll") -ReferencedAssemblies (Join-Path $dir "Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.xml")
Add-Type -path (Join-Path $dir "Google.Apis.Core.1.46.0\lib\net45\Google.Apis.Core.dll") -ReferencedAssemblies (Join-Path $dir "Google.Apis.Core.1.46.0\lib\net45\Google.Apis.Core.xml")
Add-Type -path (Join-Path $dir "Google.Apis.1.46.0\lib\net45\Google.Apis.dll") -ReferencedAssemblies (Join-Path $dir "Google.Apis.1.46.0\lib\net45\Google.Apis.xml")
Add-Type -path (Join-Path $dir "Google.Apis.Auth.1.46.0\lib\net45\Google.Apis.Auth.dll") -ReferencedAssemblies (Join-Path $dir "Google.Apis.Auth.1.46.0\lib\net45\Google.Apis.Auth.xml")
Add-Type -path (Join-Path $dir "Google.Apis.Calendar.v3.1.46.0.1986\lib\net45\Google.Apis.Calendar.v3.dll") -ReferencedAssemblies (Join-Path $dir "Google.Apis.Calendar.v3.1.46.0.1986\lib\net45\Google.Apis.Calendar.v3.xml")

サンプルをPowerShellの文法で書き直す

ここまで来れば、あとはサンプルをPowerShellっぽく書き直すだけです。

.NETの例とにらめっこしながら書き直します。

コードの全体

そして完成したのがこちら。

一部エラーの挙動や、dllのダウンロード、インポートを簡略化しています。

これをテキストエディタに貼って、~~.ps1という名前で保存すれば完成です。

#packageの読み込み準備
$dir="$PSScriptRoot\"
$package=@(
   ("Newtonsoft.Json","12.0.3"),
   ("Google.Apis.Core","1.46.0"),
   ("Google.Apis","1.46.0"),
   ("Google.Apis.Auth","1.46.0"),
   ("Google.Apis.Calendar.v3","1.46.0.1986")
)

#dllのインストール
for($i=0;$i -lt $package.Count;$i++){
   $name=$package[$i][0]
   $version=$package[$i][1]
   if(!(Test-Path "$dir$name.$version")){
      Install-Package $name -Source nuget -Scope CurrentUser -SkipDependencies -Destination $dir -RequiredVersion $version|out-null
   }
}

##アセンブリの読み込み
$target="net45"
for($i=0;$i -lt $package.Count;$i++){
   $name=$package[$i][0]
   $version=$package[$i][1]
   Add-Type -path (Join-Path "$dir$name.$version" "lib\$target\$name.dll") -ReferencedAssemblies (Join-Path $dir "$name.$version\lib\$target\$name.xml")|Out-Null
}
##エラーを無視する
$defaultErroAction=$ErrorActionPreference
$ErrorActionPreference="SilentlyContinue"

[string[]]$scope=[Google.Apis.Calendar.v3.CalendarService+Scope]::CalendarReadonly
$ApplicationName = "Google Calendar API .NET Quickstart";
$open=[System.IO.FileMode]::Open
$read=[System.IO.FileAccess]::Read
$stream= New-Object System.IO.FileStream -ArgumentList (Join-Path $dir "credentials.json"),$open,$read
$secrets=([Google.Apis.Auth.OAuth2.GoogleClientSecrets]::Load($stream)).Secrets
$credPath=(Join-Path $dir "token.json")
$dataStore=[Google.Apis.Util.Store.FileDataStore]::new($credPath,$true)
$credential=
([Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker]::AuthorizeAsync(
$secrets,$scope,"user",[System.Threading.CancellationToken]::None,$dataStore)).Result;

Write-Host ("Credential file saved to: " + $credPath)

##Create Google Calendar API service.
$baseClient=New-Object Google.Apis.Services.BaseClientService+Initializer
$baseClient.HttpClientInitializer =$credential
$baseClient.ApplicationName=$ApplicationName
$service=New-Object Google.Apis.Calendar.v3.CalendarService($baseClient)

##Define parameters of request.
$request=$service.Events.List("primary")
$request.TimeMin=[System.DateTime]::Now
$request.ShowDeleted=$false
$request.SingleEvents=$true
$request.MaxResults=10
$request.OrderBy=[Google.Apis.Calendar.v3.EventsResource+ListRequest+OrderByEnum]::StartTime

##List events.
$events=$request.Execute()
Write-Host "Upcoming events:"
if($events.Items -ne $null -and $events.Items.Count -gt 0){
foreach($item in $events.Items)
{
   $when=$null
   $when=$item.Start.DateTime.ToString()
   if([System.String]::IsNullOrEmpty($when)){$when=$item.Start.Date}
      Write-Host ("{0} {1}" -f $item.Summary,$when)
   }
}

$ErrorActionPreference=$defaultErroAction

最後に

Windowsの標準機能だけでGoogleカレンダーをいじるので、外部のソフトウェアをインストールする必要がないことが強みですかね。

会社のPCなので許可なしに他のソフトウェアを入れられない場合でもGoogleカレンダーをコマンドから扱うことができるようになります。

ここまでお読みいただき、ありがとうございました。

関連する記事

PowerShellでGoogleカレンダーを操作する その4~予定を削除する~ - 適材適所

PowerShellでGoogleカレンダーを操作する その3~予定を削除する~ - 適材適所

PowerShellでGoogleカレンダーを操作する その2~予定を追加する~ - 適材適所

PowerShellからGmailを送信するスクリプトを作りました - 適材適所