【GAS & LINEWORKS】サービス API Access Token を簡単に発行する

最近、サービス API について聞かれることが多くなりました。
在宅ワーク増えた影響で、Drive や Calender の API を使ったサービスを増やすようです。
サービス API はサーバー API より認証が厳しく、Token の取得がちょっと面倒なのでライブラリを作って（割と）簡単に取得できるようにしてみました。

よろしければご利用ください。

# サービス API って？

と、その前に簡単にサービス API についてお話を。
知ってる方は読み飛ばしちゃってください。

[LINEWORKS の Service API を postman で試す方法](https://qiita.com/kunihiros/items/ce3a3677113426d6b75f) でもお話しましたが、LINEWORKS の API には `サービス API` と `サーバー API` の２種類があります。

- `サービス API` : メールとかドライブとか、特定のユーザのデータにアクセスする API
- `サーバー API` : トーク Bot の操作とかメンバー追加したりとか、全体の操作をする API

ざっと説明するとこんな感じです。
公式ドキュメントで詳しい説明がありますので、興味ある方は以下のページをご参考ください。
[サービス API の利用範囲](https://developers.worksmobile.com/jp/document/1002004?lang=ja)
[サーバー API の利用範囲](https://developers.worksmobile.com/jp/document/1002005?lang=ja)  

# サービス API Access Token を発行する

そんなサービス API を使うには、もちろん Token を発行しないといけないのですが、サーバ API と違って発行の STEP が多いです。( ﾟДﾟ)ﾒﾝﾄﾞｲ

1. Service API Authorization Code の発行リクエスト
2. 利用するユーザの ID と PASS でログイン
3. 発行された Authorization Code を使って Service API Access Token の発行リクエスト

いや、仕方ないんでしょうけどさ。( ﾟДﾟ)ﾒﾝﾄﾞｲ

ってなわけで、GoogleAppsScripts で（割と）簡単に発行していきましょー！

### GoogleAppsScripts でコードを書く

https://script.google.com/ にアクセスして新しいプロジェクトを作ります。
名前は何でも良いです。

作成したら以下のコードを丸っとコピペしてください。

```javascript:app.gs
const obj = {
  "apiId" : "xxxxxxxx",
  "consumerKey" : "xxxxxxxxxx",
  "serverId" : "xxxxxxxxxxxxxxx",
  "privateKey" : "-----BEGIN PRIVATE KEY-----\nxxxxxxxxxx\n-----END PRIVATE KEY-----",
  "botNo" : null
};
const serviceKey = "xxxxxxxxxxxx";
const domainId = "xxxxxxxxxx";
const accountId = "xxxxxxxxxxxxxxxx";
const callbackURL = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxx/exec";

function regBot() {
  LINEWORKS.regServiceTokenNoticeBot(obj, accountId, domainId, callbackURL);
}
function getServiceApiToken(){
  LINEWORKS.getSeriviceToken(obj, accountId, serviceKey, callbackURL)
}
function doPost(e) {
  LINEWORKS.sendMsg(obj, accountId, "Service Api Authorization Token を発行しました。");
  const params = JSON.parse(e.postData.getDataAsString());
  LINEWORKS.sendMsg(obj, accountId, params.access_token);
}

```

### LINEWORKS Developer Console で認証情報を取得

コピペしたら [LINEWORKS Developer Console](https://developers.worksmobile.com/jp/console/openapi/main) で必要な情報を拾ってきて記載します。

- apiId : API ID
- consumerKey : Server API Consumer Key
- serverId : Server List(ID登録タイプ) の ID
- privateKey : Server List(ID登録タイプ) の認証キー
- botNo : まだ記載しません(>_<)
- serviceKey : Service API Consumer Key
- domainId : Domain ID
- accountId : 自分の LINEWORKS ユーザ ID

認証キーについてですが、実際に見てもらうとわかる通りもの凄く長い上に変な改行が入っています。少々面倒なのですが、
"-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9...\n-----END PRIVATE KEY-----" となるように \n と \n の間に認証キーを入れて一行で表記します。

### LINEWORKS ライブラリを登録

次に、GoogleAppsScripts に LINEWORKS ライブラリを登録します。 

1. 「リソース」-「ライブラリ」をクリック
2. 「ライブラリを追加」の欄に `1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod` を入力して追加ボタンをクリック
3. 「LINEWORKS」ライブラリが追加されるので、一番新しいバージョンを選んで保存ボタンをクリック

### アプリケーションを公開して Callback URL を取得

登録が完了したら、一度、Script をウェブアプリケーションとして公開します。

1. 「公開」-「ウェブアプリケーションとして導入」をクリック
2. 出てきた画面で以下の設定をします。
    - プロジェクトバージョン ： NEW
    - 次のユーザーとしてアプリケーションを実行 ： Me(自分のアカウント名)
    - アプリケーションにアクセスできるユーザー : Anyone, even anymous
3. 更新をクリック

このとき、Google からセキュリティの警告が出て許可を求めることがあります。
気にしない人はそのまま許可出しちゃってください。
気になる人は調べてから許可してください。( ﾟДﾟ)

公開が完了すると「現在のウェブ アプリケーションの URL」が取得できます。
これを、先ほどのコードの `callbackURL` に設定します。

- callbackURL : 現在のウェブ アプリケーションの URL

### ServiceTokenNoticeBot を登録する

LINEWORKS ライブラリで ServiceTokenNoticeBot を登録することができます。
画面上部の関数ボタンから「regBot」を選択して実行します。

![1592457186.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/2f9695e2-2b69-fa67-339e-08dcab7bf637.png)

すると、Bot が自動的に登録されてトーク画面に `botNo` を教えてくれます。

![1592457333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/2042851b-1d25-e535-88e7-3057102b2e64.png)

先ほど記載しなかった `botNo` にこの `botNo` を記載します。

```js
  "botNo" : 0000000
```

`botNo` は `Number` ですので数字をそのまま入力します。

入力したら先ほどの手順で、もう一度 Script をウェブアプリケーションとして公開します。
プロジェクトバージョンを `NEW` にするのを忘れないでくださいね～(*‘∀‘)

### いよいよ Token 発行です！

画面上部の関数ボタンから「getServiceApiToken」を選択して実行します。
![1592458115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/fea82720-78fe-51ea-4fd0-d1df522c6e52.png)

すると、Bot がトークに URL を送ってくるので、これをクリックします。
![1592458268.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/ff6196d3-2d1e-c0f7-0a52-8493a037e04e.png)

すると、Token が発行されてトーク画面に送信されます。

![1592458323.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/6f2600e3-55eb-1053-34ec-3b4120fbf7f3.png)
![1592458398.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/c015be23-d0f4-636e-2df1-9a9bee9f02dd.png)

発行されました！やったね！(*'▽')

## 別のユーザの Token を取得する

ちなみに `getServiceApiToken` のところのコードを少しいじると別のユーザのトークンも取得できます。

```js
const otherId = "otherUser@domain";

function getServiceApiToken(){
  LINEWORKS.getSeriviceToken(obj, otherId, serviceKey, callbackURL)
}
function doPost(e) {
  LINEWORKS.sendMsg(obj, accountId, "Service Api Authorization Token を発行しました。");
  const params = JSON.parse(e.postData.getDataAsString());
  LINEWORKS.sendMsg(obj, accountId, otherId + " さんの Token です。\n" + params.access_token);
}
```

`otherUser@domain` のトークに Bot から URL が送信されるので、クリックしてもらえば自分のトークに Token が送られてきます。

管理者がメンバーの Token をいっぺんに発行するときに便利です。
ほんと、便利です( ﾟДﾟ)（大事なことなので２回言った）

なんだったらトークに送信するんじゃなくてスプレッドシートに記録していったら Token の一覧が作れてしまいます・・・！
発行日も記録して、期間が満了するタイミングで再発行するように設定して・・・って、あれ？
これ、サービスとして確立するのでは・・・？？
まぁ、そこまで需要があるかは謎ですが(*‘∀‘)

#おわりに
ここまでお付き合いいただきありがとうございました。

割とマニアックな話題になりました。
有料プラン以上じゃないと Serivice API 使えないですし。
でも、使えると便利なんですよね。
メールやカレンダー、ホームの内容確認したり、投稿したり。
あと、Drive が連携できる！

今度、Google Drive やカレンダーと同期させてみようと思ってます。
そしたらかなり便利になる予感がしています・・・！(｀・ω・´)

ではまた！(^^)/

#参考にさせていただきましたm(_ _)m
[GoogleAppsScript 公式サイト](https://developers.google.com/apps-script/reference/)
[LINEWORKS Developers](https://developers.worksmobile.com/jp/document?lang=ja)