##設計
- NuxtベースアプリケーションからSlackに通知する機能を実装したい。
- 定期的な自動再送機能もほしい。
- トークンをNuxt側に置くのはちょっと...
そんな要件を満たすためには、Nuxtからサーバーを経由するのもありかなという感じで作成。
##必要なもの
- Nuxtアプリケーション
- Node.js (当方Version 13.2.0)
- 設定済みSlack API (トークンとBot Token Scopesにてchat:write権限が必要。#generalに参加済み)
##Nuxtでの実装
求められるものは
- メッセージ入力
- 宛先入力
- 再送間隔 or 再送しないの入力
- 設定内容のPOST
とりあえず上記の4つを実装すれば最低限機能は満たせそうなので書いていく。
見た目はこの際捨て置く。
またquerystringを使っているので未インストールなら
npm install --save querystring
以下、コード。
<template>
<div class="create-post">
<input type="text" v-model="message" id="message">
<input type="text" v-model="channel" id="channel">
<input type="text" v-model="schedule" id="schedule">
<button v-on:click="send">
送信
</button>
</div>
</template>
<script>
import querystring from "querystring"
export default {
data() {
return {
message: '',
channel: '',
schedule: 'none'
}
},
methods : {
async send(){
let json_data = {
message: this.$data.message,
channel: this.$data.channel,
schedule: this.$data.schedule
};
const response = await this.$axios.$post('/test/rest', querystring.stringify(json_data));
}
}
}
</script>
<style scoped>
.create-post{
width: 30%;
height: 200px;
padding-left: 200px;
}
#message{
margin-top: 10%;
}
#channel{
margin-top: 10%;
}
#schedule{
margin-top: 10%;
}
</style>
そうするとこのようなページが出来上がる
今回、NuxtからサーバーにPOSTするために@nuxtjs/axiosを使用している。
詳しくはご自分で調べてほしいのだが、使用する際、nuxt.confing.jsにて以下の文を編集・追加している。
modules: [
'@nuxtjs/axios',
],
axios: {
proxy: true
},
proxy: {
'/test/': {
target: 'http://0.0.0.0:3000/',
pathRewrite: {'^/test/': ''}
}
},
このように設定することでCORSを簡単に解決することができる。
クロスオリジンリソースを共有するには?
##サーバーの用意
サーバーでは次のような処理を行いたい。
- HTTP Requestを受けとる
- 中身のデータからメッセージとあて先、定期再送情報を取り出す
- それに合わせてSlackに通知する
それではコードを書いていく。
これにあたって、以下の記事やサイトを参考にさせていただいた。
Nodejs HTTP/HTTPS サーバーとクライアントのコーディングパターン
【Node.js】Slack APIを使用してメッセージを送信する
Node.jsで定期実行メモ
node-cron npm
node-fetch npm
const http = require('http');
const fetch = require('node-fetch');
const cron = require('node-cron');
const queryString = require("querystring");
const StringDecoder = require("string_decoder").StringDecoder;
const Decoder = new StringDecoder('utf8');
let server = http.createServer();
async function postToSlack(token, msg, channel) {
const { WebClient } = require('@slack/web-api');
const client = new WebClient(token);
const params = {
channel: channel,
text: msg
};
await client.chat.postMessage(params);
}
let tasks = [];
server.on('request', function (req, res) {
req.on('data', async function(chunk) {
let json = JSON.parse(JSON.stringify(queryString.parse(Decoder.write(chunk))));
if (json.schedule === 'none') { //スケジュール指定がない場合
await postToSlack('your token here', json.message, json.channel);
} else { //ある場合
let task = cron.schedule(json.schedule, async () => {await postToSlack('your token here', json.message, json.channel);});
tasks.push(['start', task]);
}
let return_json = {
state: true,
};
res.writeHead(200, {'Content-Type': 'application/json'});
let replyData = queryString.stringify(return_json);
res.write(replyData);
res.end();
});
});
server.listen(3000);
##実際に試す
Nuxtのページで文章とあて先を入力して送信。
そしてSlackに通知が来た。
定期実行も確認
以上、実装完了とす。
##感想
エラー処理を全く実装していないので怖い。
APIが用意されていると楽。
あとはSlackに限らず通知できるように拡張できそう。
##おわりに
お読みいただきありがとうございました。なにか間違いがございましたらコメントへよろしくお願いします。