Office365グループのメンバーをPowerAutomateで自動追加する

# はじめに
SharePointのリスト+PowerAutomate(Flow)を使って、リストにアイテムが投稿されたら、それをトリガーにしてOffice365のグループのメンバーに自動的に追加するようにしました。ただ後述しますが、当社の設定では出来ませんでした。。

# SharePointでリストを作る
SharePointでリストを作成します。変更したところは以下のとおり、
## 詳細設定
<img width="625" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/cf99cb54-3447-13cd-1c01-feb63bc7f73e.png">
読み取り、編集アクセス権を変更しました。他は適宜変更してください。

## 列
<img width="649" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/1efd13c7-d99b-b395-e16e-6df00b7aba34.png">

- タイトル：必須→任意に変更しました。今回は特にしようしません。
- 追加/削除：メンバーの追加だけではなく削除もできるようにしたかったので、選択できるようにしました。
- 対象ユーザ：その名のとおり。
- 対象グループ：その名の通り。SharePointではグループだけの選択項目はなかったので、しかたなく「ユーザまたはグループ」にしています。
- ステータス：自動でと言っても、そのメンバーに入るべきでは無いのに入ってしまうのを防ぐために承認フローを走らせます。そのためのステータス欄です。

# PowerApps
図の通り、PowerAppsで入力不要なフィールドを削除しました。
<img width="301" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/f2750412-c2ed-cfb9-3eb3-57ab45328ade.png">
登録者フィールドは表示しなくても良いのですが、投稿への直接リンクをクリックしたときに、申請者(=登録者)が表示されないと面倒なので追加しました。これはお好みですね。

# PowerAutomate
旧称・Flowです。トリガーは上記で作成したリストにアイテムが追加されたらの「When a new item is created」です。
## グループIDを取得する
<img width="611" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/1cbc25d4-9ddd-5087-f4c8-a08678f597fb.png">
グループにユーザを追加するアクションはAzureADの「ユーザーをグループに追加」アクションなのですが、対象のユーザとグループは一意識別子である必要があります。ユーザの一意識別子はAzureADの「ユーザーの取得」アクションを使えば(キーはメールアドレス)取得できますが、グループの場合は一意識別子(=グループID)を取得できるようなアクションが見当たりません。

「When a new item is created」の動的コンテンツに良さそうなものがあります。
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/f36f7b73-0db0-8003-7354-76fb6e6c9c8e.png">
これのClaimsという項目が何を意味しているのか不明ですが、"xxxxx|yyyyyy|グループID"というフォーマットの文字列のようです。なので、このClaimsからグループIDを取得する必要があります。
Java的には以下のような感じになりますかね。

```java
グループID=対象グループClaims.substring(対象グループClaims.lastIndexOf('|')+1)
```

### 変数の初期化
まずは、最後の'|'の位置を格納するための変数を宣言(=初期化)します。
<img width="599" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/81c8d05a-3aaf-8a19-1b8d-6dcffdceb056.png">
値の部分は以下のようにしました。

```
lastIndexOf(triggerBody()?['OData__x5bfe__x8c61__x30b0__x30eb__x30']?['Claims'],'|')
```

OData__・・・の所はSharePointの列のIDになるので、この部分を変更すれば使えますが、動的コンテンツからトリガーの対象グループClaimsを選択してあげれば良いでしょう。

### インクリメント
上記で格納した値は'|'が最後に出てくる位置なので、文字列を切り取る場合は+1してあげる必要があります。PowerAutomateでは式の中で加算が使えないので、専用のアクションを使います。
<img width="605" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/5fbbd974-7c07-b0a3-0b83-5d318e7a9bde.png">
ここまで書いていて気付いたのですが、式には数学関数があるので、add関数を使えばこのような個別のアクションを作る必要はなかったのでした。

### 切り出し
切り出します。
<img width="600" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/4e4f4119-bd45-3342-8655-ba36b8473578.png">
値の部分は以下のようにしました。

```
substring(triggerBody()?['OData__x5bfe__x8c61__x30b0__x30eb__x30']?['Claims'],variables('グループClaimsの最後の|の位置'))
```

これでグループIDが取得できます。

## グループ追加
<img width="603" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245365/e8dd28d8-3128-dd33-e46f-5ff71baf92bd.png">
グループIDには上で取得したグループIDをセットします。ユーザIDは「ユーザーの取得」アクションを実行した結果を入れてあげればよいでしょう。
残りのアクションは割愛します。あとは承認フローとか。

# 動作確認
動作確認をしたところ、「Unable to update the specified properties for objects that have originated within an external service.」というエラーが発生して失敗してしまいました。
どうやらグループのタイプが「メールが有効なセキュリティグループ」なのが原因のようです。
調べてみるとGraphAPIのドキュメントに記載がありました。
[Working with groups in Microsoft Graph](https://docs.microsoft.com/en-us/graph/api/resources/groups-overview?view=graph-rest-beta)
Office365グループとセキュリティグループのみAPIで管理ができるようです。当社ではメーリングリスト代わりにグループを作っていましたが、全てメールが有効なセキュリティグループでした。PowerAutomate内部では結局はGraphAPIにリクエストを投げているだけなので、上記のマニュアルのとおり準ずると思います。
グループのタイプは後から変更できないっぽいので作り直しか方法はなさそうです。詰みました。

補足ですが、当社ではOffice365のグループをメーリングリスト、アクセス制御のグループとして使用できることを期待していました。Office365グループでもアクセス制御のグループとしては使用できます。
ただ、例えば課ごとのグループを作成。部のグループを作成し、そのメンバーとしてbyNameではなく課のグループを指定するっていうのはOffice365グループではできませんでした。これが出来るのが「メールが有効なセキュリティグループ」だけでした。