メールを保存するニーズある?
QiitaのQ&Aで見かけた内容が面白そうだったので、Power Automateで実装してみます。本当はOutlookのVBAで処理を作りたいようなのですが、目的を達したいだけならこの方法でもよいかと思いまして。よかったら参考にしてください。
条件は以下の通り
社内メールを受信後にセキュリティ面も考慮して、件名・ドメイン名・特定の拡張子等が一致する場合のみメールの状態のまま(本文と添付ファイル)、管理・検索しやすいようにファイル名を自動で変更して保存するシステムを開発したいと考えております。
ということです。
ここでは仮に、条件を以下のようにしてみます。
- ドメインが mocabrown.com からのメールのみ動作する
- 件名は「メール送ります」の場合のみ動作する
- 添付ファイルがついていて、その拡張子が .xlsx の場合のみ動作する
仕様を考える
以下のような仕様にしようと思います。
- メールがとどいたら、必要な条件に合うメールだけをOutlook Onlineの機能でメールをフォルダ分けする
- Power Automateは、特定のフォルダにメールが届いた場合に動作を開始する
- 届いたメールの本文をSharePoint OnlineのListsに書き込む
- メールに添付されているファイルは、yyyymmdd_書き込んだリストのID.xlsx で、指定のSharePoint Onlineのドキュメントフォルダに保存する
- SharePoint OnlineのListには、保存したファイルのURLを書き込む
条件にあうメールをOutlook Onlineでフォルダに振り分ける
Office.comを開き、画面左上の9つの点のボタンを開き、「Outlook」をクリックしてOutlook Onlineを開きます。
条件に合うメールだけを振り分けるために、フォルダを新規作成します。
画面右のほうにある「・・・」ボタンから、「ルール」>「ルールを管理」を開きます。
とりあえず、このような条件で設定してみました。
実際にテストメールを送信してみます。しっかり振り分けられました。これで準備OKです。
メール受信をトリガーにする
まずは、自分自身にメールが届くことで処理の開始を起こします。何かをきっかけに動作を始めるので「自動化したクラウドフロー」です。
フローに名前をつけ、Outlookのトリガーのなかから、「新しいメールが届いたとき(v3)」を選び、作成をクリックします。
最初の設定は、どのフォルダにメールが届いたときに動作を開始させるかを表しています。ここでは、先ほど作成した「条件に合ったメール」のフォルダを指定します。
「詳細オプションを表示します」の部分をクリックして開きます。
「添付ファイルを含める」と、「添付ファイル付きのみ」の項目を、どちらも「はい」にします。件名や誰から届いた場合かなどは、すでにOutlook Onlineのフォルダ振り分けで指定しているので、ここでは設定不要です。条件がかわったときに、Outlook側で調整すればよいので、このほうが楽かと思います。
「新しいステップ」をクリックして「作成」をひとつ作ったら、入力欄に動的なコンテンツから「本文」を選択します。
ここまで出来たら、とりあえずメールがとどいたときの動作をみるために、いったん保存して「テスト」ボタンを押し、「手動」を選択して「テスト」をクリックします。
Power Automateがメール受信待ちの状態になるので、ふたたび条件に合うメールを送信してみます。
テストがうまくいきました。「作成」のなかには、トリガーとなったメールの本文に書いた内容が見えています。
SharePoint OnlineのListsを用意する
メールを条件に合わせて受信するところまで成功したので、今度はメールの内容を保存する場所をつくります。本文はSharePoint Listsに保存するので、適当なサイトにリストを新規で作成します。
新規でリストを追加して、空白のリストをつくります。
こんな感じに名前をつけました。
本文列をテキスト形式で「MainMessage」。添付ファイル保存URLの列をハイパーリンク形式で「URL」となづけて追加しました。
設定ボタンから「リスト設定」を選び・・・
「タイトル」をクリックして・・・
「この列への情報の入力を必須にする」を「いいえ」に変えてから右下の「OK」をクリックしましょう。いまのところタイトル列は使いません。
ファイルの保存場所もSPO上に確保する
リストとおなじく、SharePointサイト上に適当なフォルダを作成して、ファイルの保存場所にしましょう。
今回はドキュメントフォルダのなかに「添付ファイル保存フォルダ」を新規作成しました。
つづいて、保存する添付ファイルの名前に利用するために、メールが届いた日付をつくります。トリガーにはUTC時間という日本時間より9時間前の日時が記録されているので、画像のようにタイムゾーン変換をつかいます。書式設定文字列に「yyyyMMdd」といれておくと、年月日の数字が並んだものを取得できます。
さらにつづけて「ファイルの作成」をつくります。サイトアドレスとフォルダーのパスは、さきほどSPO上につくったフォルダを指定します。ファイル名の先頭には、タイムゾーンの変換の結果を置き、アンダーバーでつないで「項目の作成」の「ID」の項目を加えます。最後に.xlsxを記載しておきます。
「ファイルコンテンツ」のところに、トリガーから拾った「添付ファイルコンテンツ」を置くと同時に、自動的に「ApplyToEach」のループに囲まれます。
これは、添付ファイルが1つだけとは限らないため、ループを回して複数の添付ファイルを順番に処理しようとしてくれるためです。
今回は、添付ファイルはひとつだけ、というお約束で進めます。
全体をみると、こんな感じのつながりになりました。準備ができたら「テスト」を実行しましょう。今回は「自動」で進めます。前回に手動でトリガー時間を選択してやると、わざわざメールを送りなおしてトリガーを発動させる必要がなくなります。
テストの結果
リストには本文が書きこまれました。
添付ファイル保存用のフォルダには、日付とリストのID番号がついたファイルが保存されています。ひとまずここまで成功です。
結果を見ておさらい
ここまでの結果を見てこの後やることのおさらいです。
- リストに追加されたMainMessageはHTMLタグが付いていて見にくいので消したい
- ファイルのURLがまだリストのURL列に書き込めていない
- 添付ファイルの拡張子が何でも動作してしまう
さっそく上の課題を解決していきましょう。
HTMLタグを取り除く
これは簡単。「項目の作成」の前に「HTMLからテキスト(プレビュー)」を追加し、トリガーの本文をコンテンツ欄に入れます。
一方、「項目の作成」のもともと「本文」が入っていたところには、「HTMLからテキスト」の結果を置きます。
リストのURL列に書き込む
ApplyToEachの中の「ファイルの作成」の下に「項目の更新」を追加します。項目の更新は、リストの特定のIDの特定の列の内容を更新する処理をしてくれます。
IDにはApplyToEachより上ですでに本文をリストに書き込んだ部分の「項目の作成」から「ID」を取得します。URL列には直前に処理をおこなっている「ファイルの作成」から「Path」を持ってきます。
ファイルパスの前半が足りない
自動で再びテストしてみましょう。
おや?項目の更新のところでエラーとなってしまいました。
エラーの内容を確認すると、SharePointリストの列の型を「ハイパーリンク形式」で作成しているのに、Pathのなかには'"/Shared Documents/添付ファイル保存フォルダ/20230601_4.xlsx"'としか入っていないので、前半のhttpsから始まる部分が抜けているためのようです。
動的な項目にサイトのURLが見当たりませんでした。変数にしてもよいですが、とりあえず手っ取り早くPathの前に直書きしてみました。
気を取り直して、再度テストを実行です。何度かテストしたので添付ファイルはリストのIDが変わりながら保存されています。
リストの側も見てみます。最初はHTMLタグが含まれていた本文はすっきりして、URLには自動保存された添付ファイルの場所URLが記録されています。ID列はこのリストのレコードID自体を参照しているので、同じ日に複数メールが届いても重複することはありません。
xlsx拡張子以外の場合は処理をやめる
このままだと、どんな拡張子の添付ファイルの場合も動作してしまうので、早い段階で条件分けを加えましょう。
まず試しに作成にトリガーの中から「添付ファイルの名前」を入れてやると、自動的にApplyToEachが作られます。これは前述のとおり添付ファイルがひとつだけとは限らないからです。
今回は割り切って添付ファイルは一つだけで、つまり配列の0番目が添付されているファイルの名前と割り切ってみます。
スクリーンショットを見ると、どの部分にファイル名が隠れているかわかります。
ApplyToEachの下にあらためて作成を作り、参考にしながら直接式を書いてみます。作成2の中にはこのような式を入れました。
triggerOutputs()?['body/attachments'][0]?['name']
テスト実行すると、しっかり添付ファイルの名前が取得できました。ループでファイル名を取得していた部分は不要なので、「ApplyToEach2」は削除しておきます。
あとは、このファイル名の最後に「.xlsx」を含んでいなければ処理終了させるだけです。
添付ファイルがない場合は、トリガー自体がされませんので、ちょっと強引ですが一通り仕様を満たせました。
さいごに
あとは工夫するとすれば複数のファイルが添付されていたときに、ループにカウンターをつけて、ファイル名の最後に数字を加えて新たな行を追加してやるとかでしょうか。
もっとスマートな方法もあるかと思いますが、とりあえずこんなことができたらなぁ、が簡単につくれるのがPower Automateの素敵なところです。
全体のスクリーンショットを置きましたのでよかったらお使いください。