Power AutomateとOffice Scriptを利用してメールからデータを抽出する仕組みを作る

# はじめに
Power Automateの強味として、**自動化したクラウドフロー**の利用が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/cb122eaf-d271-e992-044e-6af79880c2d4.png)
この機能の中で凄いな、と思っているのは __指定されたイベントによってトリガーされる__ このトリガーの中に、
GmailとOutlookでのメール受信も含まれていることです。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/30e08f20-264a-a23f-bd6b-66b2b96ded2d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/b05bb2cf-140d-73ce-420d-832ec536be1c.png)

今回は __新しいメールが届いたときメールの文面から「正規表現」を使い、必要なデータをExcel Onlineに自動でストックしていく方法を解説したいと思います__ 

# 注意
本記事では「正規表現」の詳細な内容にまでは触れません。「私が使って便利だな」と感じている表現のみ書きます。
正規表現を使えば、文字列から検索する __パターン__ を指定することでサクっとデータが取り出すことができ、大変便利ですが、奥深い世界であり、正規表現の内容を列挙するだけで立派な書籍が出来上がるほどです。

詳しく学ばれたい方は下記の本を推奨します。

https://www.oreilly.co.jp/books/9784873113593/

## Power Automateで「正規表現」を利用するためには
Power Automateに、メールのテキストを渡し、必要なデータを抽出するためには、この __正規表現__ を利用することが効果的です。
しかしながら、正規表現を利用するには、Excel Online Fileに書く __Office Script__ を使う必要があります。

 * 下記の「スクリプトの実行」が正規表現を使って、必要な要素を返すステップに該当しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/75d89478-51d3-00e6-f8ab-ec7fd7c78781.png)

私たちのビジネスにおいて、Teamsを中心としたチャットによるタスクの設定などもPower Platformでは可能です。
しかしSaaSを中心に、登録された内容やリマインダーから、メールという媒体から情報をキャッチすることも度々あることも事実です。

__定型的にメールに情報が記載されるのであれば、__ 人の手を介して情報をスプレッドシートにまとめるという行為は、
手間でありミスが起こるポイントでもあります。

`今回はそういった転記作業からの脱却`にお力添えできればと思い、記事を書かせていただきました。

# Goal
今回目指すのは下記の様なExcel Onlineのシートに、メールの情報が自動で転記されることです。
 - 日付
 - 店舗
 - 金額

上記の3要素です。SaaSの製品でもリマインダーとして、このような情報がメールで届く例もあります。
それを見て、Excelに転記するってことは __ナンセンス！__ 今すぐやめましょ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/6623854c-e393-3344-6f09-2b7fe39a70a5.png)

# 具体的な手順
さて、まずはフローを見てみます。

## 1. __自動化したクラウドフローを構築する__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/0d92c7fe-6a04-4f00-00ca-e11069bbdc5e.png)

Microsoft様の製品連携バージョンでお届けします！

# Office Script サンプルコード
インターネットに多く挙げられていますが、下記のブログのコードを紹介させてください。

https://www.teijitaisya.com/powerautomate-regex/

RegExpオブジェクトを作成して、パターンにマッチする文字を返せる汎用的で美しいコードです。
世の中に発信していただいたことに深く敬意を表します。

こちらでも引用をさせてください。

```TypeScript:RegularExpressions
function main(workbook: ExcelScript.Workbook, text: string, pattern: string, flags: string): string[] {
  let ptn = new RegExp(pattern, flags);
  return text.match(ptn) ?? [];
}
```

> オフィス スクリプトは TypeScript で書かれており、JavaScript のスーパーセットです。 JavaScript に慣れている場合は、コードの多くが両言語で共通しているため、知識を引き継ぐことができます。

https://learn.microsoft.com/ja-jp/office/dev/scripts/develop/scripting-fundamentals

learnの引用になります。Java Scriptの兄弟分のような存在であるようです。
書き方に差異はあるものの、Google Apps Scriptを学んでいたことから馴染みやすい印象を受けます。

ちなみにType Scriptの学習は『サバイバルTypeScript』というこれでもか！というほどの入門コンテンツがあるので学ぶ環境は十分です。

https://typescriptbook.jp/

大切なのは・・・自分の気持ちですね・・・

***
## 2. __Outlookの設定をする__
今回は「Outlookの受信トレイ」にメールが届いた場合を想定して進めます。
大切なことですが、**メールアプリケーション**には**標準で「メールの振り分け」であったり、
「ラベルの付与」といった機能が設けられておりますので、**メールアプリケーションの設定**も
この仕組みでは大切な要素になります。

### 具体的なフローが起動する仕組み
仕組みの解像度をより高めていきます。
自動化の内容は下記のとおりです。

1. `【ほげほげPay】利用明細のお知らせ`というタイトルのメールがOutlookで受信されたとき
1. 受信したメールの本文から**必要な情報を正規表現で抽出し**
1. Excel Onlineのデータに転記する

こちらが今回の自動化の内容になります。

個人のメールアカウントでやるので、少し内容が粗いところもありますが、ご了承ください。

 - **実際に届くメールのイメージ**
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/7d248407-0d7e-ac26-2d6f-c36f2a2124c4.png)


 - **Outlookでルールを設定**
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/68b104a7-c75c-bc97-21fd-6a05e90e8738.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/81461b7c-3999-5133-c0b8-15bd6cd96563.png)

:::note info
OutlookでもGmailでも、このような**メール受信時の対処を設定する機能**は充実しています。
また直感的な操作で設定できるため、活用をおススメします。
:::

## 3. __自動化したクラウドフローを作り込んでいく__
上記の準備が完了したら、クラウドフローの活用も着々と進めることができます。
    - **Power Automateのトリガー**
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/b6d316fc-91ee-6bab-97d2-c0c15978aec2.png)

