プリザンターから LINE WORKS に通知できるように設定する

この記事は [OSS のノーコード・ローコード開発ツール「プリザンター」Advent Calendar 2024](https://qiita.com/advent-calendar/2024/pleasanter) の 16 日目です。

## 要約

* プリザンターには通知機能があるが、通知先として LINE WORKS は用意されていない
* HTTP クライアントという通知種別を使えば実現できそうだが、JSON の送信が難しいため不可
* 代替としてサーバスクリプトを用いて LINE WORKS への通知を行ってみた（完全再現はしていない）

## プリザンターの通知機能

プリザンターには、レコードの作成や更新を行った際にメールなどで通知することができる機能があります。

https://pleasanter.org/ja/manual/table-management-notification

記事執筆時点では、メール以外の通知先として、Slack、Chatwork、LINE、Teams、Rocket.Chat、InCircle を利用することができるようです。

一方で、これらのツールと肩を並べる（と、個人的には思っている）「LINE WORKS」は、通知先として用意されていないようです。

## LINE WORKS

LINE WORKS は、ビジネスチャットの一種で、ビジネス版 LINE とも称されるように LINE と似た操作感が特徴です。

https://line-works.com/

しかし、提供元である [LINE WORKS 株式会社の会社紹介](https://line-works.com/aboutus/) に記載されている通り、LINE と LINE WORKS は別物です。

> 「LINE」は、LINE ヤフー株式会社が提供するコミュニケーションアプリです。無料で友だちや家族と、トーク（チャット）・音声通話・ビデオ通話などを楽しむことができます。 LINE WORKS とは、アプリも運営会社も異なります。 

よって、プリザンターで用意されている LINE への通知の仕組みをそのまま使って LINE WORKS へ通知することはできません。

## 通知種別：HTTP クライアント

冒頭でメールや Slack などを挙げた通知先ですが、その指定は「通知種別」という項目で行います。通知種別には、これまで挙げたもののほかに「HTTP クライアント」というものがあります。[^1]

[^1]: [プリザンター 1.3.17.0 以降](https://pleasanter.org/ja/manual/httpclient)

この「HTTP クライアント」を使用すると、任意の URL に対して、`GET`、`POST`、`PUT`、`DELETE` といった HTTP リクエストを送信することができます。つまり、いわゆる Web API を叩くことができるということですが、LINE WORKS も含め、多くのツールは Web API を使って外部システムとの連携を実現しているので、この「HTTP クライアント」を使うことで、プリザンターで用意されていないツールにも通知することができそうです。

:::note info
「HTTP クライアント」を使用するためには、[Notification.json](https://pleasanter.org/ja/manual/notification-json) の設定項目 `HttpClient` が `true` である必要があります。記事執筆時点のバージョンでは、デフォルトで `false` になっているようなので、通知種別に「HTTP クライアント」が表示されない場合は確認してください。また、明示はされていないようですが、筆者が確認する限り、デモ環境では「HTTP クライアント」を使用できないようです
:::

## できませんでした

LINE WORKS に用意されている Incoming Webhook アプリ（後述）と、「HTTP クライアント」で、プリザンターから LINE WORKS に通知できる、と思いましたが、うまくいきません。

調べてみると、どうやっても JSON を送信できないようでした。

https://zenn.dev/ulpianus/articles/01f1cbcbe85682

このままでは LINE WORKS への通知もさることながら、せっかく用意されている「HTTP クライアント」も使いどころがかなり限られてしまうと思い[^2]、issue を書きました。

[^2]: 通知の設定項目のうち「メディア種別」の既定値が `application/json` となっていることからも憶測できるが、「HTTP クライアント」では JSON を送信するケースが多いと思われる

https://github.com/Implem/Implem.Pleasanter/issues/586

## 代替案

このままアドベントカレンダーの記事を終えるとクリスマスを迎えられない気がするので、サーバスクリプトで代替する方法を検討しました。

https://pleasanter.org/ja/manual/server-script

ここからはプリザンターのマニュアル風に書いてみます。

### 前提条件

LINE WORKS のテナントを作成してください。フリーを含め、どのプランでも構いません。

https://help.worksmobile.com/ja/getting-started-guides/registration/

### Incoming Webhook アプリの追加と URL の取得

LINE WORKS にログインしてください。

#### Incoming Webhook アプリの追加

1\. [管理者画面](https://common.worksmobile.com/proxy/admin) にアクセスしてください

2\. アプリディレクトリから [Incoming Webhook アプリ](https://line-works.com/appdirectory/incoming-webhook/) を追加してください

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/e1f74c70-210d-b2aa-1d58-df33860e8b97.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/57c1ebfe-3601-5bf3-a11b-95d815d4556c.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/3356e640-ab0a-ae77-aa61-5ce209b16879.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/45dbf538-77b0-a990-e7f3-ae7e9956a8d8.png)

#### URL の取得

1\. Incoming Webhook Bot を含む新たなトークルームを開始してください（または、既存のトークルームに Incoming Webhook Bot を招待してください）

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/b83008b4-2b8e-4b20-2e0c-9e42c8b78c67.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/a160e94a-1a67-6eea-07fc-a3718a3b88cc.png)
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/3cf87b5e-db4c-c98d-48a4-d23c24de799f.png)

2\. トークルームのメニューにある「チャンネル ID」をクリックし、表示されたトークルームのチャンネル ID を控えてください

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/5891d8f4-0bd9-90d9-2c08-11a911278f07.png)
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/cfe0f3a3-3a2f-afdc-7702-9c9125ee8382.png)

3\. トークルームの下部に表示されるメニューの「Webhook リスト」をクリックしてください

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/206468dd-685b-bc95-7159-00d4cb711c38.png)

