序
さてさて、今年もやって来ましたね。Advent Calendar の季節です。前日になっても埋まっていない穴を発見したので、日頃のコミュニティの皆さまへの恩返しも兼ねて、こちらの記事で塞いでしまおうと思います。
雑談なのですが、この季節はアウトプットがたくさんで嬉しい一方「何か書かないといけない(焦)」という気持ちにもなって大変です(※この気持ちになるのが嫌です!という話ではなく「皆さんにお尻を叩いてもらっていますよ」という話です)
つい最近読んだ note にもそんなことが書かれてありました。アウトプットに関して悩んでいる人がいらっしゃいましたら、こちらも一読の価値は大いにあると感じております。
やりたいこと
今回やりたいことは、SharePoint ニュースの投稿通知をメール送信するというものです。SharePoint の設定の方で実装できそうなものですが、かゆいところに手が届きません(以下の画像を参照)
実装のポイントは次のとおりです:
- SharePoint ニュースを新規投稿したときだけメールが送信される
- その新規投稿には、下書きからの投稿も含まれる
- 編集された場合はメール通知されない
開発環境や組織の権限などの差で、当記事にある設定をそのまま流用することはできない場合がありますが、何か参考になるようなものがあれば幸いです。フローの全体像は以下の通り:
Special Thanks
今回の記事は、太田さんの記事を参考にしています。概ね、この記事をマネすれば完結してしまう内容ではあるのでコチラを読んでいただければと思います。
それでも、この記事をわざわざ書いている理由は「記事を投稿している途中に自動保存されるタイプの更新も Power Automate が拾ってしまう」というお悩みに対処できているかなと思ったからです。困っている方はお試しいただければと思います(検証なので自己責任で)
トリガーの設定
使用するトリガーは「ファイルが作成または変更されたとき(プロパティのみ)」です。入力必須項目である「ライブラリ名」のドロップダウンリストを展開して「カスタム値の入力」をクリックします。
「サイトのページ」を直接入力して、設定タブに切り替えます。ここで、トリガーが実行される条件を設定していきます。
上画像の「トリガーの条件」に数式を2つ入力します。
//1つ目
@equals(triggerBody()?['{VersionNumber}'],'1.0')
//2つ目(追加ボタンをクリック)
@equals(triggerBody()?['PromotedState'],2)
このあたりの説明は、"Special Thanks" にて紹介した太田さんの記事に詳しいですが、少しだけ補足説明してみましょう。
この数式は、Power Automate を実行した後で見ることのできる(JSON形式の)情報から;
- {VersionNumber} に含まれている値と、
- PromotedState に含まれている値
の2個所に、それぞれ "1.0" と 2 が含まれているかどうかを検知するためのものです。
今回の場合だと、{VersionNumber} に "1.0" があり、PromotedState に 2 が含まれているかどうかを検出するためのものです。
VersionNumber は、文字通り、投稿されたニュースのバージョン情報であり、"1.0" は、投稿されたばかりの記事に適用される数値です。
一方、PromotedState は(これも文字通りといえば文字通りなのですが)SharePoint ニュースを投稿したのかしていないのかを表す数値であり、
- 1は「ニュースを投稿する」ボタンが押される前の状態を、
- 2は「ニュースを投稿する」ボタンが押された後の状態
をそれぞれ示しています。ステータス0もありますが、このあたりの説明は、平野愛さんの以下の書籍(p.143)に詳しいです。重版おめでとうございます(ここで言うな)
ということで、今回は「投稿されたばかりの記事」かつ「投稿ボタンを押された記事」を検知して Power Automate のフローが実行する…という仕組みになっています。このあたり、ちょっと難しい。
JSON形式の出力を整形したり抽出したりする方法は、この記事では解説しませんが、至るところで説明されています。随分前になりますが、当時、自分が苦戦していた頃にまとめたスライドがあるので、こちら参考文献の方をご笑覧ください(情報が古いので、関連する Microsoft Learn の情報とも照らし合わせてくださいね)
メールアドレスを取得する
次に、このニュースを読んで欲しい人にメールを送信するための情報を「SharePoint に HTTP 要求を送信します」アクションで取得します。特に、メールアドレスがないとメールは送れないので、メールアドレスの情報に絞ってお話をします。
入力必須項目の「サイトのアドレス」には、ニュースを投稿しているサイトを選択し、方法に GET メソッドを選択します。URI には、以下の呪文を唱えます。
_api/web/sitegroups/getByName('サイト名 所有者')/users
今回は、SharePoint サイトの権限を割り当てられているユーザーなので「所有者」ではなく「閲覧者」が適切だと思います(テストで作ったまま放置してました)。これで、メールアドレスなど、アクセス権を割り当てられたユーザー情報を開示できるというわけですね。
ここで一度 Power Automate を実行します。メールアドレスの記載された配列が JSON 形式で戻ってくるので、それを「選択」アクションで取得していきます。
//From に入力する式
body('SharePoint_に_HTTP_要求を送信します')?['d']?['results']
//Map の左辺
Email
//Map の右辺
item()['Email']
これでメールアドレスが取得できるので、Apply to each アクション内に「メールの送信(V2)」アクションを挿入してしまえば、メールの送信自体は可能です。
この部分はコピペで実装できるはずですが、実装後の運用で何か起きた時に困るのはフローの作成者ですので、JSONデータをどうやって取得するのか…というところの理解は必須です。
筆者も最初はできませんでした。でも、頑張って読んでいく内に書けるようにもなっていました。慣れです。JSONコワクナイ。
さて、1つ。注意点としては Power Automate の要求数に制限がある点です。大きな組織(部署)となると特に、このあたりの制限にも注意を向ける必要があります。
この場合は Apply to each の使用を控えたり(送信先A; 送信先B; 送信先C という形式でメールアドレスを入力できるようにする)、メール送信を複数のフローに分けたりするなどの対策が必要です。このあたりの情報は公式文書でしっかりと確認しておくのが吉です(ゼッタイだよ!)
まあ、一番の対策は Teams で業務を回せるようにしてメールを送信しない風土を作ることだと思いますが「段階的な導入」に尽力されている場合もあると思うので、追記という形で記しておきます。
リンクをメール本文に埋め込みたい
最後、コンテンツを埋め込みたい場合があると思います。というか、絶対にそうしたいはずです。しかし、嬉々として、直接メール本文に記事の URL を動的コンテンツとして貼り付けてもリンクではなく、単なる文字列として扱われてしまいます。
その際は、上の画像のように「作成」アクションを使用して、このアクションを動的コンテンツとしてメール本文に埋め込むことで実現できます。
<a href="投稿した記事のURL"> URLとして利用される文字 </a>
ここで HTML のタグを書いておいて、該当箇所にトリガーで取得した動的コンテンツを次のように挿入することで…
<a href="@{triggerBody()?['{Link}']}">@{triggerBody()?['Title']}</a>
文字列ではなく、リンクとして機能します。
メールアドレスのテキスト整形については踏み込みません。他の同士たちのコンテンツ(記事など)も参照していただき、色んな出会いを楽しんでいただければと思います。
結
前日のお昼に参加登録し、この日の業務終了後に記事執筆というチキンレースとなり、まとまっていない文章になっていると思います。読みにくいなどありましたら申し訳ありません。が、ふんわりでも良いので、何かしら皆さまのお役に立てていただけたのであれば幸いです。
他、埋まっていない日付がありましたらまたお会いしましょう。
それでは、また。