Power Automate: 運行情報を取得して TeamsとSMSで通知

# 背景
関東に越してきて、久しぶりの通勤電車
愛知の際には経験したこともない遅延が頻発して、駅に着いてから在宅勤務に変えること二度目

ということで、運行情報を課内共有＆自身へ通知することで、楽をしようってお話

ただ、駅までの往復も運動不足解消には良いことなので、無駄は無駄としててもいいような気もする

# 概要

ポイント

-  運行情報は、各路線毎別々に取得すると面倒だが、無償がいい
    -  [Yahoo](https://transit.yahoo.co.jp/diainfo) が一番？
-  SMSの通知は？
    -  ちょっと前にイベントもやってた [Twilio](https://www.twilio.com/) の無償枠かな
-  利用数をどう減らすか？AutomateのCallも減らしたいので
    -  SMS通知は減らしたい
        -  変化検知をする必要があるので、OneDrive に
    -  Teams通知は、取得した時刻は表示したい、が、投稿しまくりはうざい
        -  [Adaptive Card の更新](https://qiita.com/baku2san/items/78264b8e3d5abf1f67f8)とする。
            -  この場合、最新化しても通知をしないので、以下考慮必要
                -  固定化してすぐみられるように
                -  SMS通知タイミングで、Feed。＜今回はこれはパス
    -  起動制限もかける
        - [スケジュール実行を平日8:00-18:59 の間だけ動かす](https://qiita.com/baku2san/items/66fc8067072ffc740ad1)

以上の、フローを作ってみる

# 通知イメージ
- Teams 通知
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/51565ccd-5377-3e65-0c94-1d24aebdfcf6.png)

- SMS 通知
上記の詳細部分を送るだけなので省略

# フロー

## 全体
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/89dae375-3537-3a56-30ba-2c6784a7fead.png)

基本は以下
- スケジュール実行
- 運行情報取得
- SMS通知
- Teams通知

## スケジュール実行
基本は以下で、定期実行

https://qiita.com/baku2san/items/66fc8067072ffc740ad1

## 運行情報取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/b7f024bc-eeff-7412-19dc-f1b18900186d.png)

1. スクレイピング用にファイルをOneDriveにあげる
1. コンテンツを取得して
1. Run Script で正規表現を使って運行情報を取得
      ```typescript: Yahoo運行情報から、詳細と更新日時を取得する
    function main(
    	workbook: ExcelScript.Workbook,
    	originalText: string
    ): string {
    	// originalText = '                 <dt><span class="icnNormalLarge">[○]</span>平常運転</dt><dd class="normal"><p>16: 05現在、ほぼ平常通り運転しています。<span>（7月15日 16時5分掲載）</span></p></dd></dl>'
    
    	var expressionText = '<dd class="trouble"><p>(.+?)<span>(.+?)</span></p></dd>'
    	var expression = new RegExp(expressionText);
    	var matches = originalText.match(expression);
    
    	var expressionTextNormal = '<dd class="normal"><p>(.+?)(<span>(.+?)</span>)?</p></dd>'
    	var expressionNormal = new RegExp(expressionTextNormal);
    	var matchesNormal = originalText.match(expressionNormal);
    
    	console.log(matches);
    	console.log(matchesNormal);
    	var details = matches ? matches[1] : matchesNormal[1];
    	var updated = matches ? matches[2] : matchesNormal[3];
    	var hasTrouble = matches ? true: false;
    	var result = JSON.stringify({ details, updated, hasTrouble });
    
    	console.log(result);
    	return result;
    }
    ```
1. 取得した結果を、Parse JSON で使いやすく

    ```json: Parse JSON
    {
        "type": "object",
        "properties": {
            "details": {
                "type": [
                    "string",
                    "null"
                ]
            },
            "updated": {
                "type": [
                    "string",
                    "null"
                ]
            },
            "hasTrouble": {
                "type": [
                    "boolean",
                    "null"
                ]
            }
        }
    }
    ```

## Teams通知
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c2e04960-227a-9d06-889e-3744bc8edeba.png)

1. <details ><summary>Card 情報を生成</summary>   

   ```json: 運行情報用Card
    {
      "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
      "type": "AdaptiveCard",
      "version": "1.4",
      "msteams": {
        "width": "full"
      },
      "body": [
        {
          "type": "TextBlock",
          "text": "運行情報 at @{body('Convert_time_zone')}",
          "wrap": true,
          "color": "Accent"
        },
        {
          "type": "Container",
          "items": [
            {
              "type": "ColumnSet",
              "columns": [
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "ActionSet",
                      "actions": [
                        {
                          "type": "Action.OpenUrl",
                          "title": "小田急",
                          "url": "https://www.odakyu.jp/cgi-bin/user/emg/emergency_bbs.pl"
                        }
                      ]
                    }
                  ]
                },
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "TextBlock",
                      "text": "@{body('Parse_JSON')?['details']}",
                      "wrap": true
                    }
                  ]
                },
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "TextBlock",
                      "text": "@{body('Parse_JSON')?['updated']}",
                      "wrap": true
                    }
                  ]
                }
              ]
            },
            {
              "type": "ColumnSet",
              "columns": [
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "ActionSet",
                      "actions": [
                        {
                          "type": "Action.OpenUrl",
                          "title": "湘南新宿ライン",
                          "url": "https://traininfo.jreast.co.jp/train_info/line.aspx?gid=1&lineid=shonan-shinjukuline"
                        }
                      ]
                    }
                  ]
                },
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "TextBlock",
                      "text": "@{body('Parse_JSON_Shinzyuku')?['details']}",
                      "wrap": true
                    }
                  ]
                },
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "TextBlock",
                      "text": "@{body('Parse_JSON_Shinzyuku')?['updated']}",
                      "wrap": true
                    }
                  ]
                }
              ]
            },
            {
              "type": "ColumnSet",
              "columns": [
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "ActionSet",
                      "actions": [
                        {
                          "type": "Action.OpenUrl",
                          "title": "東海道本線",
                          "url": "https://traininfo.jr-central.co.jp/zairaisen/index.html?lang=ja"
                        }
                      ]
                    }
                  ]
                },
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "TextBlock",
                      "text": "@{body('Parse_JSON_tokaidoHonsen')?['details']}",
                      "wrap": true
                    }
                  ]
                },
                {
                  "type": "Column",
                  "width": "stretch",
                  "items": [
                    {
                      "type": "TextBlock",
                      "text": "@{body('Parse_JSON_tokaidoHonsen')?['updated']}",
                      "wrap": true
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
   ```
    </details>

1. Update Card をするだけ
:::note info
Update Card をする為には、事前に Card 投稿をしておくことが必要 :p
:::

https://qiita.com/baku2san/items/78264b8e3d5abf1f67f8

## SMS通知
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/9ec6d93f-0300-8ba4-8be2-ce5ac3bd921b.png)

1. SMS通知用のメッセージ生成
```text: Compose Notification Message
@{if(body('Parse_JSON')?['hasTrouble'], body('Parse_JSON')?['details'], '')}
@{if(body('Parse_JSON_Shinzyuku')?['hasTrouble'], body('Parse_JSON_Shinzyuku')?['details'], '')}
@{if(body('Parse_JSON_tokaidoHonsen')?['hasTrouble'], body('Parse_JSON_tokaidoHonsen')?['details'], '')}
```
1. 通知抑制用の前回メッセージの取得と比較
1. 変化があった場合には、前回メッセージとして上書き保存
1. Twilioを利用して、SMS通知
　　※登録して、無料トライアルで使うだけ

https://www.twilio.com/ja-jp


# あとがき

特定の会社だけの通知サービスならあるみたいだけど、全路線共通サービスってのはないんですかねぇ


JRの例

https://faq.jr-odekake.net/faq_detail.html?id=4867