app.js 14.1 KB
const CGV = require('./CGVTicketing.js');
//const SearchingTheaterAPI = require('./SearchingTheaterAPI');
const async = require('async');
CGV.init();

const PUSH_TARGET_URL = 'https://api.line.me/v2/bot/message/push'
const REPLY_TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
const asyncHandler = require('express-async-handler');
const bodyParser = require('body-parser');
const request = require('request');
const moment = require("moment");
const HTTPS = require('https');
const path = require('path');
const fs = require('fs');
const sslport = 23023;

var express = require('express');
var app = express();
app.use(bodyParser.json());

/////////////////////////////////////////////////
// commit 할때 지워야 할 것들
const USER_ID = '';
const TOKEN = '';
const domain = "";
const LocalAPI_TOKEN = "";
/////////////////////////////////////////////////
let isBrandSelected = false;
let CGV_Flag = -1; //진행 단계
let CGV_date = ""; //날짜
let RequestedLocation = ""; //사용자가 입력한 장소
let RespondedTheaters = []; //API를 통해 받아온 영화관들 및 카카오맵 연결 링크
let SelectedTheater = ""; //사용자가 설정한 영화관 이름
let SelectedTheaterCode = ""; //영화관 고유코드
let CGV_accessible_movies = []; //상영 날짜와 상영관에 따라 예매할 수 있는 영화 목록
let CGV_movie_chart = []; 
let url_web = "https://www.cgv.co.kr/ticket/";
let url_mobile = "https://m.cgv.co.kr/WebApp/Reservation/quickResult.aspx";
/////////////////////////////////////////////////

//영화관 정보와 영화 랭킹을 가져오는 것까지 대략 30초가 걸림 => 30초 기다리고 메세지 전송
setTimeout(function () {
    PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
}, 20000);

