15
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Mattermostでリマインダーを作ってみたよ

Last updated at Posted at 2019-12-02

この記事は、富士通システムズウェブテクノロジー Advent Calendarの3日目の記事です。
(お約束)本記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません。

はじめに

MattermostにはSlackと違い、リマインダーが標準で用意されていない。
社内でリマインダー機能が欲しいって意見があったので、「リマインダーくらい直ぐ作ってるよー」って意気込みで作ってみました。
※Slackと同じ使い勝手のリマインダーが一応プラグインとして提供されてるらしい。

用意するもの

  • Node-RED
  • SQLServer
    ※データベースを使ってますが、ファイルでも代用可能です。

処理について

登録処理:Mattermostのスラッシュコマンドからリマインダーを登録する。

  1. ユーザーはスラッシュコマンドを入力する。
    コマンド:/reminder
  2. BOTはリマインダー登録ダイアログを作成しJSON形式でMattermostに送信する。
  3. ユーザーはダイアログにリマインダーの登録したい情報を入力し、ボタンを押す
  4. BOTは入力内容を受け取り、データベースに登録し、登録結果をMattermostにJSON形式で送信する。

通知処理:指定した日時になったらMattermostに通知を投げる。

  1. BOTは毎分データベースにDELETE_FLGはOFFのリマインダー情報をSELECT文で受け取る。
  2. SELECT文実行結果を1行ずつ読み込み、ユーザーの指定した日時が現在日時と一致した場合、Mattermostにリマインダー情報をJSON形式で送信する。

登録処理

Mattermostに表示されるダイアログは以下のとおりである。ここにリマインダー情報を入力し、DBに登録される。

ダイアログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528240/be6ced7f-dad8-daaa-3b58-10185fe2c7b4.png)

テキストボックスに日時のサブタイプがない為、yyyyMMddhhmm形式でゴリ押しで作成した。
とりあえず、日付と時間のところは現在の日時を入れ、必要がある人だけが書き換えれば良いという風にした。

ソースコード
var dt = new Date();
var message_help_text = "メッセージは本ダイアログ呼出し時のチャンネルにリマインドされます。" +
                        "プライベートチャンネルにはリマインド出来ません。" +
                        "Markdown記法に対応しています。" +
                        "メンションをメッセージに含ませると、指定したメンション先に通知が来るようになります。";
msg.payload = {
    url:"http://**.**.**.**:8888/reminder2",
    channel_id:msg.payload.channel_id,
    trigger_id:msg.payload.trigger_id,
    dialog: {
        title: "開発用リマインダー設定(公開チャンネルのみ)",
        submit_label: "SET",
        state:msg.payload.response_url + "," + msg.payload.channel_name + "," + msg.payload.user_name,
        elements: [
            {
                display_name: "メッセージ",
                name: "MESSAGE",
                type: "textarea",
                default:msg.payload.text,
                placeholder: "担当者は顧客に提示報告メールを送信してください。",
                help_text:message_help_text
            },
            {
                display_name: "繰り返し",
                name: "INTERVAL",
                type: "select",
                options: [
                    {
                        text: "しない",
                        value: "None"
                    },
                    {
                        text: "平日",
                        value: "Weekdays"
                    },
                    {
                        text: "休日",
                        value: "Holiday"
                    },
                    {
                        text: "毎日",
                        value: "EveryDay"
                    },
                    {
                        text: "毎週",
                        value: "EveryWeek"
                    },
                    {
                        text: "毎月",
                        value: "Monthly"
                    },
                ]
            },
            {
                display_name: "開始日付(yyyyMMdd)",
                name: "TARGET_DATE",
                type: "text",
                max_length:8,
                min_length:8,
                default:createDate(),
                placeholder:"yyyyMMdd",
                help_text:"デフォルト値:ダイアログ表示時の日付"
            },
            {
                display_name: "指定時刻(hhmm)",
                name: "TARGET_TIME",
                type: "text",
                max_length:4,
                min_length:4,
                default:createTime(),
                placeholder:"hhmm",
                help_text:"デフォルト値:ダイアログ表示時の時刻"
            }
        ],
    }
}
return msg;

function createDate()
{
    var format = String(dt.getFullYear());
    if(String((dt.getMonth() + 1)).length === 1) {
        format += "0" +  String((dt.getMonth() + 1));
    } else {
        format += String((dt.getMonth() + 1));
    }
    
    if(String(dt.getDate()).length === 1) {
        format += "0" +  String(dt.getDate());
    } else {
        format += String(dt.getDate());
    }
    return format;
}

