背景
複数チャネルへの投稿機能はあるものの、単純にメッセージを転送する方法が欲しいなと思ったので作ってみた記録
課題
- 添付ファイルは未対応
- 取得して、転送先へUpload&Link置換が必要
- 同様に、転送元に対するLinkも未対応
- 転送時、件名(Subject)を入れられないので、Bold指定してる・・
- スレッド全体の転送
- 親メッセージであっても、子メッセージを取得してとかはしてないので。
概要
詳細
Actionは、Scope単位でクリップボード共有のJsonを記録
選択したメッセージからの起動トリガー
選択されたメッセージに対して (V2)
で、対象のメッセージから起動させる
起動用Adaptive Card
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": "Teams 転送",
"wrap": true
}
],
"actions": [
{
"type": "Action.Submit",
"title": "開始"
}
]
}
Teamの選択
Adaptive Card で転送先のTeamを選択させる
コード例
Teamの選択
{
"id": "b97d757d-806f-4306-9680-e2c1e1765ad3",
"brandColor": "#8C3900",
"connectionReferences": {
"shared_teams": {
"connection": {
"id": "/providers/Microsoft.PowerApps/apis/shared_teams/connections/shared-teams-16d937a3-3608-4ff1-826c-5e345b32810f"
}
}
},
"connectorDisplayName": "Control",
"icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=",
"isTrigger": false,
"operationName": "Select_Team",
"operationDefinition": {
"type": "Scope",
"actions": {
"List_teams": {
"type": "OpenApiConnection",
"inputs": {
"host": {
"connectionName": "shared_teams",
"operationId": "GetAllTeams",
"apiId": "/providers/Microsoft.PowerApps/apis/shared_teams"
},
"parameters": {},
"authentication": {
"type": "Raw",
"value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
},
"runAfter": {},
"metadata": {
"operationMetadataId": "c860f3c1-226e-45bf-86ac-442d0193dc2a"
}
},
"Select_TeamName_Array": {
"type": "Select",
"inputs": {
"from": "@outputs('List_teams')?['body/value']",
"select": {
"title": "@item()?['displayName']",
"value": "@item()?['id']"
}
},
"runAfter": {
"List_teams": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "ea6a6424-4c01-41bf-b508-f8f051c63a7a"
}
},
"Compose_SelectionTeamNames": {
"type": "Compose",
"inputs": {
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"msteams": {
"width": "full"
},
"version": "1.4",
"body": [
{
"type": "Container",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Thread転送",
"weight": "bolder"
}
]
},
{
"type": "Column",
"width": "auto",
"id": "collapseImage",
"isVisible": true,
"items": [
{
"type": "Image",
"url": "https://adaptivecards.io/content/down.png",
"width": "20px",
"altText": "collapsed"
}
]
},
{
"type": "Column",
"width": "auto",
"id": "expandImage",
"isVisible": false,
"items": [
{
"type": "Image",
"url": "https://adaptivecards.io/content/up.png",
"width": "20px",
"altText": "expanded"
}
]
}
],
"selectAction": {
"type": "Action.ToggleVisibility",
"targetElements": [
"collapse",
"expand",
"collapseImage",
"expandImage",
"collapsedItems",
"expandedItems"
]
}
}
]
},
{
"type": "Container",
"id": "collapsedItems",
"isVisible": false,
"items": [
{
"type": "TextBlock",
"weight": "Bolder",
"text": "@{triggerBody()?['teamsFlowRunContext']?['messagePayload']?['subject']}"
},
{
"type": "TextBlock",
"weight": "Lighter",
"size": "Small",
"text": "@{triggerBody()?['teamsFlowRunContext']?['messagePayload']?['body']?['plainText']}"
}
]
},
{
"type": "Container",
"separator": true,
"items": [
{
"type": "TextBlock",
"text": "転送先のTeamを選択してください。",
"wrap": true,
"color": "Accent"
},
{
"type": "Input.ChoiceSet",
"choices": "@body('Select_TeamName_Array')",
"placeholder": "フィルター機能は、1.5 対応後・・・",
"isMultiSelect": false,
"style": "filtered",
"id": "TeamSelection",
"spacing": "None"
},
{
"type": "TextBlock",
"text": "選んだTeams内のChannelに投稿します。",
"wrap": true,
"spacing": "None",
"horizontalAlignment": "Right",
"size": "Small",
"weight": "Lighter",
"color": "Warning"
}
]
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "転送先Teamを決定",
"wrap": true,
"style": "positive"
}
]
}
]
},
"runAfter": {
"Select_TeamName_Array": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "9f6179c7-9398-4251-9117-44d715c61005"
}
},
"Post_adaptive_card_and_wait_for_a_response_selectedTeam": {
"type": "OpenApiConnectionWebhook",
"inputs": {
"host": {
"connectionName": "shared_teams",
"operationId": "PostCardAndWaitForResponse",
"apiId": "/providers/Microsoft.PowerApps/apis/shared_teams"
},
"parameters": {
"poster": "Flow bot",
"location": "Chat with Flow bot",
"body/body/messageBody": "@outputs('Compose_SelectionTeamNames')",
"body/body/updateMessage": "Thanks for your response!",
"body/body/recipient/to": "@{triggerBody()?['teamsFlowRunContext']?['from']?['AadObjectId']}\n;"
},
"authentication": {
"type": "Raw",
"value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
},
"runAfter": {
"Compose_SelectionTeamNames": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "c22398ec-f7af-47e3-b8f1-aba340a5113a"
}
},
"Compose_SelectedTeamID": {
"type": "Compose",
"inputs": "@outputs('Post_adaptive_card_and_wait_for_a_response_selectedTeam')?['body/data/TeamSelection']",
"runAfter": {
"Post_adaptive_card_and_wait_for_a_response_selectedTeam": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "aed0e5c9-bad8-4718-ae74-0cf714857e87"
}
},
"Condition_CheckCancelAtTeam": {
"type": "If",
"expression": {
"equals": [
"@outputs('Compose_SelectedTeamID')",
""
]
},
"actions": {
"Terminate": {
"type": "Terminate",
"inputs": {
"runStatus": "Cancelled"
},
"runAfter": {}
}
},
"runAfter": {
"Compose_SelectedTeamID": [
"Succeeded"
]
}
}
},
"runAfter": {
"Post_a_choice_of_options_as_the_Flow_bot_to_a_user": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "0819bb5a-b245-468e-958a-56670298d017"
}
}
}
Channelの選択
転送先TeamのChannel一覧から、転送先のChannelを選択させる
コード例
Channelの選択
{
"id": "05f3427a-3a15-4782-a75f-c6a253a30c88",
"brandColor": "#8C3900",
"connectionReferences": {
"shared_teams": {
"connection": {
"id": "/providers/Microsoft.PowerApps/apis/shared_teams/connections/shared-teams-16d937a3-3608-4ff1-826c-5e345b32810f"
}
}
},
"connectorDisplayName": "Control",
"icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=",
"isTrigger": false,
"operationName": "Select_Channel",
"operationDefinition": {
"type": "Scope",
"actions": {
"List_channels_on_selectedTeam": {
"type": "OpenApiConnection",
"inputs": {
"host": {
"connectionName": "shared_teams",
"operationId": "GetChannelsForGroup",
"apiId": "/providers/Microsoft.PowerApps/apis/shared_teams"
},
"parameters": {
"groupId": "@outputs('Compose_SelectedTeamID')"
},
"authentication": {
"type": "Raw",
"value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
},
"runAfter": {},
"metadata": {
"operationMetadataId": "fa350674-6924-451c-ad5e-52a6636b0997"
}
},
"Select_TeamChannelInfo": {
"type": "Select",
"inputs": {
"from": "@outputs('List_channels_on_selectedTeam')?['body/value']",
"select": {
"title": "@item()?['displayName']",
"value": "@item()?['id']"
}
},
"runAfter": {
"List_channels_on_selectedTeam": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "30969f22-73f2-464e-ab20-d0a6d8159eeb"
}
},
"Compose_SelectionChannelNames": {
"type": "Compose",
"inputs": {
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"msteams": {
"width": "full"
},
"version": "1.4",
"body": [
{
"type": "Container",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Thread転送",
"weight": "bolder"
}
]
},
{
"type": "Column",
"width": "auto",
"id": "collapseImage",
"isVisible": true,
"items": [
{
"type": "Image",
"url": "https://adaptivecards.io/content/down.png",
"width": "20px",
"altText": "collapsed"
}
]
},
{
"type": "Column",
"width": "auto",
"id": "expandImage",
"isVisible": false,
"items": [
{
"type": "Image",
"url": "https://adaptivecards.io/content/up.png",
"width": "20px",
"altText": "expanded"
}
]
}
],
"selectAction": {
"type": "Action.ToggleVisibility",
"targetElements": [
"collapse",
"expand",
"collapseImage",
"expandImage",
"collapsedItems",
"expandedItems"
]
}
}
]
},
{
"type": "Container",
"id": "collapsedItems",
"isVisible": false,
"items": [
{
"type": "TextBlock",
"weight": "Bolder",
"text": "@{triggerBody()?['teamsFlowRunContext']?['messagePayload']?['subject']}"
},
{
"type": "TextBlock",
"weight": "Lighter",
"size": "Small",
"text": "@{triggerBody()?['teamsFlowRunContext']?['messagePayload']?['body']?['plainText']}"
}
]
},
{
"type": "Container",
"separator": true,
"items": [
{
"type": "TextBlock",
"text": "転送先の Channel を選択してください。",
"wrap": true,
"color": "Accent"
},
{
"type": "Input.ChoiceSet",
"choices": "@body('Select_TeamChannelInfo')",
"placeholder": "フィルター機能は、1.5 対応後・・・",
"isMultiSelect": false,
"style": "filtered",
"id": "ChannelSelection",
"spacing": "None"
},
{
"type": "TextBlock",
"text": "選んだTeams内のChannelに投稿します。",
"wrap": true,
"spacing": "None",
"horizontalAlignment": "Right",
"size": "Small",
"weight": "Lighter",
"color": "Warning"
}
]
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "転送先Team/Channelを決定",
"wrap": true,
"style": "positive"
}
]
}
]
},
"runAfter": {
"Select_TeamChannelInfo": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "5158f7ca-5204-46d3-b3d9-3802f0eccc0f"
}
},
"Post_adaptive_card_and_wait_for_a_response_selectedChannel": {
"type": "OpenApiConnectionWebhook",
"inputs": {
"host": {
"connectionName": "shared_teams",
"operationId": "PostCardAndWaitForResponse",
"apiId": "/providers/Microsoft.PowerApps/apis/shared_teams"
},
"parameters": {
"poster": "Flow bot",
"location": "Chat with Flow bot",
"body/body/messageBody": "@outputs('Compose_SelectionChannelNames')",
"body/body/updateMessage": "Thanks for your response!",
"body/body/recipient/to": "@{triggerBody()?['teamsFlowRunContext']?['from']?['AadObjectId']};"
},
"authentication": {
"type": "Raw",
"value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
},
"runAfter": {
"Compose_SelectionChannelNames": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "c22398ec-f7af-47e3-b8f1-aba340a5113a"
}
},
"Compose_SelectedChannelID": {
"type": "Compose",
"inputs": "@outputs('Post_adaptive_card_and_wait_for_a_response_selectedChannel')?['body/data/ChannelSelection']",
"runAfter": {
"Post_adaptive_card_and_wait_for_a_response_selectedChannel": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "b6bceed5-43d0-4adf-b58a-6df14dcfe8d5"
}
},
"Condition_CheckCancelAtChannel": {
"type": "If",
"expression": {
"equals": [
"@outputs('Compose_SelectedChannelID')",
""
]
},
"actions": {
"Terminate_2": {
"type": "Terminate",
"inputs": {
"runStatus": "Cancelled"
},
"runAfter": {}
}
},
"runAfter": {
"Compose_SelectedChannelID": [
"Succeeded"
]
}
}
},
"runAfter": {
"Select_Team": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "b4d29d38-68f7-4190-897e-c8cf80336ecb"
}
}
}
Message転送
あとは、転送するだけ
コード例
Message転送
{
"id": "196fd284-6237-4e46-829a-1cdaea9ef213",
"brandColor": "#8C3900",
"connectionReferences": {
"shared_teams": {
"connection": {
"id": "/providers/Microsoft.PowerApps/apis/shared_teams/connections/shared-teams-864099d5-54a7-4002-93b6-565ecf481128"
}
},
"shared_flowmanagement": {
"connection": {
"id": "/providers/Microsoft.PowerApps/apis/shared_flowmanagement/connections/shared-flowmanagemen-7143b7a4-a5cb-4de9-8676-f10e-b4a3a73d"
}
}
},
"connectorDisplayName": "Control",
"icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=",
"isTrigger": false,
"operationName": "TransferMessageAsParentThread",
"operationDefinition": {
"type": "Scope",
"actions": {
"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": "Channel",
"body/recipient/groupId": "@outputs('Compose_SelectedTeamID')",
"body/recipient/channelId": "@outputs('Compose_SelectedChannelID')",
"body/messageBody": "<p><strong></strong><strong>@{triggerBody()?['teamsFlowRunContext']?['messagePayload']?['subject']}</strong><strong></strong><br>\n@{triggerBody()?['teamsFlowRunContext']?['messagePayload']?['body']?['content']}</p>"
},
"authentication": {
"type": "Raw",
"value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
},
"runAfter": {},
"metadata": {
"operationMetadataId": "2cb00491-f733-41e0-b54a-228f4a38eed7"
}
},
"Post_message_in_a_chat_or_channel_FinishedNotification": {
"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": "以下に転送しました。\n<p><a href=\"@{outputs('Compose_TransferedChannelLink')}\">転送先チャネルへ</a> </p>\n\n<backquote><strong>\n@{triggerBody()?['teamsFlowRunContext']?['messagePayload']?['subject']}</strong><br/>\n</backquote>"
},
"authentication": {
"type": "Raw",
"value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
},
"runAfter": {
"Compose_TransferedChannelLink": [
"Succeeded"
]
}
},
"Compose_TransferedChannelLink": {
"type": "Compose",
"inputs": "https://teams.microsoft.com/l/channel/@{outputs('Compose_SelectedChannelID')}/%25E6%25A9%259F%25E8%2583%25BD%25E7%25A2%25BA%25E8%25AA%258D?groupId=@{outputs('Compose_SelectedTeamID')}&tenantId=@{outputs('Compose_tenantID')}",
"runAfter": {
"ExtractTenantID": [
"Succeeded"
]
}
},
"ExtractTenantID": {
"type": "Scope",
"actions": {
"List_My_Environments": {
"type": "OpenApiConnection",
"inputs": {
"host": {
"connectionName": "shared_flowmanagement",
"operationId": "ListUserEnvironments",
"apiId": "/providers/Microsoft.PowerApps/apis/shared_flowmanagement"
},
"parameters": {},
"authentication": {
"type": "Raw",
"value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
},
"runAfter": {},
"metadata": {
"operationMetadataId": "9a3f17f3-e58a-419e-ae2b-a1d6fe3298c4"
}
},
"Filter_array": {
"type": "Query",
"inputs": {
"from": "@outputs('List_My_Environments')?['body/value']",
"where": "@contains(item()?['name'], 'Default')"
},
"runAfter": {
"List_My_Environments": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "be4305b2-9929-4205-911c-cc5e1b11634e"
}
},
"Compose_tenantID": {
"type": "Compose",
"inputs": "@replace(first(body('Filter_array'))['name'], 'Default-', '')",
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "c1d509ab-04e8-4962-80cb-3769fa205fe9"
}
}
},
"runAfter": {
"Post_message_in_a_chat_or_channel": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "3bd9fe04-cf30-4cf0-a817-27e02b478e32"
}
}
},
"runAfter": {
"Select_Channel": [
"Succeeded"
]
},
"metadata": {
"operationMetadataId": "19ee1cdc-ea8f-4da5-8338-640a6a10d806"
}
}
}
あとがき
まぁ、とりあえず現状はこれで、そのうち課題対応するか・・どうか・・
keyword
how to transfer Teams Message in chat or channel