背景
Teams で大量のメンバーがいる際に、特定のキーワードで検索した一覧が欲しい時があったので作ってみた。
概要
-
出力したファイル名に付加する為、ID からTeam情報を取得
-
Trigger から、Rest API 用の Filter/取得上限を生成
-
Graph API でメンバー一覧取得
-
CSV 生成
-
ファイルに保存して、リンクを取って
外観
詳細
躓きポイントは以下ぐらい?
New Designer だと、For a selected message が現状未対応
ってことで、Old Designer に戻して作る必要がある
フローのコピーペーストも、New Designer ではまだ制約が大きいけど・・
Graph API
- API の使い方によっては使えない
- OK: https://graph.microsoft.com/v1.0/groups/{groupId}
-
NG: https://graph.microsoft.com/v1.0/groups('{groupId}')
どちらも、Graph Explorer なら問題ないのに・・
- 検索方法
- 以下で、Startswith なんかの例もあるので、よしなに
サンプルコード
adaptive card
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"msteams": {
"width": "full"
},
"body": [
{
"type": "TextBlock",
"text": "このチームのメンバー一覧をCSVにして、OneDriveに保存します。",
"weight": "Bolder",
"size": "Medium",
"color": "Attention"
},
{
"type": "TextBlock",
"text": "現状、人数は100人のままです。最大999。フィルター使おう",
"wrap": true,
"color": "Warning"
},
{
"type": "Input.Text",
"placeholder": "DisplayName に対してフィルターする文字を入れてください",
"id": "FilterForDisplayName",
"label": "Filter For DisplayName"
},
{
"type": "Input.Number",
"placeholder": "取得数上限を入れてください",
"label": "取得メンバーの上限",
"value": 100,
"min": 1,
"max": 999,
"errorMessage": "メンバー上限を入れてください",
"id": "MemberTopLImit"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "作成するぜ"
}
]
}
{"id":"04e2d2b4-1d2f-4aaf-9495-46f974f30c4c","brandColor":"#8C3900","connectionReferences":{"shared_office365groups_1":{"connection":{"id":"/providers/Microsoft.PowerApps/apis/shared_office365groups/connections/5e96053ddc264f998e74dbe3ccf3ef9c"}},"shared_onedriveforbusiness_1":{"connection":{"id":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness/connections/shared-onedriveforbu-60023b13-318a-4e0f-a004-302d9501e437"}},"shared_teams":{"connection":{"id":"/providers/Microsoft.PowerApps/apis/shared_teams/connections/shared-teams-864099d5-54a7-4002-93b6-565ecf481128"}}},"connectorDisplayName":"Control","icon":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=","isTrigger":false,"operationName":"Scope","operationDefinition":{"type":"Scope","actions":{"Get_a_team":{"type":"OpenApiConnection","inputs":{"host":{"connectionName":"shared_teams","operationId":"GetTeam","apiId":"/providers/Microsoft.PowerApps/apis/shared_teams"},"parameters":{"teamId":"@triggerBody()?['teamsFlowRunContext']?['channelData']?['team']?['aadGroupId']"},"authentication":{"type":"Raw","value":"@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"}},"runAfter":{},"metadata":{"operationMetadataId":"c6661b5a-064a-4019-a310-d3e71cd381e9"}},"Compose_Filter":{"type":"Compose","inputs":"@if(empty(triggerBody()?['cardOutputs']?['filterForDisplayName']), '', concat('&$search=\"displayName:', encodeUriComponent(triggerBody()?['cardOutputs']?['filterForDisplayName']), '\"'))","runAfter":{"Get_a_team":["Succeeded"]},"metadata":{"operationMetadataId":"ebd22013-9d6d-4dbc-963b-cb4dc4d13877"}},"Select":{"type":"Select","inputs":{"from":"@body('Send_an_HTTP_request_V2')['value']","select":{"UserPrincipalName":"@item()['userPrincipalName']","Displayname":"@item()['displayName']","SurName":"@item()['surName']","GivenName":"@item()['givenName']","Mail":"@item()['mail']"}},"runAfter":{"Send_an_HTTP_request_V2":["Succeeded"]},"metadata":{"operationMetadataId":"41e64b55-f8fd-463a-93a3-8d28cc641689"}},"Create_CSV_table":{"type":"Table","inputs":{"from":"@body('Select')","format":"CSV"},"runAfter":{"Select":["Succeeded"]},"metadata":{"operationMetadataId":"abf5d606-c041-4016-a480-834e3db4595e"}},"Create_file":{"type":"OpenApiConnection","inputs":{"host":{"connectionName":"shared_onedriveforbusiness_1","operationId":"CreateFile","apiId":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness"},"parameters":{"folderPath":"/FlowCreated/MembersCsvs","name":"MembersOf@{outputs('Get_a_team')?['body/displayName']}@{if(empty(triggerBody()?['cardOutputs']?['filterForDisplayName']), '', concat('_filteredBy', triggerBody()?['cardOutputs']?['filterForDisplayName']))}_@{body('Convert_time_zone')}.csv","body":"@concat(uriComponentToString('%EF%BB%BF'), body('Create_CSV_table'))"},"authentication":{"type":"Raw","value":"@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"}},"runAfter":{"Convert_time_zone":["Succeeded"]},"runtimeConfiguration":{"contentTransfer":{"transferMode":"Chunked"}},"metadata":{"operationMetadataId":"0e9137cb-6ae5-4071-b6fb-847b34dd5e1b"}},"Create_share_link":{"type":"OpenApiConnection","inputs":{"host":{"connectionName":"shared_onedriveforbusiness_1","operationId":"CreateShareLinkV2","apiId":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness"},"parameters":{"id":"@outputs('Create_file')?['body/Id']","type":"View","scope":"Organization"},"authentication":{"type":"Raw","value":"@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"}},"runAfter":{"Create_file":["Succeeded"]},"metadata":{"operationMetadataId":"70570745-93cf-4459-932c-818f1ea9c9a6"}},"Post_message_in_a_chat_or_channel":{"type":"OpenApiConnection","inputs":{"host":{"connectionName":"shared_teams","operationId":"PostMessageToConversation","apiId":"/providers/Microsoft.PowerApps/apis/shared_teams"},"parameters":{"poster":"Flow bot","location":"Chat with Flow bot","body/recipient":"@{triggerBody()?['teamsFlowRunContext']?['from']?['aadObjectId']};","body/messageBody":"<p>@{outputs('Compose')}</p>"},"authentication":{"type":"Raw","value":"@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"}},"runAfter":{"Compose":["Succeeded"]},"metadata":{"operationMetadataId":"a64b0116-38fd-428e-96bc-0d10d223d607"}},"Compose_Top":{"type":"Compose","inputs":"@if(empty(string(triggerBody()?['cardOutputs']?['memberTopLImit'])), '', concat('&$top=', string(triggerBody()?['cardOutputs']?['memberTopLImit'])))","runAfter":{"Compose_Filter":["Succeeded"]},"metadata":{"operationMetadataId":"c2061e77-2380-49f7-b2e0-a646de2856af"}},"Send_an_HTTP_request_V2":{"type":"OpenApiConnection","inputs":{"host":{"connectionName":"shared_office365groups_1","operationId":"HttpRequestV2","apiId":"/providers/Microsoft.PowerApps/apis/shared_office365groups"},"parameters":{"Uri":"https://graph.microsoft.com/v1.0/groups/@{triggerBody()?['teamsFlowRunContext']?['channelData']?['team']?['aadGroupId']}/members/microsoft.graph.user?$count=true&$orderBy=displayName&$select=displayName,givenName,jobTitle,mail,surname,userPrincipalName,id,userPrincipalName@{outputs('Compose_Filter')}@{outputs('Compose_Top')}","Method":"GET","ContentType":"application/json","CustomHeader1":"ConsistencyLevel: eventual"},"authentication":{"type":"Raw","value":"@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"}},"runAfter":{"Compose_Top":["Succeeded"]},"metadata":{"operationMetadataId":"a37d42b1-e6c0-465d-ad8a-b40a70b17435"}},"Current_time":{"type":"Expression","kind":"CurrentTime","inputs":{},"runAfter":{"Create_CSV_table":["Succeeded"]},"metadata":{"operationMetadataId":"021254d1-b987-4877-b8c0-1012507b1b66"}},"Convert_time_zone":{"type":"Expression","kind":"ConvertTimeZone","inputs":{"baseTime":"@body('Current_time')","formatString":"yyyyMMdd","sourceTimeZone":"UTC","destinationTimeZone":"Tokyo Standard Time"},"runAfter":{"Current_time":["Succeeded"]},"metadata":{"operationMetadataId":"a9021c08-f59a-4342-af79-3dbc8f21b191"}},"Compose":{"type":"Compose","inputs":"<p><a href=\"@{outputs('Create_share_link')?['body/WebUrl']}\">@{outputs('Create_file')?['body/Name']}</a></p>","runAfter":{"Create_share_link":["Succeeded"]},"metadata":{"operationMetadataId":"4088f3b5-cdce-44ee-ac03-e91270e3a1ea"}}},"runAfter":{},"metadata":{"operationMetadataId":"63f93a96-4357-49c5-8d54-b86d0cbac008"}}}
あとがき
GraphAPI は便利なんだけど、Automate で使うと制約に意外に躓くのがたまにきず
実装コードって公開されてたら見に行きたいぐらい・・ってあるん?