Google Apps Script Advent Calendar 2020 の 18日目!
どうぞよろしくお願いします。
はじめに
リモートワークでチャットの利用が増えてきた昨今。
仕事も効率よく自動化するために Bot の利用も増えてきました。
報告用 Bot とか経費精算 Bot とかで、メンバーがファイルを送信したら Google Drive に保存して管理者に通知してくれたら管理しやすいですよね。
ってなわけで作ってみました!(*'▽')
実際の画面
GoogleAppsScript で LINE WORKS BOT を作る
以下の記事を参考に Bot を作成してあります。
【GAS × LINE WORKS】BOT で PDF ファイルを送受信!
この記事で作った Bot にコードを書き加えていきます♪
コードを書き加える
ファイルデータを受信するプログラムは実装されているので、追加で実装する機能は以下の2つです。
- 受信したファイルをダウンロードする
- ダウンロードしたファイルを Google Drive に保存する
ではでは、ひとつずつ実装していきまっす!ヾ(´∀`)ノ
1. 受信したファイルをダウンロードする
Bot がファイルを受信すると resourceId
というものを取得します。
実際のファイルデータを手に入れるには、この resourceId
を使って API を Request します。
使用する API はトーク Bot のコンテンツダウンロード API です。
では、この API を呼び出す関数を作っていきます。
function fileDownload(resourceId) {
const headers = {
'consumerKey': CONSTS.consumerKey,
'Authorization': 'Bearer ' + LINEWORKS.getToken(CONSTS),
'x-works-apiid': CONSTS.apiId,
'x-works-resource-id': resourceId
}
const options = {
'method': 'get',
'headers': headers
}
const uri = 'http://storage.worksmobile.com/openapi/message/download.api'
return UrlFetchApp.fetch(uri, options)
}
headers
には認証情報が入ります。
CONSTS
への認証情報のセットについてはコチラをご参考ください。
ダウンロードするファイルの resourceId
も headers
に記載します。
ダウンロードしたファイルは HTTPResponse
オブジェクトで取得されます。
公式 Reference - Class HTTPResponse
あっという間ですね!( ゚Д゚)
では、HTTPResponse
オブジェクトを Google Drive に保存していきましょう。
2. ダウンロードしたファイルを Google Drive に保存する
HTTPResponse
オブジェクトの操作は簡単。
.getBlob()
で作成した Blob
オブジェクトを DriveApp
で書き込むだけ・・・
と、思いきや意外な落とし穴がありました。
保存したファイルの名前がなぜかすべて download.api
になってしまうのです!
呪いか?( ゚Д゚)
何故だかはわかりませんが、ファイル名が正常に取れない模様。
仕方がないので HTTPResponse
のヘッダー情報からファイル名を取得することにしました。
function createFile(response){
const resHeaders = response.getAllHeaders()
const refererUri = resHeaders['x-hlink-org-referer'].split('/')
const filename = refererUri[refererUri.length - 2]
const resBlob = response.getBlob()
resBlob.setName(filename)
const drive = DriveApp.getFolderById(folderId)
drive.createFile(resBlob)
}
filename
が一発で取れれば良かったのですが、無理なので split()
しました。
ちなみにヘッダー情報の中身はこんな構成でした。ご参考までに。
{x-resource-type=resource, Date=Tue, 15 Dec 2020 05:52:01 GMT, Last-Modified=Tue, 15 Dec 2020 05:25:28 GMT, x-hlink-org-referer=https://jp1-storage.worksmobile.com/k/oneapp/r/jp1.xxxxxxxx/xxxxxxxx/v2-xxxxxxxx-443220668.190531528/TEST_PDF.pdf/, ETag=1608009928, Server=FileCloud, Connection=keep-alive, Content-Disposition=attachment; filename="TEST_PDF.pdf"; charset=utf-8; filename*=UTF-8''TEST_PDF.pdf, Content-Length=28315, Content-Type=application/pdf}
無事に実行され、ファイルが Google Drive に保存されましたとさー(*‘∀‘)
おしまい♪
全体のコード
全体のコードはここに折りたたんで貼り付けておきます。
// LINE WORKS API 認証情報
const CONSTS = {
'apiId': 'API ID',
'consumerKey': 'Server API Consumer Key',
'serverId': 'Server List(ID登録タイプ) の ID',
'privateKey': 'Server List(ID登録タイプ) の認証キー',
'botNo': 'botNo',
'botMaster': 'BOT 管理者のアカウント ID'
}
// ファイルを保存するフォルダの ID
const folderId = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
// BOT
function doPost(e) {
if(e === null || e.postData === null || e.postData.contents === null) return
const requestJSON = e.postData.contents
const requestObj = JSON.parse(requestJSON)
const user = requestObj.source.accountId
switch(requestObj.content.type){
case 'file':
const resourceId = requestObj.content.resourceId
LINEWORKS.sendMsg(CONSTS, CONSTS.botMaster, `${user}さんからファイルが届きました。`)
LINEWORKS.sendFile(CONSTS, CONSTS.botMaster, resourceId)
LINEWORKS.sendMsg(CONSTS, user, '管理者に File を転送しました。')
const file = fileDownload(resourceId)
createFile(file)
LINEWORKS.sendMsg(CONSTS, CONSTS.botMaster, 'Google Drive に File を保存しました。')
break
default:
LINEWORKS.sendMsg(CONSTS, user, '管理者に File を送信するにはファイルをトークに添付してください。')
}
}
/**
* コンテンツダウンロード API を使用してファイルを取得する
* @param {string} resourceId LINE WORKS からダウンロードするファイルの resourceId
* @return {HTTPResponse object} ダウンロードしたファイルデータ
*/
function fileDownload(resourceId) {
const headers = {
'consumerKey': CONSTS.consumerKey,
'Authorization': 'Bearer ' + LINEWORKS.getToken(CONSTS),
'x-works-apiid': CONSTS.apiId,
'x-works-resource-id': resourceId
}
const options = {
'method': 'get',
'headers': headers
}
const uri = 'http://storage.worksmobile.com/openapi/message/download.api'
return UrlFetchApp.fetch(uri, options)
}
/**
* ダウンロードしたファイルデータを folderId のフォルダに保存する
* @param {HTTPResponse object} ダウンロードしたファイルデータ
*/
function createFile(response){
const resHeaders = response.getAllHeaders()
const refererUri = resHeaders['x-hlink-org-referer'].split('/')
const filename = refererUri[refererUri.length - 2]
const resBlob = response.getBlob()
resBlob.setName(filename)
const drive = DriveApp.getFolderById(folderId)
drive.createFile(resBlob)
}
おわりに
ここまでお付き合いいただきありがとうございました。
前回の宣言通り、Google Drive に保存してやったぜ!(*‘∀‘)メズラシイ
UrlFetchApp.fetch()
からのファイル保存は意外と簡単にできるんですね。
やっぱり GoogleAppsScript は扱いやすいなー。
連携もしやすいし、LINE WORKS API との相性いいかも?
あと、Advent Calender の記事を色々と見ていたら @taketakekaho さんの記事で Google Drive の OCR 機能が無料で使えることを知りました( ゚Д゚)
GASとGoogleDriveのOCR機能で文字起こしボットを作ってみた時のTips
次はさらに OCR 機能追加してみるのも楽しいかも!
ではまた!(^^)/