app.post('/hook', asyncHandler(async (req, res, next) => {

    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);

    //어느 순간에서든 "브랜드"를 입력해 원하는 브랜드 선택
    //initFlag : false ==> 브랜드 선택 전
    //initFlag : true ==> 브랜드 선택 됨
    if (eventObj.message.text == "브랜드") {
        isBrandSelected = false;
        CGV_Flag = -1;
        PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
    }

    //브랜드 선택- CGV 인 경우 CGV_Flag를 0으로 두어 메가박스 임을 확인
    if (isBrandSelected == false && eventObj.message.text == 1) {
        isBrandSelected = true;
        CGV_Flag = 0;
    }

    //CGV로 브랜드가 선택된 경우
    if(isBrandSelected == true && CGV_Flag != -1){
        if(CGV_Flag === 0){
            const text1 = "영화관 위치를 입력해주세요";
            const text2 = "ex) 강남"
            SendMessage(eventObj, text1, text2);
            CGV_Flag++;
        }
        else if(CGV_Flag === 1){
            RespondedTheaters = [];
            RequestedLocation = message.text;
            KakaoLocalAPI("CGV", RequestedLocation);
            setTimeout(function() {
                if(RespondedTheaters.length == 0)
                    PushSingleMessage("검색 결과가 없습니다. 다시 입력해주세요.");
                else{
                    if(RespondedTheaters.length == 1){
                        SelectedTheater = RespondedTheaters[0].theater_name;
                        SelectedTheaterCode = CGV.getTheaterCode(SelectedTheater);
                        setTimeout(function() {
                            CGV_Flag = 2;
                        }, 2000);
                    }
                    else{
                        let CGV_OutputString = "원하시는 상영관의 번호를 정확히 입력해주세요\n";
                        for (let i = 0; i < RespondedTheaters.length; i++) {
                            CGV_OutputString += String(i + 1) + ": " + RespondedTheaters[i].theater_name + "\n";
                        }
                        CGV_OutputString += String(RespondedTheaters.length + 1) + ": 다시 검색하기";
                        PushSingleMessage(CGV_OutputString);
                        CGV_Flag = 101;
                    }
                }
            }, 2000);
            
        }
        else if(CGV_Flag == 101 && RespondedTheaters.length != 0){
           let selection = parseInt(message.text);
           if(selection > 0 && selection < RespondedTheaters.length + 1){
               SelectedTheater = RespondedTheaters[selection - 1].theater_name;
               SelectedTheaterCode = await CGV.getTheaterCode(SelectedTheater);
               CGV_Flag = 2;
           }
           else{
                const text1 = "영화관 위치를 입력해주세요";
                const text2 = "ex) 강남"
                SendMessage(eventObj, text1, text2);
                CGV_Flag = 1;
           }

        }
        ////날짜 입력 받기
        if(CGV_Flag === 2){
            const text1 = "선택한 영화관은 CGV" + SelectedTheater + "입니다.\n 영화를 관람할 날짜를 선택해 주세요.";
            const text2 = "ex)20020409, YYYYMMDD";
            SendMessage(eventObj, text1, text2);
            CGV_Flag = 3;
        }
        //날짜 확인 및 날짜, 장소에 대해 상영중인 영화 리스트 가져오기
        if (moment(message.text, "YYYYMMDD", true).isValid() && CGV_Flag == 3) {
            CGV_date = message.text;
            //console.log(MEGA_date, MEGA_TheaterLocation);
            if (CGV_date && SelectedTheater) {
                CGV_accessible_movies = await CGV.getMovieChart(5);
                const text1 = "현재상영작을 가져오는 중입니다.";
                const text2 = "잠시만 기다려주세요.";
                PushMessage(text1, text2);
                console.log(CGV_accessible_movies);
                CGV_Flag++;
            }
            //원본 코드
            // MEGA_date = parseInt(eventObj.message.text);
            // if (MEGA_date && MEGA_TheaterLocationCode) {
            //     MEGA_PlayingMovieURL = "https://megabox.co.kr/on/oh/ohb/SimpleBooking/simpleBookingPage.do" + '?brchNo1=' + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
            //     console.log(MEGA_PlayingMovieURL)
            //     async.waterfall[
            //         megabox.using_PlayingMovieURL(MEGA_PlayingMovieURL),
            //         megabox.geting_PlayingMovie()
            //     ]
            //     MEGA_flag++
            //     console.log(MEGA_flag);
            // }
        }
        if(CGV_Flag === 4){
            let AccessibleMovieText = "-- 예매 가능한 상영작 --\n\n";
            if(CGV_accessible_movies.length == 0){
                PushMessage("현재상영작이 없습니다.","영화관 선택 단계로 이동합니다.");
                setTimeout(function () {
                    PushMessage("영화관 위치를 입력해주세요", "ex1) 강남");
                }, 1000);
                CGV_Flag = 1;
            }
            else if(CGV_accessible_movies.length == 1){
                AccessibleMovieText += ("1. " + CGV_accessible_movies[0].title);
                const SelectedMovieCode = CGV_accessible_movies[0].code;
                PushMessage(AccessibleMovieText, "바로 링크가 전송됩니다.");
                setTimeout(function() {
                    const finalURL_web = url_web + "?MOVIE_CD=" + SelectedMovieCode + "&MOVIE_CD_GROUP=" + SelectedMovieCode + "&THEATER_CD=" + SelectedTheaterCode + "&PLAY_YMD=" + CGV_date;
                    const finalURL_mobile = url_mobile + "?mgc=" + SelectedMovieCode + "&tc=" + SelectedTheaterCode + "&ymd=" + CGV_date;
                    //console.log(finalURL_web);
                    //PushMessage(finalURL_web, "링크를 누르면 예매 창으로 바로 이동합니다.");
                    PushURLMessage(finalURL_web, finalURL_mobile);
                }, 1000);
            }
            else{
                setTimeout(function() {
                    let rank = 1;
                    for(const elem of CGV_accessible_movies){
                        AccessibleMovieText += (rank.toString() + ". " + elem.title);
                        AccessibleMovieText += "\n";
                        rank++;
                    }
                    console.log(AccessibleMovieText);
                    PushMessage(AccessibleMovieText, "예매할 영화 번호를 입력해주세요.\n ex)1 (영화 앞 숫자만 입력)");
                    CGV_Flag = 5;
                }, 1000);
            }
        }
        if(CGV_Flag === 5){
            const index = parseInt(message.text) - 1;
            const SelectedMovieCode = CGV_accessible_movies[index].code;
            const finalURL_web = url_web + "?MOVIE_CD=" + SelectedMovieCode + "&MOVIE_CD_GROUP=" + SelectedMovieCode + "&THEATER_CD=" + SelectedTheaterCode + "&PLAY_YMD=" + CGV_date;
            const finalURL_mobile = url_mobile + "?mgc=" + SelectedMovieCode + "&tc=" + SelectedTheaterCode + "&ymd=" + CGV_date;
            //console.log(finalURL_web);
            //PushMessage(finalURL_web, "링크를 누르면 예매 창으로 바로 이동합니다.");
            PushURLMessage(finalURL_web, finalURL_mobile);
            setTimeout(function () {
                isBrandSelected = false;
                CGV_Flag = -1;
                PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
            }, 1000);
        }

    }
    res.sendStatus(200);
}));

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);
  }
  

