ここ最近クロスバイクで通勤していて、ただ通勤してるだけではつまらないので、AppleのヘルスケアにAppleWatchを通して走った距離や消費したカロリーを蓄積している
ただ現状は蓄積してるだけなので何か出来ないかと考えているけど一旦GCSにおく
今回はGCSにアップロードするのにGoogleAppScriptsを使用する
大まかな流れ
- iphone側でヘルスケアデータの書き出しを行う
- 共有方法でGmailを使用する(自分のgmailアカウントから自分のgmailアカウントへメールを送ることになります)
- Gmai側では任意のラベルをつけて、それを対象にしてGASで処理をさせ添付されているデータをGCSへアップロードして完了したラベルをはる
ラベルの設定
ラベルはなんでも良いが今回は上の画像のように GCSエクスポート
という親ラベルに 未処理
と 完了
という子ラベルを配置した
今回はiphone側からヘルスケアデータをGmailでおくった時に 未処理
というラベルをつけるようにフィルタを設定する
サービスアカウントの発行
GoogleAppScriptからGCSへファイルアップロードするためにサービスアカウントを発行する
発行の仕方については
Google Cloud Storage の認証 | Cloud Storage ドキュメント | Google Cloud Platform
を見ると良さそうです
ポイントとしてはGCSへの書き込み権限とjsonで鍵を取得するの2つが満たされていること
GoogleAppScript
GoogleAppScriptファイルを新規で作成をする
ここにGmailから未処理ラベルがついたメールを取り出して添付ファイルをGCSにアップロードしていく
未処理のラベルをメールを取り出して完了するラベルをはる処理
function main() { // serachに使えるのはgmailでの検索フォームと同じ const threads = GmailApp.search('label:gcsエクスポート-未処理'); for(var i = 0; i < threads.length; i++) { const messages = GmailApp.getMessagesForThread(threads[i]); /* 各メールから日時、送信元、件名、内容を取り出す*/ const message = messages[messages.length - 1]; const attachments = message.getAttachments(); for(var j = 0; j < attachments.length; j++) { if (attachments[0].getName() == "書き出す.zip") { // ここにファイルアップロード処理をかく threads[i].removeLabel(yetLabel); threads[i].addLabel(completeLabel); } } } }
アップロード時には認証を行わなけれならないので すでに先人がAppScript用に配布しているものがあるので今回はこれを使用する
function uploadFile_(gmailAttachment) { // GASのスクリプトプロパティにSAJsonKeyという名前で先程のサービスアカウントのjsonをまるごといれる const jsonKey = JSON.parse(PropertiesService.getScriptProperties().getProperty("SAJsonKey")); const gsAPP = new GSApp.init(jsonKey.private_key, ['https://www.googleapis.com/auth/devstorage.full_control'], jsonKey.client_email); const tokens = gsAPP.addUser(jsonKey.client_email).requestToken().getTokens(); const token = tokens[jsonKey.client_email].token; const bucketName = '任意のバケット名'; const uploadFilepath = 'GCSへのアップロードパス exp: hoge/fuga.zip'; const requestUrl = "https://www.googleapis.com/upload/storage/v1/b/"+bucketName+"/o?uploadType=media&name="+encodeURIComponent(uploadFilepath); const blob = gmailAttachment.copyBlob(); const bytes = blob.getBytes(); const fetchOptions = { method: "POST", contentLength: bytes.length, contentType: blob.getContentType(), payload: bytes, headers:{Authorization:"Bearer "+ token} }; UrlFetchApp.fetch(requestUrl, fetchOptions); }
最終的なGoogleAppScriptの中身は下記のようになる
あとはGoogleAppScriptには定期実行する cronのような機能があるので任意の時間で発火させるだけで可能である
これで実行すると未処理のファイルがあるとGoogleAppScriptが定期処理の際に処理にてGCSへファイルをアップロードしてくれる
おまけ
運用するにあたっては処理開始したのか?完了したのか?わからないのでslackに通知なげてます