catch-img

【図解】社内外へのアウトプット/インプット同時投稿をノーコードで~Microsoft TeamsとTwitterを連携~

社外へのアウトプットをTwitterでツイートし、同時に社内インプットとしてTeamsへの投稿をFlowで連携してみます。

目次[非表示]

  1. 1. 社外アウトプットと社内インプットを同時にする目的
  2. 2. 連携イメージ(Twitter, Microsoft Flow, Microsoft Teams)
  3. 3. Microsoft Teamsの設定
  4. 4. Microsoft Flowの設定
  5. 5. テストしてみての課題
  6. 6. 課題1 「投稿者が自分になっている」
  7. 7. 課題2 「写真が投稿されない」
  8. 8. 当日の勉強会で使ってみました
  9. 9. やってみてのまとめ
  10. 10. すべてのビルダーにおすすめ

 

社外アウトプットと社内インプットを同時にする目的

こんにちは。ラーニングサービス本部 テクニカルトレーニング第一部 山下です。
今年もre:Invent 2019に参加できることになり(多分?)ものすごくテンションがあがっております。

AWS認定インストラクターというクラウド時代の人材育成な仕事をしながら、re:Inventに行きたいエンジニアさんはお気軽にご相談ください!
(re:InventとはAWSが開催している世界規模の年次カンファレンスです!)

さて、昨年のre:Inventの記録を確認しようと、弊社で利用しているMicrosoft Teamsの関連チャネルを確認しました。

syanaigai_teams_twitter_01

 

syanaigai_teams_twitter_02

 チャネルが散らばっていて我ながら見づらいです。
あと、Twitterにも書いてるのでTeamsにすべての情報がないです。

他の勉強会やカンファレンスでもTwitterがメインになっているので、社内でTwitter見てない人にはまったく届けられないことになります。
だからといって、Twitter投稿して、Teams書いてというのは面倒なので、やりたくないです。

なので連携します。

Microsoft Flowというサービスを使うとコードをまったく書かずに連携することもできます。
Microsoft Power Platformド素人な私ですが、後から発生した課題もあわせて、調べながら3時間ほどで実現できました。

APIや機能が充実しているので、普段コードを書いてない人やエンジニアではない人もチャレンジしてみる価値があると思いました!

 

連携イメージ(Twitter, Microsoft Flow, Microsoft Teams)

 

syanaigai_teams_twitter_03

Twitterユーザーなら誰でもいいのですが、私( @yamamanx )がTwitterに #trainocate_teams とハッシュタグをつけてツイートします。

Microsoft Flowで定義済みのタスクがTwitterのツイートを拾って、Teamsの特定チャネルに投稿します。

では設定した内容を図解していきます。

Microsoft Teamsの設定

syanaigai_teams_twitter_04

対象のチームを選択して、チャネルを作成します。

 

syanaigai_teams_twitter_05

「Twitter共有」というチャネル名にしました。
余談ですが、最近はチャネル名に絵文字を使うようにしてます。

 

Microsoft Flowの設定

 

