Nuxt 및 Node.js 서버에서 Slack 알림 구현

디자인


  • Nuxt 베이스 어플리케이션으로부터 Slack 에 통지하는 기능을 구현하고 싶다.
  • 정기적인 자동 재전송 기능도 원한다.
  • 토큰을 Nuxt 쪽에 놓는 것은 조금 ...

  • 그런 요건을 충족하기 위해서는 Nuxt에서 서버를 경유하는 것도 있을까라는 느낌으로 작성.

    필요한 것


  • Nuxt 응용 프로그램
  • Node.js (우리 버전 13.2.0)
  • 구성된 Slack API(토큰 및 Bot Token Scopes에서 chat:write 권한이 필요합니다. #general에 가입됨)

  • Nuxt에서 구현



    요구되는 것은
    1. 메시지 입력
    2. 받는 사람 입력
    3. 재전송 간격 or 재전송하지 않는 입력
    4. 설정 내용의 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를 간단하게 해결할 수 있다.
    크로스 오리진 리소스를 공유하는 방법?

    서버 준비



    서버에서는 다음과 같은 처리를 하고 싶다.
    1. HTTP Request 수신
    2. 내용의 데이터로부터 메시지와 목적지, 정기 재전송 정보를 꺼낸다
    3. 그에 따라 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에 한정하지 않고 통지할 수 있도록 확장할 수 있을 것 같다.

    결론



    읽어 주셔서 감사합니다. 뭔가 실수가 있으면 코멘트에 잘 부탁드립니다.

    좋은 웹페이지 즐겨찾기