Power Automate側でも**何のメールが届いたか**、上記の通り設定することができます。
Outlook側での設定をおススメしましたが、全部Power Automateで管理したい、という場合は
好みで細かく設定するところを決めれば良いでしょう。

https://learn.microsoft.com/ja-jp/power-automate/email-triggers

このトリガーでメールを取得した際に手に入る**戻り値は多い**です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/748f7d5c-0c8d-08d2-5408-0a7becc038ae.png)

この中で使う値は「本文のプレビュー」`@{triggerBody()?['bodyPreview']}`になります。
他にも戻り値がありますが、この値の特徴は、**メールのプレーンテキストが取得できること**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/5ae5683d-ba61-f7fa-b5ef-928ff135080f.png)

HTML形式で評価されたテキストの場合、`<body>~~`のようにタグが多くあり、利用しづらい特徴があります。
プレーンテキストであれば、自分が実際に見るメールの文字そのものを評価して活用することができるので、
こちらの利用を私はお勧めいたします。

**そのうえで、走らせる次のステップはこちらです**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/d051b2e6-1366-4e89-678a-a1bea78ce16a.png)

Office Scriptが実際に起動しているものですね。
正規表現は
```
(?<=支払金額\s+)\d.*(?=円)
```
上記が該当します。
フラグの「g：グローバルマッチ」です。
文字列の最後まで検索を繰り返します。複数該当した場合は、配列で値を返す、ということです。

サンプルのメールを実際に送ると、**正規表現**により、オブジェクトで返されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/19e05041-1e1d-164e-3825-9d2523e3f1d7.png)

**ここまで来たら活用の道が見えてきましたね！**

***
## クラウドフロー全体像
今回のフローで取得したいのは
 - ご利用日時
 - ご利用店舗
 - 支払金額

この三点です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/1f3b87b2-e9b5-4f92-68d9-666b2973fc38.png)

取得したものをこちらに転記します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/f3e14191-4bc0-0425-f319-a95fee8b0409.png)

今、私が思いつく方法は、2パターンです。

### 1. 都度、正規表現を使って実現するパターン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/d577ecf9-ca5f-0d38-913b-dc0424917149.png)

最後に転記しやすいように*配列*に結果を格納して、Excelの転記に使っています。
またOffice Scriptのデータを取得する際は、今回の場合グローバルマッチを正規表現で採用していることから
**「スクリプトの実行」の戻り値は配列**になっています。

データを取得する際には添え字にインデックスが必要です。

:::note warn
警告
Office Scriptをフローに加える際は実行時間に注意してください。
今回の例でも約10秒近くかかります。
:::

今回の正規表現の例です。
```JavaScript:
// スクリプトの実行　日時
(?<=ご利用日時\s+)\d.*
// スクリプトの実行　店舗
(?<=ご利用店舗　　).*
// スクリプトの実行　支払金額
(?<=支払金額\s+)\d.*(?=円)
```

### フローの結果
Excelのテーブルに無事転記することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/26632367-bbf0-973d-0da8-f9ed696fc78e.png)

#### このフローの問題点
Power Automateの中で内容が冗長になること、実行時間がかかることから、
Office Scriptの実行を何度もPower Automateの中に入れるということは悪手である可能性があります。

よりスマートな書き方を目指すのであれば、一度Office Scriptにデータを渡した際に、
**欲しいデータがまとめて取得できる**この方がスマートといえましょう。

***

### 2. Office Scriptで必要なデータをまとめて取得するパターン
せっかくコードを書くのであれば、スクリプト内でほしいデータをまとめて取得できたほうがスマートです。
サンプルとして今回書いた例をご紹介します。

```TypeScript:RegularExpressions2
function main(workbook: ExcelScript.Workbook, text: string) {
  let result = {};
  let regex: string[] = [];

  regex = text.match(/(?<=ご利用日時\s+)\d.*/g);
  if (regex != null) { result["date"] = regex[0];}
  else { result["date"] = "null"; }

  regex = text.match(/(?<=ご利用店舗　　).*/g);
  if (regex != null) { result["shop"] = regex[0];}
  else { result["shop"] = "null"; }

  regex = text.match(/(?<=支払金額\s+)\d.*(?=円)/g);
  if (regex != null) { result["payment"] = regex[0];}
  else { result["payment"] = "null"; }

  return result;
}
```
:::note warn
お願い
コードはドンドン修正してください🙇
:::

この例でフローを実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/9e716ee0-0446-9350-f0a3-c388df496928.png)

**戻り値がオブジェクトで出力されました✨**

フロー実行時間も圧倒的に短縮されます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/407def1d-b1ea-1f40-50f4-7c42f1f2a7fc.png)

 - Excelの結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/0c0b4529-3cb1-f6a3-cfaf-7c2c7e64c6c4.png)

Office Scriptの活用でメールが情報自動収集ツールに化ける！
とても素敵です！！

本当におススメ技なので紹介させていただきました！

# 最後に！
登壇やTwitterなどいろいろ動いてますので、TwitterをFollowしてくださると嬉しいです！
**記事のいいね！もHappyです！！**

https://twitter.com/DemodoriGatsuo

# 終わりに
検証をしていく中で、Outlookの`本文のプレビュー`機能でテキストが全て拾えているのか怪しい場面がありました。
その場合は`本文`を取得してScriptの中で文字列のタグ情報を正規表現で除去することをお勧めします。

```TypeScript:タグをキレイにするコード
  // argvが引数の場合、このreplaceで変更が可能かと！
  let text = argv.replace(/(<([^>]+)>)/g, '');
```

最後までお読みいただきありがとうございました🙇🙇