フォーム入力をしたら LINE から入力完了通知が来る方法をつくってみよう

# LINE で注文フォームをつくりたい

## やりたいこと
LINE をインターフェースとして商品の予約や注文を行うために、次の機能をつくります。

:::note
- LINE からユーザーにフォームのリンクを送る
- ユーザーがそのフォームを入力し終えたら LINE で入力完了を連絡する
:::

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/36c84351-c2f3-4b8a-919b-057aa04c0518.png">

一見、シンプルな機能ですが、フォームの回答完了ボタンをきっかけにして LINE でメッセージを送るため、LINE アカウント側は返信すべきユーザーの情報を保持している必要がある、という訳です。

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/43e76fd9-908b-4d69-8e1b-f57495cc80c6.png">

---

## 既存サービスのモヤモヤ

入力完了の通知は Google Form や Notion のフォームを使うことでユーザーのメールアドレスに送信することはできますが、せっかく LINE を使ってユーザーとやり取りしているので、やり取りは LINE のみで完結したいです。

- Google Form のメール設定  
> 回答者のメールアドレスに回答内容を送れる <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/9402b443-731f-4045-82b0-efdadffb3a75.png">

  
- Notion のフォーム  
> 回答者は回答後にメールで回答内容を受け取れる 
> <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/5c2b3b3c-bf2b-4670-9c95-5369475df050.png">

- LINE のメッセージをフォームとして使う
応答メッセージを設定しながら LINE で選択肢のある質問をいくつか送ることで疑似的にフォームのふるまいをしますが、これはメッセージの設計や回答結果の解析が大変なのでやはりフォームを活用したいです。

> <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/c6055d18-8418-4e0f-9a1b-b5965ad72242.png">
[LINE Developers の公式ドキュメント](https://developers.line.biz/ja/docs/messaging-api/message-types/#confirm-template)

---

## クエリパラメータで ユーザー ID 付きのフォームをつくれば解決

フォームの URL にクエリパラメータとしてユーザー情報を追加し、回答データとしてユーザー情報を記録します。
イメージはこのようなフォームの URL です。

```
https://formurl?userid=【ユーザー ID】
```

Tally というフォームビルダーを使って、フォームの回答時に LINE で通知が来るような設計をしました。

https://tally.so/

:::note warn
Tally の代わりに Google Form を使えますが、ユーザー体験的には Tally が良いです（後ほど説明します）。
:::

---

## 制作の前提

* LINE のアクセストークンがある
* Make のアカウントがある（慣れている他の iPaaS でも OK）
* Tally のアカウントがある

---

## 実装

### 1. まずはフォームを用意

Tally でフォームをつくります。UI は Notion に似ています。

`Hidden field` というブロックを用意し、"userid" という名前を付けます。名前は何でも良いです。 

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/3f5d5855-c19b-489f-b951-d5fe14fb00e9.png">

`Hidden field` のブロックはインデントが入っており、回答時にはブロックは回答時には見えません。 
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/2c203d31-453b-479a-bf6f-1969c63604ae.png"> 
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/5a660d9f-3e91-4c36-a3a1-00bb65423900.png">

この状態で、フォームのリンクを取得すると URL はこのようになります。

```
https://tally.so/r/12a3bc
```

ここでクエリパラメーターとして先ほど `Hidden field` のブロックに設定したパラメーター ("userid") を使います。
"userid" の値に `12345` を入れ、フォームで回答してみます。

```
https://tally.so/r/12a3bc?userid=12345
```

先ほど試したように `Hidden field` の質問は見えませんが、回答結果には `12345` が反映されています。 <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/91b0422d-e035-4726-b29e-c3d19ef2ad0c.png"> <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/9dbea7ba-ff56-49c4-bdbf-af32c695792c.png">

あとはこの値を Make などで受け取り、LINE の返事に使います。

---

### 2. Make で LINE からフォームを送る

Make で次のように LINE のモジュールを繋げます。 
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/269181cb-057c-4b76-b607-b1c25a2e38e8.png">

* LINE ： `Watch Events`
アクセストークンを使い、LINE アカウントと紐づけます。

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/2a5d5980-43d5-42cb-a34b-032dfb44eb56.png">

* LINE ： `Send a Reply Message`
`Watch Events`モジュール で手に入れた `Events[]: Reply Token` を `Reply Token` に入れます。

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/fb6695b1-e6d9-43fa-a67e-9dcdde04f809.png">

そして、ユーザーに送るフォームの URL をメッセージに追加します。

:::note 
ここが大事です
:::

この時、Tally のフォームの末尾には `Events[].source.userId` を使います。 
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/34c266f0-336f-4a78-a2da-cf90c71eb34a.png">

---

### 3. Make でユーザー ID をフォームから LINE に渡す

Make で次のように Tally と LINE のモジュールを繋げます。 
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/975dfcdc-b5d0-4732-819a-af4f97407667.png">

* Tally ： `Watch New Responses`
先ほどのフォームのアカウントと紐づけます。

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/8d00a91a-1ae7-4d92-8dff-f334a83938fc.png">

* LINE ： `Send a Push Message`
Tally のフォーム回答にトリガーしてプッシュメッセージを送ります。
`To` には `Hidden field` に仕込んでおいたユーザー ID を Tally から持ってきます。

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/edbc6f5c-3904-4603-98db-9d99e7b1e223.png">

これで LINE から送ったフォームにユーザーが回答した時にメッセージが自動で送られます。
実装はこれで終了です！

---

## 余談：Google Form より Tally が良い！

実は Google Form でもクエリパラメーターによる事前入力は可能です。

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/d689a9a4-5656-4c42-81ba-408971913b79.png"> 
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/8657a2ec-a659-4e6c-a3fb-179510aa1393.png">

リンクを取得するとこのような URL がコピーされます。

```
https://docs.google.com/forms/d/e/1FA…6Lg/viewform?usp=pp_url&entry.987654321=123456
```

この URL では `entry.987654321=123456` がユーザー ID の質問に対応するクエリパラメーターなので、ここを例えば `000001` とするとフォームへ自動で転記されます。 

<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/611285d2-129b-4295-ade1-08ca383a8db7.png">

ただし、ユーザーが回答している途中でこの設問が見えてしまうのが難点です。仮に、ユーザーが ID を書き換えてしまうと LINE の返事ができません。
　　
フォームのつくりを工夫して、回答者がこの設問へたどり着かないようにする方法もあります。
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/2a4bbb6a-4d9f-4002-9d23-9693fe5e9e99.png">


残念ながら、この場合は回答結果に ID が反映されませんでした。 
<img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/8ed5c3a1-108a-4320-a3a7-21db3ef0be7d.png">

Tally の隠し設問がこのような ID の受け渡しに便利でした。

https://tally.so/help/hidden-fields

---

## 参考
https://note.com/eguweb/n/n21893b89a7dc