この記事は、富士通システムズウェブテクノロジー Advent Calendarの3日目の記事です。
(お約束)本記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません。
はじめに
MattermostにはSlackと違い、リマインダーが標準で用意されていない。
社内でリマインダー機能が欲しいって意見があったので、「リマインダーくらい直ぐ作ってるよー」って意気込みで作ってみました。
※Slackと同じ使い勝手のリマインダーが一応プラグインとして提供されてるらしい。
用意するもの
- Node-RED
- SQLServer
※データベースを使ってますが、ファイルでも代用可能です。
処理について
登録処理:Mattermostのスラッシュコマンドからリマインダーを登録する。
- ユーザーはスラッシュコマンドを入力する。
コマンド:/reminder
- BOTはリマインダー登録ダイアログを作成しJSON形式でMattermostに送信する。
- ユーザーはダイアログにリマインダーの登録したい情報を入力し、ボタンを押す
- BOTは入力内容を受け取り、データベースに登録し、登録結果をMattermostにJSON形式で送信する。
通知処理:指定した日時になったらMattermostに通知を投げる。
- BOTは毎分データベースにDELETE_FLGはOFFのリマインダー情報をSELECT文で受け取る。
- SELECT文実行結果を1行ずつ読み込み、ユーザーの指定した日時が現在日時と一致した場合、Mattermostにリマインダー情報をJSON形式で送信する。
登録処理
Mattermostに表示されるダイアログは以下のとおりである。ここにリマインダー情報を入力し、DBに登録される。
ダイアログ
テキストボックスに日時のサブタイプがない為、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からのメッセージ
通知処理
先ほど登録したリマインダーはこんな感じで通知が来ます。
通知内容
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のコマンドより個人的には使いやすい自分好みのリマインダーを作ることが出来ました。
次回はプラグイン化してどこの環境でも使えるリマインダーに出来たらなぁって思ってます。ノシ