function createTime()
{
    var format = null;
    if(String(dt.getHours()).length === 1) {
        format = "0" + dt.getHours(); 
    } else {
        format = String(dt.getHours());
    }
    
    if(String(dt.getMinutes()).length === 1) {
        format += "0" +  String(dt.getMinutes());
    } else {
        format += String(dt.getMinutes());
    }
    return format;
}

ダイアログで必要事項を入力し「SET」ボタンを押すと、コマンドを実行したチャンネルに以下のような通知がBOTから来る。

BOTからのメッセージ
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528240/7febc96e-5079-da15-ee38-3a5946a03896.png)

通知処理

先ほど登録したリマインダーはこんな感じで通知が来ます。

通知内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528240/da3524e7-c251-a1a2-cf08-5cc0e6d68ecb.png)

BOTは毎分データベースにDELETE_FLGはOFFのリマインダー情報をSELECT文で受け取り、条件と一致したリマインダーをMattermostに送信する。

ソースコード
var dt = new Date();
var WeekChars = [ "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" ];
var wDay = WeekChars[dt.getDay()];
var hh = ("0"+dt.getHours()).slice(-2);
var mm = ("0"+dt.getMinutes()).slice(-2);
var hhmm = hh + "" + mm;
var yyyy = dt.getFullYear();
var MM = (dt.getMonth() + 1);
var dd = dt.getDate();
var yyyyMMdd = String(yyyy) + String(MM) + String(dd); 

var year = null;
var month = null;
var date = null;
var dayOfWeek = null;
var hour = null;
var minute = null;
var thisInterval = "Weekdays";
if (wDay === "日曜日" || wDay === "土曜日" ) {
        thisInterval = "Holiday";
}
for(i=0;i<msg.database.length;i++)
{
    year = msg.database[i].TARGET_DATE.slice(0, 4);
    month = msg.database[i].TARGET_DATE.slice(4, 6);
    date = msg.database[i].TARGET_DATE.slice( -2 );
    var targetDate =  new Date(parseInt(year), (parseInt(month) -1), parseInt(date));
    dayOfWeek = targetDate.getDay();
    
    if(msg.database[i].TARGET_TIME === hhmm) {
        if (msg.database[i].INTERVAL === "EveryDay") {
            return createMsg(); //毎日
        } else if (msg.database[i].INTERVAL === "None" && msg.database[i].TARGET_DATE === yyyyMMdd) {
            return createMsg(); //繰り返しなし
        } else if (msg.database[i].INTERVAL === thisInterval) {
            return createMsg(); //平日or休日
        } else if (dayOfWeek === dt.getDay() && msg.database[i].INTERVAL === "EveryWeek") {
            return createMsg(); // 毎週
        } else if (date === date && msg.database[i].INTERVAL === "Monthly") {
            return createMsg(); // 毎月
        }
    }
}
return null;

function createMsg() {
    if (msg.database[i].INTERVAL === "None") {
        msg.payload = {
            userName: "いつもアシスト ふくまろ",
            channel:msg.database[i].CHANNEL_NAME,
            text:"リマインドします。",
            attachments: 
            [{
                author_name:"REMINDER_ID." + msg.database[i].REMINDER_ID,
                text:msg.database[i].MESSAGE,
            }]
        };
        msg.database = {
            "REMINDER_ID":msg.database[i].REMINDER_ID,
            "CHANNEL":msg.database[i].CHANNEL_NAME,
            "INTERVAL":msg.database[i].INTERVAL
        };
    } else {
        msg.payload = {
            userName: "いつもアシスト ふくまろ",
            channel:msg.database[i].CHANNEL_NAME,
            text:"リマインドします。",
            attachments: 
            [{
                author_name:"REMINDER_ID." + msg.database[i].REMINDER_ID,
                text:msg.database[i].MESSAGE,
                actions:[{
                    name:"このリマインダーを停止させる",
                    integration: {
                        url: "http://**.**.**.**:8888/stop/reminder",
                        context:{
                            "REMINDER_ID":msg.database[i].REMINDER_ID,
                            "CHANNEL":msg.database[i].CHANNEL_NAME,
                            "INTERVAL":msg.database[i].INTERVAL
                        }
                    }
                }]
            }]
        };
    }
    return msg;
}

ひとこと

Slackのコマンドより個人的には使いやすい自分好みのリマインダーを作ることが出来ました。
次回はプラグイン化してどこの環境でも使えるリマインダーに出来たらなぁって思ってます。ノシ

15
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?