app.js 12.8 KB
var express = require('express');
const request = require('request');
const axios = require("axios");
const cheerio = require("cheerio");
const ncov_url = "http://ncov.mohw.go.kr/"; // 질병관리본부 url
const yongin_url = 'http://www.yongin.go.kr/health/ictsd/INC_selectIctsdPatntList.do?q_currPage=1&q_rowPerPage=10&_=1592578382959'; // 용인시
const TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
const MULTI_TARGET_URL = 'https://api.line.me/v2/bot/message/multicast'
const BROAD_TARGET_URL = 'https://api.line.me/v2/bot/message/broadcast'
const TOKEN = 'YOUR TOKEN'
const NAVER_NEWS_ID = 'YOUR ID'
const NAVER_NEWS_SECRET = 'YOUR SECRET'
const fs = require('fs');
const path = require('path');
const HTTPS = require('https');
const domain = "YOUR DOMAIN"
const sslport = 23023;
const bodyParser = require('body-parser');
var app = express();


// broadcast route yongin
var period_broadcast = 100000;
var count_broadcast = 0;

setInterval(function(){
    broadcast();
}, period_broadcast);

app.use(bodyParser.json());
app.post('/hook', function (req, res) {

    var eventObj = req.body.events[0];
    var source = eventObj.source;
    var message = eventObj.message;

    // request log
    console.log('======================', new Date() ,'======================');
    console.log('[request]', req.body);
    console.log('[request source] ', eventObj.source);
    console.log('[request message]', eventObj.message);
    

    var isNationWide = message.text;
    var sub_nationwide = "국내";
    if(isNationWide.indexOf(sub_nationwide) !== -1){
        replyNationWide(eventObj);
    } 
    else if(message.text == "야" || message.text == "도움말" || message.text.indexOf("어떻게") !== -1){
        console.log('[request hello]')
        replyHello(eventObj);
    } 
    else if(message.text.indexOf("뉴스") !== -1){
        console.log('[request news]')
        replyNews(eventObj);
    } 
    else if(message.text.indexOf("동선") !== -1){
        console.log('[request route]')
        replyRoute(eventObj);
    } 
    else{
        console.log('[request way]')
        replyWay(eventObj);
    }

    res.sendStatus(200);
});

//reply status
function replyNationWide(eventObj) {
    //read status
    request.post(ncov_url, function (err, res, body) { 
    
        const $ = cheerio.load(body)
        let parentTag = $("div.liveNum ul.liveNum li");
        
        let resultArr = [];
        parentTag.each(function(i, elem){
            let itemObj = { 
                text : $(this).find("strong").text(), 
                num :$(this).find("span").text()
            }
            resultArr.push(itemObj); 
        })

        request.post(
            {
                url: TARGET_URL,
                headers: {
                    'Authorization': `Bearer ${TOKEN}`
                },
                json: {
                    "replyToken":eventObj.replyToken,
                    "messages":[
                        {
                            "type":"text",
                            "text":resultArr[0].text + ' : ' + resultArr[0].num.replace('(누적)', '').replace('(누적)', '').replace('전일대비', '')
                        },
                        {
                            "type":"text",
                            "text":resultArr[1].text.replace('(격리해제)', '') + '       : ' + resultArr[1].num.replace('(격리해제)', '')
                        },
                        {
                            "type":"text",
                            "text":resultArr[2].text.replace('(격리 중)', '') + '   : ' + resultArr[2].num.replace('(격리 중)', '')
                        },
                        {
                            "type":"text",
                            "text":resultArr[3].text + '       : ' + resultArr[3].num
                        },
                        {
                            "type": "sticker",
                            "packageId": "11539",
                            "stickerId": "52114122"
                        }
                    ]
                }
            },(error, response, body) => {
                console.log(body)
            });
    
    })

    
}

//hello
function replyHello(eventObj) {
   
    request.post(
        {
            url: TARGET_URL,
            headers: {
                'Authorization': `Bearer ${TOKEN}`
            },
            json: {
                "replyToken":eventObj.replyToken,
                "messages":[
                    {
                        "type":"text",
                        "text":"안녕하십니까. 코로나 알리미 입니다."
                    },
                    {
                        "type":"text",
                        "text":"1. 국내 현황은 '국내'를 타이핑 해주세요." + "\n" + "\n" + "2. 코로나 19 관련 뉴스는 '뉴스'를 타이핑 해주세요." + "\n" + "\n" + "3. 용인시 확진자의 동선은 '동선'을 입력해주세요." + "\n" + "\n" + "* 새로운 확진자의 동선이 공개되면 알려드리겠습니다."
                    },
                    {
                        "type":"text",
                        "text":"감사합니다."
                    },
                    {
                        "type": "sticker",
                        "packageId": "11539",
                        "stickerId": "52114110"
                    }

                ]
            }
        },(error, response, body) => {
            console.log(body)
        });
}

// else
function replyWay(eventObj) {
   
    request.post(
        {
            url: TARGET_URL,
            headers: {
                'Authorization': `Bearer ${TOKEN}`
            },
            json: {
                "replyToken":eventObj.replyToken,
                "messages":[
                    {
                        "type":"text",
                        "text":"대답할 수 없는 입력입니다."
                    },
                    {
                        "type":"text",
                        "text":"사용 방법은 '도움말'을 입력해주세요."
                    },
                    {
                        "type": "sticker",
                        "packageId": "11539",
                        "stickerId": "52114129"
                    },
                    {
                        "type":"text",
                        "text":"감사합니다."
                    }
                    

                ]
            }
        },(error, response, body) => {
            console.log(body)
        });
}

