簡単絶品node.jsですぐできるTeams投稿

# [簡単絶品node.jsですぐできるTeams投稿](https://cookpad.com/recipe/6530547)
Teamsの「Incomming Webhook」アプリをProxy越しに叩いて、YOLP(地図)APIから取ってきた降雨情報を投稿してみました♪

# 材料

* Microsoft Windows 10
* Microsoft Teams
* node.js
    * `$npm install request` 必須
    * `$npm config set proxy "http://<userid>:<password>@<server-address>:<port>"`　お好みで。
* Yahoo!API
    * YOLP(地図)
        * 気象情報API
        * 郵便番号検索API
    * Yahoo!API ID（各自取得してね。）
* VSCode
* Proxy Server URL　ご自身の環境に合わせてください。
* [Microsoft Teams API (Incoming Webhook) で投稿 -- Qiita](https://qiita.com/wataash/items/72b49509c3964294dd67) ありがとうございます。

# 作り方

1. node.jsをインストールする。
    2. 最新の安定バージョンをインストールしてください。
2. `$npm install request` で、requestモジュールをインストールする。
3. Teamsの「チーム」にIncomming WebhookをインストールしてエンドポイントURLを取得する。([Microsoft Teams API (Incoming Webhook) で投稿 -- Qiita](https://qiita.com/wataash/items/72b49509c3964294dd67))　＃画像を引用しております。 
![画像を拝借しております。](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F167409%2F68ef98fb-7ac5-a91d-1343-6f224eee06ba.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=1696749e38ad90e93e17a37d5116b814)
4. YOLP(地図）の[郵便番号検索API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/zipcodesearch.html)に郵便番号を入力して、郵便番号地域の緯度経度情報を取得します。
5. YOLP(地図）の[気象情報API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/weather.html)に緯度経度情報を入力して、その地域の現在の降雨情報と1時間後までの降雨予報を取得します。
    1. Proxyを越えてrequest.get()する場合、Proxyのアドレスが必要になります。ご自身の環境をお確かめください。
    2. request.get()する前に、optionsの`proxy: proxy_url,`でProxyサーバーへのアドレスを設定すれば良いみたいです。どこでそれを覚えたかは忘れました。実環境で動作したことを確認したので、それでいいのでしょう。
6. 4,5で取得した情報からTeamsへ投稿するメッセージをMarkdown記法で作成します。
7. node.jsからエンドポイントURLへメッセージをrequest.post()します。
8. `$node app.js`を実行してください。
9. Teamsの自分が作成したチームへメッセージが投稿されていることを確認してください。

![2020-12-21_15_10_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103572/bcb494fd-33b0-260c-e55d-f5d056fbd128.png)

# このSouceの生い立ち

私が仕事をしているフロアは窓がありません。昼休み、外へ出ると雨が降っていて折りたたみ傘を取りに戻ることがありました。昼休み前、帰宅直前にある地域の降雨情報や降雨予報情報があったら便利だと思いませんか？
と、ふとおもったので、なんとなく作ってみました。

<details><summary>レシピコード app.js(157行)</summary><div>

```javascript:app.js
//Rain Notifer for Teams
var request = require('request');//$ npm install request

//Japan Post
var zipaddress = "https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=";
//Proxy URL
const proxy_url = "http://<id>:<password>@<hostname>:<port>";//(TODO)modify
//Yahoo! API ID = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
const appId = "&appid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //(TODO)modify
//Teams Webhook URL
const TEAMS_URL = "https://outlook.office.com/webhook/....."; //(TODO)modify

//https://www.j-lis.go.jp/spd/code-address/todouhuken/cms_16914188.html

var zip = "060-8588";//北海道
//var zip = "163-8001";//東京都
//var zip = "540-8570";//大阪府
//var zip = "812-8577";//福岡県	
//var zip = "900-8570";//沖縄県	

var zipcode = CheckPostCode(zip);

var url = "https://map.yahooapis.jp/search/zip/V1/zipCodeSearch?query=" + zipcode + "&output=json" + appId;

//console.log(url);

var options = {
    url: url,
    proxy: proxy_url,
};

request.get(options, function (error, res, body) {
    if (error) {
        //console.log(error);
        return null;
    }

    //console.log(body);

    var json = JSON.parse(body);

    var count = json["ResultInfo"]["Count"];

    //console.log(count);

    if (count > 0) {
        var Feature = json["Feature"][0];
        var coordinates = Feature["Geometry"]["Coordinates"];

        //console.log(coordinates);

        if (coordinates != null) {

            var url = "https://map.yahooapis.jp/weather/V1/place?coordinates=" + coordinates + "&output=json" + appId;

            var options = {
                url: url,
                proxy: proxy_url,
            };

            request.get(options, function (error, res, body) {
                if (error) {
                    //console.log(error);
                    return null;
                }

                var infoObject = new Object();

                var json = JSON.parse(body);

                //console.log(body);

                var Feature = json["Feature"][0];
                var WeatherList = Feature["Property"]["WeatherList"]["Weather"];
                var Rainfall = WeatherList[1]["Rainfall"];
                var result = coordinates.split(',');

                infoObject['rainfall'] = Rainfall;
                infoObject['lon'] = result[0];
                infoObject['lat'] = result[1];

                var message = getMessage(infoObject);

                postTeams(message);

            });
        }
        else {
            return null;
        }
    }
});

function postTeams(message) {

    var options = {
        uri: TEAMS_URL,
        headers: {
            "Content-type": "application/json",
        },
        json: {
            "text": message //markdown format is OK.
        },
    };

    request.post(options, function (error, response, body) {
        console.log("statusCode = " + response.toJSON().statusCode);
    });
}

function getMessage(info) {

    if (info != null) {

        //メッセージを作成する
        var rainfall_msg = makeMessage(info.rainfall);

        var message = "# -- Yahoo!気象情報 -- \n\n";
        message += "郵便番号：" + "[" + zipcode + "](" + zipaddress + zipcode + ")" + "\n\n";
        message += "現在の降雨情報：" + rainfall_msg + " ";
        message += "[(雨雲レーダー - Yahoo!天気・災害)](https://weather.yahoo.co.jp/weather/zoomradar/?lat=" + info.lat + "&lon=" + info.lon + "&z=13)\n\n";
        //message += "[郵便番号](https://www.post.japanpost.jp/zipcode/index.html)(xxx-xxxx)を送信すると，その地域の現在の降雨情報を表示します．\n\n";

        return message;
    }
    else {
        return "降雨情報は取得できませんでした。入力した郵便番号が正しいか確認してね。";
    }
}

function makeMessage(Rainfall) {

    if (Rainfall == 0.0) {
        message = "今、雨は降っていません。";
    } else if (Rainfall < 10.0) {
        message = "弱い雨が降っています。";
    } else if (Rainfall < 20.0) {
        message = "やや強い雨。ザーザーと降っています。";
    } else if (Rainfall < 30.0) {
        message = "強い雨。土砂降りで、傘をさしていてもぬれる雨が降っています。";
    } else if (Rainfall < 50.0) {
        message = "激しい雨。傘持ってる? バケツをひっくり返したように雨が降っています。";
    } else if (Rainfall < 80.0) {
        message = "非常に激しい雨。滝のように非常に激しい雨が降っています。";
    } else if (Rainfall >= 80.0) {
        message = "猛烈な雨。土砂降りで、傘をさしていてもぬれる雨が降っています。";
    }

    return message;
}

function CheckPostCode(postCode) {
    var pattern = /^\d{3}-?\d{4}$/g;
    var result = postCode.match(pattern);

    return result;
}

```

</div></details>

# コツ・ポイント

## Proxy越え
```javascript:app.js
var options = {
    url: url,
    proxy: proxy_url,
};
```
request.get()でYahoo!APIにアクセスしたら、Proxyで弾かれました。色々調べた結果、proxyを設定することで解決しました。

# bot化?

ボットに郵便番号を送信するとその地域の降雨情報を教えてくれる仕組みを、とあるチャットシステムで作ったことはあるのですが、現場のTeamsではoutgoing Webhookがありませんでした。

最近？Microsoftのサイトで[outgoing Webhook](https://docs.microsoft.com/ja-jp/microsoftteams/platform/webhooks-and-connectors/how-to/add-outgoing-webhook)についての記事を見つけました。私の環境ではoutgoing Webhookが無効になっているかもしれません。

Teamsでカスタムボットを作った方がいれば、リンクを教えて下さい。:grinning: