Microsoft Forms で作ったイベント参加フォームに上限を設定したい

## はじめに

Microsoft Forms でイベントの参加受付をする事があります。
コミュニティイベントなら connpass 等のイベントサイトを使うのが良いのでしょうが、社内のローカルイベントの場合は、全員がアカウントを持っている事や、氏名／メールアドレスを自動的に収集出来る事から Forms の方が良い事もあります。

ですが、残念ながら Forms では申込数に上限を設ける事が出来ません。

そこで、Logic App を使って、申込数が上限に達した以降の申し込みにはお断りメールを自動的に送信する仕組みを作ってみます。


## 手順

空の Logic App を作成し、Forms トリガーの「新しい応答が送信されるとき」を選択します。

![2020-02-08_16h57_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/c27ccaaf-09dc-3a2f-2d30-01b761abd44d.png)

対象の Form を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/3273296f-4e95-fdfd-526e-195976804743.png)


続けて、回答者のメールアドレスを取得する為に Forms トリガーの「応答の詳細を取得する」アクションを追加します。

レスポンスIDには上のトリガーで取得した `responseId` を指定すれば良いのですが、動的プロパティで取得する事ができません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/78fe39d3-08ae-1ac7-f42b-9c2160bd0825.png)

なので、コードビューで編集します。
`@triggerBody()['body']['resourceData']['responseId']` を `queries.response_id` に指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/855dab6b-275c-a3d0-07e5-935e2658742d.png)


response_id は1から順に振られるので、これが閾値以下なら参加受付メールを、超えていれば受付締切メールを送る事にします。

条件分岐を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/58005ad9-6372-d006-5600-4148e6e3dcd3.png)




「値の選択」では動的なコンテンツの追加が使えるので、「応答通知の一覧 応答ID」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/508ad6ba-4313-468a-c5b5-4a4e8fa60862.png)


条件は「次の値以下」とし、「値」には任意の数値（申込上限値）を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/85cf230d-a4f4-5aac-0b8d-59863cadd5b1.png)


メール送信アクションを追加します。
ここでは Office 365 Outlook で作成しますが、ここは何でも良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/96b1f4be-6ecd-cb37-8906-b1d441bc51a0.png)


true の場合に申込確認メールを送信します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/aae8afae-d38d-3248-283f-ab0c47c26150.png)

ここでも動的プロパティが効かない為、コードビューで指定します。
メールアドレスは `@body('応答の詳細を取得する')?['responder']`、レスポンスIDは `@{triggerBody()['body']['resourceData']['responseId']}` で取得できます。

```json
"actions": {
    "メールの送信_(V2)": {
        "inputs": {
            "body": {
                "Body": "<p>受付番号：@{triggerBody()['body']['resourceData']['responseId']}<br>\n<br>\n@{body('応答の詳細を取得する')?['responder']} さんの参加を受け付けました。<br>\n<br>\n</p>",
                "From": "hoge@example.com",
                "Importance": "Normal",
                "Subject": "テストイベント申込確認",
                "To": "@body('応答の詳細を取得する')?['responder']"
            },
            "host": {
                "connection": {
                    "name": "@parameters('$connections')['office365']['connectionId']"
                }
            },
            "method": "post",
            "path": "/v2/Mail"
        },
        "runAfter": {},
        "type": "ApiConnection"
    }
}
```



同様に、falseの場合に受付られなかった旨のメールを送信します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/ded26bfa-3d4c-6d48-948b-6a75b184a331.png)

```json
"actions": {
    "メールの送信_(V2)_2": {
        "inputs": {
            "body": {
                "Body": "<p>受付番号：@{triggerBody()['body']['resourceData']['responseId']}<br>\n<br>\n申し訳ありませんが、定員に達した為参加を締め切りました。<br>\n</p>",
                "From": "hoge@example.com",
                "Importance": "Normal",
                "Subject": "あなたは補欠です（テストイベント参加申込）",
                "To": "@{body('応答の詳細を取得する')?['responder']}"
            },
            "host": {
                "connection": {
                    "name": "@parameters('$connections')['office365']['connectionId']"
                }
            },
            "method": "post",
            "path": "/v2/Mail"
        },
        "runAfter": {},
        "type": "ApiConnection"
    }
}
```


全体像はこんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/1a8787b3-5bc7-922f-434e-62327a55dd5f.png)



## おわりに

Forms でイベント参加の上限を設ける為に、回答数に応じて受付／拒否のメールを送信する仕組みを Logic App で実装しました。
「受け付けました」と言っておきながら後で「定員を超えているのでやっぱり駄目でした」と連絡するよりはまだマシ・・・だと思います。

キャンセルやら繰り上がりやらを考えると、やっぱりイベントサイトを使いたいところではありますが。