// reply route yongin
function replyRoute(eventObj) {

    var array = fs.readFileSync('yongin.txt').toString().split("\n");
    real_Text = ""
    for (i in array) {
        if (array[i] == "[인적사항]" || array[i] == "[환자 현황]" || array[i] == "[확진자 현황]") {
            if (i == 0) {
                real_Text += array[i];
            } else {
                array[i] = '\n' + '\n' + "[인적사항]";
                real_Text += array[i];
            }

        } 
        else if(array[i].indexOf("○") !== -1){
            array[i] = array[i] + '\n';
            real_Text += array[i]
        } 
        else {
            real_Text += array[i]
        }
        real_Text += '\n'
    }

    request.post(
        {
            url: TARGET_URL,
            headers: {
                'Authorization': `Bearer ${TOKEN}`
            },
            json: {
                "replyToken":eventObj.replyToken,
                "messages":[
                    {
                        "type":"text",
                        "text":"최근 확진자의 정보입니다. 감사합니다."
                    },
                    {
                        "type":"text",
                        "text":real_Text
                    },
                    {
                        "type": "sticker",
                        "packageId": "11539",
                        "stickerId": "52114110"
                    }
                ]
            }
        },(error, response, body) => {
            console.log(body)
        });
}

// Broadcast yongin
function broadcast(){
 
    request.post(yongin_url, function (err, res, body) {

        const $ = cheerio.load(body)
        let parentTag = $("div.view_content");

        let resultArr = [];
        parentTag.each(function (i, elem) {
            let itemObj = {
                text: $(this).find("p").text(),
            }
            resultArr.push(itemObj);
        })
        
        realText = ""
        for (var i = 0; i < 5; i++) {
            realText += resultArr[i].text
            realText += '\n'
        }
        fs.readFile('yongin.txt', 'utf8', function (err, data) {
            if (data !== realText) {
                fs.writeFile('yongin.txt', realText, 'utf8', function (error) {
                    console.log('write new route')
                });

                request.post(
                    {
                        url: BROAD_TARGET_URL,
                        headers: {
                            'Authorization': `Bearer ${TOKEN}`
                        },
                        json: {
                            "messages":[
                                {
                                    "type":"text",
                                    "text":"새로운 '용인시' 확진자의 동선이 공개되었습니다."
                                },
                                {
                                    "type":"text",
                                    "text":"http://www.yongin.go.kr/health/ictsd/index.do"
                                },
                                {
                                    "type": "sticker",
                                    "packageId": "11539",
                                    "stickerId": "52114110"
                                }
                            ]
                        }
                    },(error, response, body) => {
                        console.log(body)
                    });
            }
            else {
                console.log('not exist new route')
            }
        });

    })
}

//reply news
function replyNews(eventObj) {

    var news_Title = ['title1', 'title2', 'title3', 'title4', 'title5'];
    var news_Link = ['link1', 'link2', 'link3', 'link4', 'link5'];
    request.get({
        url: 'https://openapi.naver.com/v1/search/news',
        qs: {
            query: '코로나 19', // 검색어
            start: 1, // 검색 시작 위치
            display: 10, // 가져올 뉴스 개수
            sort: 'sim', // date or sim
        },
        headers: {
            'X-Naver-Client-Id': NAVER_NEWS_ID,
            'X-Naver-Client-Secret': NAVER_NEWS_SECRET
        }
    }, function (err, res, body) {
        let json = JSON.parse(body) //json으로 파싱

        for (var i = 0; i < 5; i++) {
            news_Title[i] = json.items[i].title.replace('<b>', '').replace('</b>', '').replace('&quot;', '').replace('&quot;', '');
            news_Link[i] = json.items[i].link;
        }
        
        request.post(
            {
                url: TARGET_URL,
                headers: {
                    'Authorization': `Bearer ${TOKEN}`
                },
                json: {
                    "replyToken": eventObj.replyToken,
                    "messages": [
                        {
                            "type": "text",
                            "text": news_Title[0] + '\n' + news_Link[0]
                        },
                        {
                            "type": "text",
                            "text": news_Title[1] + '\n' + news_Link[1]
                        },
                        {
                            "type":"text",
                            "text":news_Title[2] + '\n' + news_Link[2]
                        },
                        {
                            "type":"text",
                            "text":news_Title[3] + '\n' + news_Link[3]
                        },
                        {
                            "type":"text",
                            "text":news_Title[4] + '\n' + news_Link[4]
                        }

                    ]
                }
            }, (error, response, body) => {
                console.log(body)
            });
    })
}


try {
    const option = {
      ca: fs.readFileSync('/etc/letsencrypt/live/' + domain +'/fullchain.pem'),
      key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/privkey.pem'), 'utf8').toString(),
      cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/cert.pem'), 'utf8').toString(),
    };
  
    HTTPS.createServer(option, app).listen(sslport, () => {
      console.log(`[HTTPS] Server is started on port ${sslport}`);
    });
  } catch (error) {
    console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.');
    console.log(error);
  }