GasでBacklogの通知をTeamsに流す

# はじめに
通知をslackに流す記事は良く見るのですが、
Teamｓに流すのそんなになかったし、とりあえず作ったので、シェアします。
Office365で、Teams使えるプランにすると、sharepointやPlanner？が使えるので
Backlog使わないかもしれませんけど。

お金かけたくないのでGASでやります。

# 環境
通知先：MSTeams
通知元：Backlog
実行環境：GoogleAppsScript

# Teams側の準備
通知先のチャンネルからIncoming WebhookのURLを取得します。
「Teams Incoming Webhook」で検索してみてください。
有効化すると、Incoming WebhookのURLが取得できます。

# Gas側の準備
SpreadSheetからでも、Scriptのダッシュボードからでもいいのですが、
プロジェクトを新規作成します。
ソースは下に全部乗っけておきますので、コピーして貼り付けてください。
ウェブアプリケーションとして公開すると、APIのURLが取得できます。
それをBacklogからのOutbound webhook先に指定します。

# Backlog側の準備
バックログに登録すると、スペース用のURLが発行されます。
これは、スクリプトで使用するので、メモしておきましょう。

```javascript:backlog2MSTeams.js
var TEAMS_URL = 'https://outlook.office.com/webhook/xxxxxxxx';
var BASEURL = 'https://xxxxxx.backlog.com/'

// Teamsに投稿するメソッド
function postTeams(message) {
    // TeamsにPOSTするdataを生成
    var data = {
        "title": message.message,
        "summary": message.summary,
        "sections": [
            {
                "activityTitle": "Baclog Update",
                "activitySubtitle": message.message,
                "activityText": message.comment
            }
        ],
        "potentialAction": [
            {
                "@context": "http://schema.org",
                "@type": "ViewAction",
                "name": "Link To Backlog",
                "target": [message.url]
            }
        ]
    };
    var payload = JSON.stringify(data);
    var headers = {
        "Content-Type": "application/json"
    };
    var options = {
        "headers": headers,
        "method": "post",
        "payload": payload
    };

    var res = UrlFetchApp.fetch(TEAMS_URL, options);
    Logger.log(res)
}

// GasのAPIに入ってきたbodyによって、投稿するメッセージを生成する
function makeMessage(body) {
    var msgObj = new Object();
    var label = "";
    var bl_key = "";
    var bl_summary = "";
    var bl_comment = "";
    var bl_url = "";
    var bl_proj_key = body.project.projectKey
    
    switch (body.type) {
        case 1:
            label = "課題が追加されました";
            bl_key = "[" + body.project.projectKey + "-" + body.content.key_id + "]";
            bl_summary = "「" + body.content.summary + "」";
            bl_url = BASEURL + "view/" + body.project.projectKey + "-" + body.content.key_id;
            bl_comment = body.content.description;
            break;
        case 2:
            label = "課題が更新されました";
            bl_key = "[" + body.project.projectKey + "-" + body.content.key_id + "]";
            bl_summary = "「" + body.content.summary + "」";
            bl_url = BASEURL + "view/" + body.project.projectKey + "-" + body.content.key_id;
            bl_comment = body.content.description;
            break;
        case 3:
            label = "課題にコメントがありました";
            bl_key = "[" + body.project.projectKey + "-" + body.content.key_id + "]";
            bl_summary = "「" + body.content.summary + "」";
            bl_url = BASEURL + "view/" + body.project.projectKey + "-" + body.content.key_id + "#comment-" + body.content.comment.id;
            bl_comment = body.content.comment.content;
            break;
        case 14:
            label = "課題をまとめて更新しました";
            bl_key = "";
            bl_summary = "";
            bl_url = BASEURL + "projects/" + body.project.projectKey;
            bl_comment = body.createdUser.name + "さんが課題をまとめて操作しました。";
            break;
        case 5:
            label = "Wikiが追加されました";
            bl_key = "";
            bl_summary = "「" + body.content.name + "」";
            bl_url = BASEURL + "alias/wiki/" + body.content.id;
            bl_comment = body.createdUser.name + "さんがWikiページを追加しました。";
            break;
        case 6:
            label = "Wikiが更新されました";
            bl_key = "";
            bl_summary = "「" + body.content.name + "」";
            bl_url = BASEURL + "alias/wiki/" + body.content.id;
            bl_comment = body.createdUser.name + "さんがWikiページを更新しました。";
            break;
        case 11:
            label = "SVNのコミットがありました";
            bl_key = "[r" + body.content.rev + "]";
            bl_summary = "";
            bl_url = BASEURL + "rev/" + body.project.projectKey + "/" + body.content.rev;
            bl_comment = body.content.comment;
            break;
        case 12:
            label = "GitPushがありました";
            var git_rev = body.content.revisions[0].rev;
            git_rev = git_rev.substr(0, 10);
            bl_key = "[" + git_rev + "]";
            bl_summary = "";
            bl_url = BASEURL + "git/" + body.project.projectKey + "/" + body.content.repository.name + "/" + body.content.revision_type + "/" + body.content.revisions[0].rev;
            bl_comment = body.content.revisions[0].comment;
            break;
        case 18:
            label = "プルリクエストが追加さました";
            bl_key = "( 担当:" + body.content.assignee.name + " )";
            bl_summary = "「" + body.content.summary + "」";
            bl_url = BASEURL + "git/" + body.project.projectKey + "/" + body.content.repository.name + "/pullRequests/" + body.content.number;
            bl_comment = body.content.description;
            break;
        case 19:
            label = "プルリクエストが更新されました";
            bl_key = "( 担当:" + body.content.assignee.name + " )";
            bl_summary = "「" + body.content.summary + "」";
            bl_url = BASEURL + "git/" + body.project.projectKey + "/" + body.content.repository.name + "/pullRequests/" + body.content.number;
            bl_comment = body.content.description;
            break;
        case 20:
            label = "プルリクエストにコメントがありました";
            bl_key = "( 担当:" + body.content.assignee.name + " )";
            bl_summary = "";
            bl_url = BASEURL + "git/" + body.project.projectKey + "/" + body.content.repository.name + "/pullRequests/" + body.content.number + "#comment-" + body.content.comment.id;
            bl_comment = body.content.comment.content;
            break;

        default:
            return;
    }
    console.log(label);

    if (label) {
        msgObj['key'] = bl_proj_key
        msgObj['url'] = bl_url
        msgObj['summary'] = bl_summary
        msgObj['message'] = bl_key + " " + label + " by " + body.createdUser.name + "\n ";
        // 長いコメントは後ろをカットする
        if (bl_comment.length > 200) {
            bl_comment = bl_comment.substr(0, 200) + "...";
        }
        msgObj['comment'] = bl_comment;
    }
    return msgObj;
}

//------------------------------------------------------------------------
// ルート
//------------------------------------------------------------------------
function doPost(e) {
    // Backlogからのdataを取得
    var body = JSON.parse(e.postData.getDataAsString());
    // bodyからTeamsに投稿するメッセージを生成する　  
    var message = makeMessage(body)
    
    if (message) {
        postTeams(message)
        return
    }

    // ここまできたらエラーとして扱う
    return "error"
}
```