Microsoft Flow(https://flow.microsoft.com/ja-jp/)にOffice365アカウントでサインインします。

とりあえず "twitter" でフローを検索してみます。

syanaigai_teams_twitter_06

 

たくさん出てきました。

"twitter teams"で絞り込んでみます。

syanaigai_teams_twitter_07

「新しいツイートが指定したハッシュタグと一致したときに Microsoft Teamsに投稿する」というドンピシャなフローがあります!

これを使います。

他にはSlack向けのものや、「否定的なツイートが投稿された場合に通知する」というのもあるのですね。

Translateも気になります。

「新しいツイートが指定したハッシュタグと一致したときに Microsoft Teamsに投稿するを選択します。

syanaigai_teams_twitter_08

TwitterとTeamsの認証が必要なのですね。

syanaigai_teams_twitter_09

Twitterを認証してできることは、

  • タイムラインのツイートを見る。
  • フォローしている人を見る、新しくフォローする。
  • プロフィールを更新する。
  • ツイートする。

タイムラインを見る以外は要らないだろうと思いつつも、大丈夫だろうと認証しました。
(もしも思いがけない何かがあればこちらで共有します。)

syanaigai_teams_twitter_10

Twitter側には検索文字列(今回はハッシュタグ)を、Teams側は投稿先のチャネルとメッセージの形式を設定しました。

syanaigai_teams_twitter_11-1

 [保存]をクリックすると「種類が必要です」というエラーになりました。

syanaigai_teams_twitter_11

 "Alert the team"という名前もなんだかなので、変更します。

[設定]メニューに[種類]という設定がありましたが、エラーメッセージの「種類」とはこれではないようです。

結局エラーは解消できなかったので、連携先のTeamsのコネクタを削除して、コネクタの追加から、Teamsへの投稿を追加しました。

syanaigai_teams_twitter_12

最終的にこうなりました。 

 

テストしてみての課題

 

syanaigai_teams_twitter_13

放置しておいても結果は見えますが、[テスト]からすぐに確認することもできました。

syanaigai_teams_twitter_14

これはこれで設定どおりにうまくいきました!

でも今回やりたかったことでは、これじゃない感があります。

  1. 投稿者が自分になっている。
  2. 写真が投稿されない。

この2点をクリアしたいです。
せっかくなので調べながらチャレンジしてみます。 

 

課題1 「投稿者が自分になっている」

 

Office365ユーザーを専用で作る、でもOKかもしれませんが、それはなんだか本来のユーザーの用途とは違うのかなと思います。

ですので、これはIncoming Webhookで解決してみます。
(社内ですでに設定済のフローがあって、それを元に調査しました。)

syanaigai_teams_twitter_15

まずTeamsのチャネル側でコネクタの設定をします。

syanaigai_teams_twitter_16

Incoming Webhookの[構成]を選択します。

syanaigai_teams_twitter_17

接続の名前を設定(今回はShareTweet)、イメージを設定(非公式キャラクターのとれのCATに連携してもらいます)して作成します。

生成されたURLをFlowで使用するのでコピーしておきます。
(後から構成済みメニューで確認することもできます)

syanaigai_teams_twitter_18

Flowで元のTeamsのアクションを削除して追加のアクションを "http"で検索し、HTTPを選択します。

syanaigai_teams_twitter_19

候補が3つ表示されるので、HTTPを選択しました。

syanaigai_teams_twitter_20

方法はPOST、URIにIncoming Webhookで生成されたURL、本文を指定すれば良さそうです。
本文はカード形式にするときには作法があるようで、その作法に則ります。

 

従来の操作可能なメッセージ カード リファレンス(https://docs.microsoft.com/ja-jp/outlook/actionable-messages/message-card-reference)

カードはJSONで記述します。
先ほどのリファレンスを見ると画像は heroImage キーを使えば実現できそうです。

最初の@2つはこうしてエスケープしておかないと「テンプレートの検証に失敗しました: '行 '1'、列 '1665' のテンプレート アクション 'HTTP' は無効です: "テンプレート言語式 'type' を解析できません: 必要なトークンは 'LeftParenthesis' で、実際は 'EndOfData' です。"。'。」というエラーになるためです。

syanaigai_teams_twitter_21

画面では、ツイートの名前やテキストを動的要素としてドラッグ&ドロップでコードを書かずに追加しているのですが、コピーして貼り付けると次のコードのようになります。

{  "@@type": "MessageCard",  "@@context": "http://schema.org/extensions",  "themeColor": "0076D7",  "sections": [    {      "activityTitle": @{triggerBody()?['UserDetails']?['FullName']},      "activityImage": @{triggerBody()?['UserDetails']?['ProfileImageUrl']},      "activityText": @{triggerBody()?['TweetText']},      "markdown": true    }  ]}   
triggerBody()?['TweetText']

 

上の図でTwitterアイコンが表示された要素部分は関数になっているのですね。
これでテストしてみたところ、「Summary or Text is required.」 Summaryキーがないのでエラーです。
リファレンスを見るとSummaryは統一されたテキストでいいそうなので、"ShareTweet"にします。
Summaryキーを足してもう一度です。

{  "@@type": "MessageCard",  "@@context": "http://schema.org/extensions",  "themeColor": "0076D7",  "Summary": "ShareTweet",  "sections": [    {      "activityTitle": @{triggerBody()?['UserDetails']?['FullName']},      "activityImage": @{triggerBody()?['UserDetails']?['ProfileImageUrl']},      "activityText": @{triggerBody()?['TweetText']},      "markdown": true    }  ]}

 

syanaigai_teams_twitter_22

とれのCATからの投稿でツイートをシェアできました。
ハッシュタグが見出しになってるのはmarkdown: true だからですね。
これを false にしてもう一回。

syanaigai_teams_twitter_23

できました!
次は写真です。

 

課題2 「写真が投稿されない」

リファレンスを見ていると、heroImage というキーが使えそうです。
まず固定の画像URLでやってみます。

{  "@@type": "MessageCard",  "@@context": "http://schema.org/extensions",  "themeColor": "0076D7",  "sections": [    {      "activityTitle": @{triggerBody()?['UserDetails']?['FullName']},      "activityImage": @{triggerBody()?['UserDetails']?['ProfileImageUrl']},      "activityText": @{triggerBody()?['TweetText']},      "markdown": false,      "heroImage": {        "image": "https://www.trainocate.co.jp/top_common/img/trainocate_logo.gif"      }    }  ],  "summary": "ShareTweet"}

これでやってみても全然表示されません。
情報も検索できなかったので、別の方法を考えます。

写真付きのツイートでテストをして、リクエスト側の本文を見てみたら、MediaUrlsという項目がありました。

syanaigai_teams_twitter_24

ここに画像のURLがあるので、これを表示してやればよさそうです。

sections の中でマークダウン表記でHTMLを書こうかと思いましたが、ハッシュタグを見出しにしない対応で markdown: falseにしてます。

ダウンがだめならアップだ!ということで<img>タグを書きます。
@{triggerBody()?['TweetText']}のように、@{triggerBody()?['MediaUrls']} とすれば画像のURLがとれそうです。

これをtextキーとしてsectionsの中で<img src>で指定するとよさそうです。

でもここで問題が2点あります。

  1. MediaUrls は配列なのでこのままじゃ多分だめ
  2. 画像があるときないときでtext キーのふるまいを変える必要あり

関数を使うことでなんとかならないか、関数のリファレンスを確認してみました。

Azure Logic Apps および Microsoft Flow でのワークフロー定義言語の関数リファレンス(https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference)

配列操作も、if分岐もできるようです。
残念ながらループはないように見えます。
FlowのアクションとしてForeachがあるので、おそらくそっちでループをまわして、1画像づつTeams連携アクションで処理する方法があるように思われます。

でも写真を何枚も1ツイートで貼ることはあまり考えたくないので、画像が1つでもあれば1つ目の画像を表示する、で今回は処理したいと思います。

該当の関数式はこちらになりました。
設定は1行で書いてますが、長いので当記事ではインデントと改行を入れてます。

 if(    equals(      length(        triggerBody()?['MediaUrls']      ),      0    ),    '',    concat(      '<img src="',      first(triggerBody()?['MediaUrls']),      '">'    )  )

さらにreplace関数を使って、テキストの改行対応もできました。

uriComponentToString(replace(uriComponent(triggerBody()?['TweetText']),'%0A','<br>')) 

最終的にFlowのHTTP POSTの本文はこうなりました。

{  "@@type": "MessageCard",  "@@context": "http://schema.org/extensions",  "themeColor": "0076D7",  "sections": [    {      "activityTitle": @{triggerBody()?['UserDetails']?['FullName']},      "activityImage": @{triggerBody()?['UserDetails']?['ProfileImageUrl']},      "activityText": @{uriComponentToString(replace(uriComponent(triggerBody()?['TweetText']),'%0A','<br>'))},      "markdown": false,      "text": @{if(equals(length(triggerBody()?['MediaUrls']),0),'',concat('<img src="',first(triggerBody()?['MediaUrls']),'">'))}    }  ],  "summary": "ShareTweet"}

 

syanaigai_teams_twitter_25

想定どおりの動作となりました。 これから使っていくにあたってもっとこうしたい、ああしたい、は出てくるとは思いますが、ひとまずこれで使い始めます。

 

当日の勉強会で使ってみました

この仕組みを構築した当日にちょうど勉強会「DevLOVE関西 グローバルの現場でのチームづくりの話(https://devlove-kansai.doorkeeper.jp/events/93083)」に参加予定でしたので早速使ってみました。

syanaigai_teams_twitter_26

ばっちりTeamsにも連携されました。
これを見た社内メンバーがコメントを書いて議論したり、勉強会に行ったことない人が勉強会に参加してみようって思ったり、単に情報ソースとして使ってもらったり、これきっかけで何か調べて結果を教えてくれたり、イベントのヒントにしたり、広がっていくといいなあ、と妄想しております。

 

やってみてのまとめ

Microsoft Flow初体験でした。

ノーコードで出来ることも、以前に比べてどんどん増えていってます。
それによって簡単に「システムとシステム」「システム間のデータ」「1つのインプット、複数のアウトプット」といった連携ができます。

TwitterにもTeamsにもAPIがあるから連携が簡単にできるのですね。
ということは、何かシステムの利用やSaaSの導入を検討するときに、そのサービスにはAPIがあるのか、使えるのか、ということをより意識しないといけないなと感じました。

今後できるようになるかもしれませんが、今回のように現時点では、JSONで本文を書かないといけなかったり、関数で分岐しないといけなかったりというようなローコードな要件もあるかもしれません。

ですが、できないから、で諦めるのではなく、少し調べればできることを知っておくと、いざというときの課題解決に役立ちます。
0をいきなり100にしなくても「ゼロをイチ」にして選択肢を増やしておくって本当に価値があることだと思いました。

最後にこのブログを書くにあたり当社のTeamsのブログレビューのスレッドで約50件ものリプライや質問がありました。
その中から生まれた言葉で締めくくりたいと思います。


Know Chords by NoCode (ノーコードで本当に必要な、チームの和音に気づきましょう)

 

※ノーコード/ローコードの区別は意見が分かれることも多々ありますが、当記事ではGUIだけで構築できるものをノーコード、JSONや関数など簡単なコードを記述するものをローコードとして書いています。

 

 

すべてのビルダーにおすすめ

エンジニアだけでなく、システムや仕組みを構築するすべてのビルダーにおすすめのコースです。

PowerAppsで実践する業務アプリのローコード開発ハンズオン

このコースでは、Office 365にてローコーディング開発をするために必要な、PowerApps、Common Data Service (CDS)、Microsoft Flowについてハンズオン形式で学習します。
自社のPC発注のストーリーをもとに、PC&タブレット用の入力フォームビジュアルの作成、Common Data Serviceでのデータ管理、Microsoft Flowによる自動化処理の作成について学習します。

kintone 02. アプリデザイナー編

kintoneのアプリの利用方法とアプリの作成方法・各パーツの機能を学び、目的に応じたアプリを構築するスキルを習得

 

 

山下 光洋(やました みつひろ)

トレノケート株式会社 講師。AWS Authorized Instructor Champion / AWS認定インストラクター(AAI) / AWS 認定ソリューションアーキテクト - プロフェッショナル /AWS認定DevOpsエンジニア - プロフェッショナル / AWS 認定デベロッパー - アソシエイト / AWS 認定 SysOps アドミニストレーター - アソシエイト / AWS 認定クラウドプラクティショナー / kintone認定 カスタマイズスペシャリスト他。AWS認定インストラクターとしてAWS認定コースを実施。毎年1,500名以上に受講いただいている。AWS 認定インストラクターアワード2018, 2019を日本で唯一受賞。著書『AWSではじめるLinux入門ガイド』(マイナビ出版社)。共著書『AWS認定試験対策 AWS クラウドプラクティショナー』(SBクリエイティブ社)。前職では2016年にAWS Summitにパネラーとして参加。その前はLotus Technical Award 2009 for Best Architectとして表彰されている。また、各コミュニティの運営にも個人的に関わり、勉強会にてスピーカーや参加をしている。

無料ダウンロード

オススメコンテンツ

オススメ記事

プロジェクトマネジメント PMP AWS ビジネススキル Microsoft PMBOKⓇ 田中淳子 IT資格 人材育成 山下光洋 AMA Azure コミュニケーション 人材開発用語集 PMBOK®ガイド入門 クラウド ITスキル 新入社員 横山哲也 人材育成応援ラジオ DX re:Invent セキュリティ PMP試験問題に挑戦 Cisco PMBOKⓇガイド 第6版 試験体験記 イベント・セミナー AI(人工知能) PMBOK®ガイド第6版の変更点 人材開発 CCIE CCNA テレワーク ネットワーク リモートワーク 研修 DX人材育成 GCP PMP(R)試験問題 第6版対応 PMP合格体験記 Windows Server AWS_Q&A Active Directory IT人材 IT資格解説 アセスメント キャリア デジタルビジネス ヒューマンスキル リーダーシップ 人気コースランキング 大喜利 部下の育成 AI人材 PMの心得 グローバル人材 新入社員研修といえば IoT OJT reinvent2022 リスキリング 生成AI CCNP Security Windows PowerShell クリエイティビティ プログラミング 人材トレンド 試験対策問題 PMP試験対策一問一答 コーチング プロジェクト プロトタイプビルダー 1on1 AWS_DiscoveryDay AWSトレーニングイベント GCP無料セミナー Google Cloud Google Cloud Platform G検定 ITインフラ oVice アワード クリティカルシンキング サンプル問題 ステークホルダー ダイバーシティ ディープラーニング ワーケーション 自律 試験Tips Linux PMI Power Platform Python Teams Web会議 cybozudays jawsdays2024