//메세지 전송하는 function 모음 
function SendMessage(eventObj, text1, text2 = "") { //reply message
    request.post(
        {
            url: REPLY_TARGET_URL,
            headers: {
                'Authorization': `Bearer ${TOKEN}`
            },
            json: {
                "replyToken": eventObj.replyToken,
                "messages": [
                    {
                        "type": "text",
                        "text": text1
                    },
                    {
                        "type": "text",
                        "text": text2
                    }
                ]
            }
        }, (error, response, body) => {
            console.log(body);
        });
}

function PushMessage(text1, text2 = "") { //push two message
    request.post(
        {
            url: PUSH_TARGET_URL,
            headers: {
                'Authorization': `Bearer ${TOKEN}`
            },
            json: {
                "to": `${USER_ID}`,
                "messages": [
                    {
                        "type": "text",
                        "text": text1
                    },
                    {
                        "type": "text",
                        "text": text2
                    }
                ]
            }
        }, (error, response, body) => {
            console.log(body)
        });
}

function PushSingleMessage(text1) {//push single message
    request.post(
        {
            url: PUSH_TARGET_URL,
            headers: {
                'Authorization': `Bearer ${TOKEN}`
            },
            json: {
                "to": `${USER_ID}`,
                "messages": [
                    {
                        "type": "text",
                        "text": text1
                    }
                ]
            }
        }, (error, response, body) => {
            console.log(body)
        });
}

function PushURLMessage(pcurl, smartphoneurl) {//push single message
    request.post(
        {
            url: PUSH_TARGET_URL,
            headers: {
                'Authorization': `Bearer ${TOKEN}`
            },
            json: {
                "to": `${USER_ID}`,
                "messages": [
                    {
                        "type": "text",
                        "text": "pc버전 url입니다\n\n" + pcurl
                    },
                    {
                        "type": "text",
                        "text": "mobile버전 url입니다\n\n" + smartphoneurl
                    }
                ]
            }
        }, (error, response, body) => {
            console.log(body)
        });
}

function KakaoLocalAPI(brand, location){
    let kakaoOptions = {
        url : "https://dapi.kakao.com/v2/local/search/keyword",
        method : "GET",
        headers : {
            'Authorization': `KakaoAK ${LocalAPI_TOKEN}`  
        },
        qs: {
            'query': `${brand} ${location}`,
            //'category_group_code' : 'CT1',
            'size' : 5
        },
        encoding : 'UTF-8'
    };
    request(kakaoOptions, function (err, res, body) {
        info_list = JSON.parse(body).documents;
        if(!err && res.statusCode == 200){
            info_list.forEach(info => {
                if(info.category_name.endsWith("CGV")){
                    const theater_info = {
                        "theater_name" : info.place_name.replace("CGV ", ""),
                        "theater_url" : info.place_url
                    };
                    RespondedTheaters.push(theater_info);
                }
            });
        }
    });
    
}