4\. 「追加」をクリックしてください

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/346b1f8f-dbc7-c78a-1d58-02dbde6e5c82.png)

5\. 「Webhook 名」に任意の名前（例：プリザンター）を入力、「チャンネル ID」に控えていたトークルームのチャンネル ID を入力し、「OK」をクリックしてください

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/c5ea94d3-7280-a119-c2a1-de0a13470320.png)

6\. 表示された URL を控えてください

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/242dd14a-4ce5-cd95-413b-53415c7e1d17.png)

#### プリザンターの設定[^3]

[^3]: デモ環境も可

1\. 通知を設定するテーブルを選択し、[テーブルの管理](https://pleasanter.org/ja/manual/table-management) - [サーバスクリプト](https://pleasanter.org/ja/manual/table-management-server-script) を開いてください。「新規作成」ボタンをクリックしてください

2\. 「タイトル」に任意のタイトル（例：共有）を入力、「スクリプト」に以下（`https://webhook.worksmobile.com/message/xxxxxxxxxxxxxxxxx` の部分は控えていた URL に置き換えてください）を入力し、「条件」の「共有」のチェックボックスをオンにして、「追加」ボタンをクリックしてください

```javascript
function send() {
  try {
    let user = users.Get(model.Updator);
    let data = {
      "title": model.Title + " を " + context.Action + " しました",
      "body": {
        "text": model.Body + "\n\n" + user.Name
      },
      "button": {
        "label": "URL",
        "url": context.Url
      }
    }

    httpClient.RequestUri = 'https://webhook.worksmobile.com/message/xxxxxxxxxxxxxxxxx';
    httpClient.Content = JSON.stringify(data);
    httpClient.Post();
  } catch(e) {
    context.Log(e.stack);
  }
}
```

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/1d852c79-4875-de72-1d17-938add8c4cb4.png)

3\. 再度、[サーバスクリプト](https://pleasanter.org/ja/manual/table-management-server-script) の「新規作成」ボタンをクリックしてください

4\. 「タイトル」に任意のタイトル（例：通知）を入力、「スクリプト」に以下を入力し、「条件」の通知したい条件（「作成後」、「更新後」、「削除後」）のチェックボックスをオンにして、「追加」ボタンをクリックしてください

```javascript
try {
  send();
} catch (e) {
  context.Log(e.stack);
}
```

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/12d15ddf-8489-96fc-e081-87bd72765914.png)

5\. 「更新」ボタンをクリックしてください。以上で本手順は終了です

## おわりに

プリザンターでレコードを作成すると——

![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/7d52fb4e-dd3a-2ae7-68f6-0b8230b75213.png)

—— LINE WORKS へトークとして通知されるようになりました。

![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838749/17db27f7-5f5f-876d-9d16-508ba8dc367d.png)

### 完全な再現はできていない

ひとまず LINE WORKS への通知は実現できましたが、プリザンターの通知機能の完全な再現には至っていませんので、まだまだ改善の余地があります。

なお、明らかにダメな点（手抜きした点ともいう）として、リンクボタンの URL に `context.Url` を指定しているので、`http://example.com/items/1/create` のような URL になってしまい、通知された URL を開いてもレコードが表示されません。本来はレコードのエディタ画面が適当だと思いますが、それっぽいものは見当たらないので、URL を組み立ててあげる必要があるかもしれません。

また、[前出の記事](https://zenn.dev/ulpianus/articles/01f1cbcbe85682) を拝見する限り、サーバスクリプトで通知機能を完全に再現することは難しそうです。

### Incoming Webhook アプリについて

この記事で使用している Incoming Webhook アプリは、[LINE WORKS のアプリ](https://line-works.com/appdirectory/) として用意されているもので、無料で利用することができます。

https://developers.worksmobile.com/jp/docs/webhook

https://line-works.com/blog/solution/incoming-webhook-app/

もともと LINE WORKS での通知を実現するためには、LINE WORKS の開発者向けに用意されている [Bot](https://developers.worksmobile.com/jp/features/bot) 機能を用いてチャットボットを開発する必要がありました。

[Incoming Webhook アプリのドキュメント](https://developers.worksmobile.com/jp/docs/webhook#compare-with-bot) にも記載されている通り、このアプリを利用することで、Bot 機能による開発よりも手軽に LINE WORKS での通知を実現することができます。一方で、画像やファイルを送信するといった高度な機能は利用できないため、そういった場合は Incoming Webhook アプリの利用ではなく Bot 機能による開発が必要となります。