今回は、LINE WORKS API 2.0 を使用し、出退勤時刻をメモする BOT を作ってみます。
トーク BOT とのトークルームで画面下部に表示するユーザー定義のメニューを固定メニューといいます。
手元の PowerShell を使い、あらかじめ作成しておいた BOT に対して、ボタンをクリックすると callback URL が呼ばれる 固定メニューを登録します。
# Token を取得して Secure String として $secToken に入れるところは省略
$botId = 12345678 # 作った Bot の BotId を指定
$url = "https://www.worksapis.com/v1.0/bots/$botId/persistentmenu"
$contentBody = @{
content = @{
actions = @(
@{
type = "message"
label = "出社しました"
text = "ただいま出社しました"
postback = "comeintowork"
}
@{
type = "message"
label = "帰ります"
text = "そろそろ帰ります"
postback = "leavetheoffice"
}
@{
type = "uri"
label = "使い方"
uri = "https://line.worksmobile.com"
}
)
}
}
$reqBody = $contentBody | ConvertTo-Json -depth 10
$reqBody = [System.Text.Encoding]::UTF8.GetBytes($reqBody)
Invoke-WebRequest -Uri $url -Method POST -Authentication Bearer -Token $sectoken -ContentType "application/json" -Body $reqBody
これで、BOT に固定メニューが登録できました。
次に、Azure Functions 側の構成です。
新しい BOT を使ったので、新しい BOT の botId と BotSecret は、アプリケーション設定に BOTID2 と BOTSECRET2 として追加しておきます。
HTTP Trigger テンプレートを使って新しい関数を作成し、以下のコードを貼り付けます。
using namespace System.Net
param($Request, $TriggerMetadata)
$clientId = $env:CLIENTID
$clientSecret = $env:CLIENTSECRET
$botId = $env:BOTID2
$privateKeyFile = $env:PRIVATEKEYFILE
$svcAccount = $env:SERVICEACCOUNT
$botSecret = $env:BOTSECRET2
$Scope = "bot"
$body = $Request.RawBody
$receiveMsg = $body | convertfrom-json
### GET Access Token ###
$PrivKeyPath = "D:\home\site\wwwroot\" + $privateKeyFile
$rsaPrivateKey = Get-Content $PrivKeyPath -AsByteStream
$iat = [int](Get-Date -UFormat %s)
$exp = $iat + 3600
$payload = @{
sub = $SvcAccount
iat = $iat
}
$jwt = New-JWT -Algorithm 'RS256' -SecretKey $rsaPrivateKey -PayloadClaims $payload -ExpiryTimestamp $exp -Issuer $clientId
$requestHeader = @{
'Content-Type' = 'application/x-www-form-urlencoded'
}
$requestBody = @{
assertion = $jwt
grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
client_id = $clientId
client_secret = $clientSecret
scope = $Scope
}
$url = 'https://auth.worksmobile.com/oauth2/v2.0/token'
$response = Invoke-RestMethod -Uri $url -Method POST -Headers $requestHeader -Body $requestBody
$sectoken = ConvertTo-SecureString $response.access_token -AsPlainText
$oHMACSHA256 = New-Object System.Security.Cryptography.HMACSHA256
$oHMACSHA256.key = [Text.Encoding]::ASCII.GetBytes($BotSecret)
$readBuf = [System.Text.Encoding]::UTF8.GetBytes($body)
$signature_rawout = $oHMACSHA256.ComputeHash($readBuf)
$signatureB64 = [Convert]::ToBase64String($signature_rawout)
if ($signatureB64.ToString() -eq $Request.Headers["X-Works-Signature"]) {
# 固定メニューが選択された場合の処理
$postback = $receiveMsg.content.postback
if ($postback -eq "comeintowork"){
$msg = "今日も一日頑張ろう @ " + [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]($receiveMsg.issuedTime),"Tokyo Standard Time")
}elseif ($postback -eq "leavetheoffice")
{
$msg = "お疲れさまでした! @ " + [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]($receiveMsg.issuedTime),"Tokyo Standard Time")
}else{
$msg = "固定メッセージから 「出社しました」 か 「帰ります」 を選択してください”
}
}
else {
$msg = "どなたですか?"
}
$reqBody =@{
content = @{
type = 'text'
text = $msg
}
}
$reqBody = $reqBody | convertto-json
$reqBody = [System.Text.Encoding]::UTF8.GetBytes($reqBody ) # hack for MOJI-BAKE
$userId = $receiveMsg.source.userId
$URL = "https://www.worksapis.com/v1.0/bots/$botId/users/$userId/messages"
Invoke-WebRequest -Method POST -Uri $URL -body $reqBody -Authentication Bearer -Token $secToken -ContentType "application/json"
コードはちょっと多いですが、callback メッセージに応じて返信メッセージを作成する部分がちょっと変わっているだけで、Token の取得やメッセージの送信など、ほとんどは前回と同じコードです。
ここまできたら、関数の URL を取得して、BOT の callback に指定します。BOT に送信可能なメッセージとしてテキストを選択しておきます。
これで、BOT 利用の準備ができました。
作成した BOT とのトークルームを開くと、画面下部に、登録した固定メニューが表示されています。
「使い方」 ボタンを押すと、固定メニューに登録した URL が開きます。
「出社しました」または「帰ります」ボタンを選択すると、postback パラメータとともに BOT に指定した callback URL (= Azure Functins 上の関数) が呼ばれます。Azure functios 側では、callback の内容から出社か退勤を判断し、issuedTime (= ボタンがクリックされた時刻) を含めて、ユーザーにメッセージを飛ばします。
今回はメッセージの文字列を構成してユーザーに送り返したのみですが、必要であればロジックを組み込んで、データベースに出退勤時刻を保存するようなことも可能です。