임승현

Merge branch 'feature/Chatbot_megabox' into 'master'

Feature/chatbot megabox



See merge request !35
1 +const chatbot = require("./app.js");
2 +const request = require('request');
3 +const cheerio = require('cheerio');
4 +const puppeteer = require('puppeteer');
5 +require('chromedriver');
6 +const {Builder,until} = require('selenium-webdriver'); //모듈 불러오기
7 +var webdriver = require('selenium-webdriver');
8 +var By = webdriver.By;
9 +const chrome = require('selenium-webdriver/chrome');//크롬 사용시
10 +const async = require('async')
11 +let express = require('express');
12 +let app = express();
13 +let bodyParser = require('body-parser');
14 +const { timeout } = require('async');
15 +app.use(bodyParser.urlencoded({ extended: false }));
16 +app.use(bodyParser.json());
17 +const booking_url = "https://megabox.co.kr/booking?";
18 +exports.booking_url = booking_url;
19 +const rate_url = "https://www.megabox.co.kr/movie";
20 +let r =0;
21 +let movie_data = [];
22 +exports.movie_data = movie_data;
23 +let location_data = [];
24 +exports.location_data = location_data;
25 +let index = 0;
26 +exports.init = ()=>{async.waterfall([//for 동기적 처리
27 + async () => {
28 + const driver = new webdriver.Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless()).build();//
29 + driver.get(booking_url);
30 + driver.switchTo().frame(0)//frameBokdMBooking 프레임 가져옴
31 + let seoul = await driver.wait(until.elementsLocated(By.css('#mCSB_4_container>ul>li>#btn')));
32 + let Gyeonggi = await driver.wait(until.elementsLocated(By.css('#mCSB_5_container>ul>li>#btn')));
33 + const Incheon = await driver.wait(until.elementsLocated(By.css('#mCSB_6_container>ul>li>#btn')));
34 + const DCS = await driver.wait(until.elementsLocated(By.css('#mCSB_7_container>ul>li>#btn')));//Daejeon Chungcheong Sejong
35 + const BDG = await driver.wait(until.elementsLocated(By.css('#mCSB_8_container>ul>li>#btn')));//Busan Daegu Gyeongsang
36 + const GJ= await driver.wait(until.elementsLocated(By.css('#mCSB_9_container>ul>li>#btn')));//gwangju_jeonla
37 + const Gangwon = await driver.wait(until.elementsLocated(By.css('#mCSB_10_container>ul>li>#btn')));
38 + const location_list = [seoul, Gyeonggi, Incheon, DCS, BDG, GJ, Gangwon]//
39 + for(let i = 0; i < location_list.length; i++){
40 + for (item of location_list[i]) {
41 + location_data[index++] = {
42 + 'LocationName':await item.getAttribute("brch-nm"),
43 + 'LocationNum' : await item.getAttribute("brch-no")
44 + }
45 + // let location_name = await item.getAttribute("brch-nm");
46 + // let location_num = await item.getAttribute("brch-no");
47 + // let obj = {};
48 + // obj[location_name]= location_num
49 + // location_data[index++] = obj;
50 + }
51 + }
52 + let movie_list = await driver.wait(until.elementsLocated(By.css('#mCSB_1_container>ul>li>.btn')));
53 + r = 0;
54 + for (item of movie_list) {
55 + //Using getAttribute to get the data
56 + movie_data[r++] = {
57 + 'rank' : r,
58 + 'title' : await item.getAttribute("movie-nm"),
59 + 'movie_num':await item.getAttribute("movie-no"),
60 + }
61 + }
62 +
63 + driver.close();
64 +
65 + },
66 + async () => {
67 + r = 0;
68 + const browser = await puppeteer.launch({
69 + headless: true
70 + });
71 + const page = await browser.newPage();
72 + await page.goto(rate_url);
73 + const content = await page.content();
74 +
75 + const $ = cheerio.load(content);
76 + const $rate_lists = $("ol.list>li");
77 + $rate_lists.each((index, list) => {
78 + const name = $(list).find('div.tit-area > p.tit').attr('title');
79 + const rate = $(list).find('div.rate-date > span.rate').text();
80 +
81 + if(movie_data[r].title === name){
82 + movie_data[r++]['rate'] = rate;
83 + }
84 + });
85 + for(i of movie_data){
86 + if(Object.keys(i).length==3){
87 + movie_data[r++]['rate'] = '예매율 0%';
88 + }
89 + }
90 +
91 + browser.close();
92 + console.log("Comepleted!");
93 + },
94 +
95 +])}
96 +
97 +let appdriver;
98 +exports.using_PlayingMovieURL = async(PlayingMovieURL) => {
99 + appdriver = new webdriver.Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless()).build();
100 + appdriver.get(PlayingMovieURL);
101 + //appdriver.switchTo().frame(0)
102 + //frameBokdMBooking 프레임 가져옴
103 +}
104 +exports.geting_PlayingMovie= async() => {
105 + let movie_list = await appdriver.wait(until.elementsLocated(By.css('#mCSB_1_container>ul>li>.btn')));
106 + let n = 0;
107 + console.log(movie_list);
108 + for (item of movie_list) {
109 + movie_data[n++]['running'] = await item.getAttribute('form-at');
110 + }
111 + console.log("Completed get Running");
112 +}
113 +
114 +app.listen(5000);
...\ No newline at end of file ...\ No newline at end of file
1 +const megabox = require('./Megabox.js');
2 +//const SearchingTheaterAPI = require('./SearchingTheaterAPI');
3 +const async = require('async');
4 +megabox.init(); //메가박스 코드 시작(영화관 리스트 가져오기)
5 +const PUSH_TARGET_URL = 'https://api.line.me/v2/bot/message/push'
6 +const REPLY_TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
7 +const asyncHandler = require('express-async-handler')
8 +const bodyParser = require('body-parser');
9 +const request = require('request');
10 +const moment = require("moment");
11 +const HTTPS = require('https');
12 +const path = require('path');
13 +const fs = require('fs');
14 +const sslport = 23023;
15 +var express = require('express');
16 +var app = express();
17 +app.use(bodyParser.json());
18 +/////////////////////////////////////////////////
19 +// commit 할때 지워야 할것들
20 +const USER_ID = '';
21 +const TOKEN = '';
22 +const domain = '';
23 +const KAKAO_KEY = '';
24 +/////////////////////////////////////////////////
25 +
26 +let MEGA_date;
27 +let MEGA_TheaterLocation;
28 +let MEGA_TheaterLocationCode;
29 +let MEGA_PlayingMovieList = [];
30 +let MEGA_title;
31 +let MEGA_PlayingMovieURL;
32 +let initFlag = false; //브랜드 선택 flag
33 +let MEGA_flag = -1; //메가박스 인지 확인하는 flag
34 +let MEGA_count; //메가박스에서 영화관 판단하는 count
35 +let MEGA_AbleLocationList = []; //메가박스에서 영화관 이름 매치하는 것 저장하는 list
36 +let MegaboxKakaoResultTheater = [];
37 +exports.MEGA_PlayingMovieURL = MEGA_PlayingMovieURL;
38 +////////////////////////////////////////////////
39 +//처음 영화관을 가져오는 것까지 대략 30초가 걸림 => 30초 기다리고 메세지 전송
40 +
41 +setTimeout(function () {
42 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
43 +}, 30000);
44 +
45 +//app.post('/hook', function (req, res) {
46 +app.post('/hook', asyncHandler(async (req, res, next) => {
47 + var eventObj = req.body.events[0];
48 + var source = eventObj.source;
49 + var message = eventObj.message;
50 + // request log
51 + console.log('======================', new Date(), '======================');
52 + console.log('[request]', req.body);
53 + console.log('[request source] ', eventObj.source);
54 + console.log('[request message]', eventObj.message);
55 + //어느 순간에서든 "브랜드"를 입력해 원하는 브랜드 선택
56 + //initFlag : false ==> 브랜드 선택 전
57 + //initFlag : true ==> 브랜드 선택 됨
58 + if (eventObj.message.text == "브랜드") {
59 + initFlag = false;
60 + MEGA_flag = -1;
61 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
62 + }
63 + //브랜드 선택- 메가박스 인 경우 MEGA_flag를 0으로 두어 메가박스 임을 확인
64 + if (initFlag == false && eventObj.message.text == 3) {
65 + initFlag = true;
66 + MEGA_flag = 0;
67 + }
68 + //메가박스로 브랜드 선택된 경우
69 + if (initFlag == true && MEGA_flag != -1) {
70 + if (MEGA_flag == 0) {
71 + const text1 = "영화관 위치를 입력해주세요";
72 + const text2 = "ex1)강남";
73 + SendMessage(eventObj, text1, text2);
74 + MEGA_flag++;
75 + //PusbuttonhMessage("https://developers.line.biz/en/reference/messaging-api/#message-common-properties");
76 + //console.log(MEGA_flag)
77 + }else if (MEGA_flag === 1) {
78 + MEGA_count = 0; //MEGA_count 초기화
79 + MEGA_AbleLocationList.length = 0; //MEGA_AbleLocationList 초기화
80 + for (i of megabox.location_data) {
81 + if (i['LocationName'].includes(message.text)) {
82 + MEGA_AbleLocationList[MEGA_count++] = i;
83 + }
84 + }
85 +
86 + if (MEGA_count == 1) { //결과 1개 => 바로 다음 단계 넘어가기
87 + MEGA_TheaterLocation = MEGA_AbleLocationList[0].LocationName;
88 + MEGA_TheaterLocationCode = MEGA_AbleLocationList[0].LocationNum;
89 + console.log(MEGA_TheaterLocation, MEGA_TheaterLocationCode);
90 + MEGA_flag++;
91 + } else if (MEGA_count > 1) { //결과 2개 이상 => 리스트 출력해주고 번호로 입력받아 넘어가기
92 + console.log(MEGA_AbleLocationList[0], MEGA_AbleLocationList[1]);
93 + let MEGA_OutputString = "원하시는 상영관의 번호를 정확히 입력해주세요\n"; //메가박스 영화관 가능 정보 string
94 + //PushSingleMessage("원하시는 상영관의 번호를 정확히 입력해주세요");
95 + for (let x = 0; x < MEGA_count; x++) {
96 + //PushSingleMessage(String(x + 1) + ": " + MEGA_AbleLocationList[x].LocationName);
97 + MEGA_OutputString += String(x + 1) + ": " + MEGA_AbleLocationList[x].LocationName + "\n";
98 + console.log(String(x + 1), MEGA_AbleLocationList[x].LocationName);
99 + }
100 + MEGA_OutputString += String(MEGA_count + 1) + ": 다시 검색하기";
101 + PushSingleMessage(MEGA_OutputString);
102 + MEGA_flag = 101;
103 + } else {
104 + PushSingleMessage("다시 입력해주세요.");
105 + }
106 + //원본 코드
107 + //console.log(MEGA_flag);
108 + // for (i of megabox.location_data) {
109 + // if (i['LocationName'] === message.text) {
110 + // MEGA_TheaterLocationCode = i['LocationNUm'];
111 + // console.log(MEGA_TheaterLocationCode);
112 + // MEGA_flag++;
113 + // console.log(MEGA_flag)
114 + // break;
115 + // }
116 + // }
117 + } else if (MEGA_flag == 101) {
118 + // 0< input || input > MEGA_count+1 : 다시 검색
119 + let tempNum = parseInt(message.text);
120 + if (tempNum > 0 && tempNum < MEGA_count + 1) {
121 + //번호에 맞는 LocationCode 전달
122 + MEGA_TheaterLocation = MEGA_AbleLocationList[tempNum - 1].LocationName;
123 + MEGA_TheaterLocationCode = MEGA_AbleLocationList[tempNum - 1].LocationNum;
124 + console.log(MEGA_TheaterLocation, MEGA_TheaterLocationCode);
125 + MEGA_flag = 2;
126 + } else {
127 + //다시 장소 입력받기
128 + const text1 = "영화관 위치를 입력해주세요";
129 + const text2 = "ex1)강남";
130 + SendMessage(eventObj, text1, text2);
131 + MEGA_flag = 1;
132 + }
133 + }
134 + //날짜 입력 받기
135 + if (MEGA_flag == 2) {
136 + const text1 = "현재 영화관은 " + MEGA_TheaterLocation + " 입니다.\n영화를 보실 날짜를 입력해주세요.";
137 + const text2 = "ex)20020409";
138 + SendMessage(eventObj, text1, text2);
139 + MEGA_flag = 3;
140 + }
141 + //날짜 확인 및 날짜, 장소에 대해 상영중인 영화 리스트 가져오기
142 + if (moment(message.text, "YYYYMMDD", true).isValid() && MEGA_flag == 3) {
143 + MEGA_date = parseInt(message.text);
144 + let today = GettingToday();//오늘 이후인지 확인하기 위해 날짜 가져옴
145 + //console.log(MEGA_date, MEGA_TheaterLocation);
146 + if (today<=MEGA_date && MEGA_date && MEGA_TheaterLocationCode) {
147 + const text1 = "현재상영작을 가져오는 중입니다.";
148 + const text2 = "잠시만 기다려주세요.";
149 + PushMessage(text1, text2);
150 + MEGA_PlayingMovieURL = "https://megabox.co.kr/on/oh/ohb/SimpleBooking/simpleBookingPage.do" + '?brchNo1=' + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
151 + megabox.using_PlayingMovieURL(MEGA_PlayingMovieURL);
152 + await megabox.geting_PlayingMovie();
153 + console.log(MEGA_PlayingMovieURL, megabox.movie_data);
154 + MEGA_flag = 4;
155 + }
156 + else{
157 + const text1 = "영화를 보실 날짜를 다시 입력해주세요.";
158 + const text2 = "ex)20020409";
159 + SendMessage(eventObj, text1, text2);
160 + }
161 + //원본 코드
162 + // MEGA_date = parseInt(eventObj.message.text);
163 + // if (MEGA_date && MEGA_TheaterLocationCode) {
164 + // MEGA_PlayingMovieURL = "https://megabox.co.kr/on/oh/ohb/SimpleBooking/simpleBookingPage.do" + '?brchNo1=' + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
165 + // console.log(MEGA_PlayingMovieURL)
166 + // async.waterfall[
167 + // megabox.using_PlayingMovieURL(MEGA_PlayingMovieURL),
168 + // megabox.geting_PlayingMovie()
169 + // ]
170 + // MEGA_flag++
171 + // console.log(MEGA_flag);
172 + // }
173 + }
174 + if (MEGA_flag == 4) {
175 + let obj = {};
176 + let n;
177 + let PlayingMovie = "-현재 상영작-\n\n";
178 + let movietitle;
179 + console.log(megabox.movie_data);
180 + for (n = 0; n < Object.keys(megabox.movie_data).length; n++) {
181 + if (megabox.movie_data[n].running == 'Y') {
182 + console.log(megabox.movie_data[n]);
183 + movietitle = megabox.movie_data[n].title;
184 + MEGA_PlayingMovieList[movietitle] = megabox.movie_data[n].movie_num;
185 + }
186 + }
187 + console.log(Object.keys(MEGA_PlayingMovieList).length);
188 + if (Object.keys(MEGA_PlayingMovieList).length == 0) {
189 + PushSingleMessage("현재상영작이 없습니다.\n영화관 선택 단계로 이동합니다.");
190 + setTimeout(function () {
191 + PushMessage("영화관 위치를 입력해주세요", "ex1)강남");
192 + }, 1000);
193 + MEGA_flag = 1;
194 + }else if (Object.keys(MEGA_PlayingMovieList).length == 1) {
195 + PlayingMovie += '1: ' + Object.keys(MEGA_PlayingMovieList)[0];
196 + PushMessage(PlayingMovie, "바로 링크가 보내집니다.");
197 + MEGA_title = MEGA_PlayingMovieList[Object.keys(MEGA_PlayingMovieList)[0]];
198 + setTimeout(function () {
199 + const PC_final_URL = "https://www.megabox.co.kr/booking?rpstMovieNo=" + MEGA_title + "&brchNo1=" + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
200 + const Smartphone_final_URL = "https://m.megabox.co.kr/booking/movie?movieNo="+ MEGA_title + "&brchNo1=" + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
201 + PushURLMessage(PC_final_URL, Smartphone_final_URL);
202 + setTimeout(function () {
203 + initFlag = false;
204 + MEGA_flag = -1;
205 + MEGA_PlayingMovieList = [];
206 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
207 + }, 1000);
208 + }, 1000);
209 + } else {
210 + let index = 0;
211 + for (let playingmovie = 0; playingmovie < Object.keys(MEGA_PlayingMovieList).length; playingmovie++) {
212 + PlayingMovie += (playingmovie + 1).toString() + '. ' + Object.keys(MEGA_PlayingMovieList)[index++];
213 + PlayingMovie += "\n";
214 + }
215 + console.log(PlayingMovie);
216 + await PushMessage(PlayingMovie, "예매할 영화 번호를 입력해주세요.\n ex)1 (영화 앞 숫자만 입력)");
217 + MEGA_flag = 5;
218 + }
219 + }else if (MEGA_flag == 5) {
220 + const index = parseInt(message.text) - 1;
221 + MEGA_title = MEGA_PlayingMovieList[Object.keys(MEGA_PlayingMovieList)[index]];
222 + const PC_final_URL = "https://www.megabox.co.kr/booking?rpstMovieNo=" + MEGA_title + "&brchNo1=" + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
223 + const Smartphone_final_URL = "https://m.megabox.co.kr/booking/movie?movieNo="+ MEGA_title + "&brchNo1=" + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
224 + console.log(PC_final_URL, Smartphone_final_URL);
225 + PushURLMessage(PC_final_URL, Smartphone_final_URL);
226 + MEGA_PlayingMovieList = []; //영화 리스트 초기화
227 + MegaboxKakaoResultTheater = [];
228 + GetMegaboxKakaoMapURL(MEGA_TheaterLocation);
229 + setTimeout(function () {
230 + console.log(MegaboxKakaoResultTheater[0]);
231 + let MegaboxKakaoResultTheaterNAME = MegaboxKakaoResultTheater[0]['theater_name'];
232 + let MegaboxKakaoResultTheaterURL = MegaboxKakaoResultTheater[0]['theater_url'];
233 + console.log(MegaboxKakaoResultTheaterNAME, MegaboxKakaoResultTheaterURL);
234 + PushMessage(MegaboxKakaoResultTheaterURL, "카카오맵으로 검색한 " + MegaboxKakaoResultTheaterNAME+ "의 위치입니다.");
235 + setTimeout(function () {
236 + //EGA_PlayingMovieList = [];
237 + initFlag = false;
238 + MEGA_flag = -1;
239 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
240 + }, 1000);
241 + }, 2000);
242 + }
243 + }
244 + res.sendStatus(200);
245 +}))
246 +//});
247 +try {
248 + const option = {
249 + ca: fs.readFileSync('/etc/letsencrypt/live/' + domain + '/fullchain.pem'),
250 + key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/privkey.pem'), 'utf8').toString(),
251 + cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/cert.pem'), 'utf8').toString(),
252 + };
253 + HTTPS.createServer(option, app).listen(sslport, () => {
254 + console.log(`[HTTPS] Server is started on port ${sslport}`);
255 + });
256 +} catch (error) {
257 + console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.');
258 + console.log(error);
259 +}
260 +//오늘 날짜 구하기
261 +function GettingToday(){
262 + var today = new Date();
263 + var year = today.getFullYear();
264 + var month = ('0' + (today.getMonth() + 1)).slice(-2);
265 + var day = ('0' + today.getDate()).slice(-2);
266 + var dateString = year + month + day;
267 + var dateInt = parseInt(dateString);
268 + console.log(dateInt);
269 + return dateInt;
270 +}
271 +
272 +//24시간마다 데이터 초기화
273 +var dayInMilliseconds = 1000 * 60 * 60 * 24;
274 +setInterval(function() { megabox.init(); console.log("success") },dayInMilliseconds );
275 +
276 +//Megabox - Kakao API로 영화관 위치 찾기
277 +GetMegaboxKakaoMapURL= async(LOCATE) => {
278 + let KAKAOOPTION = {
279 + url: "https://dapi.kakao.com/v2/local/search/keyword",
280 + method: "GET",
281 + headers: {
282 + 'Authorization': `KakaoAK ${KAKAO_KEY}` // commit 할때 지워야 할것
283 + },
284 + qs: {
285 + 'query': '메가박스 ' + LOCATE, // 메가박스 영화관이름
286 + //'category_group_code' : 'CT1',
287 + 'size': 5
288 + },
289 + encoding: 'UTF-8'
290 + };
291 + let selectable_theaters = [];
292 + request(KAKAOOPTION, function (err, res, body) {
293 + info_list = JSON.parse(body).documents;
294 +
295 + if (!err && res.statusCode == 200) {
296 + info_list.forEach(info => {
297 + //console.log(info.category_name);
298 + if (info.category_name.endsWith("메가박스")) {
299 + const theater_info = {
300 + "theater_name": info.place_name,
301 + "theater_url": info.place_url
302 + };
303 + //console.log(theater_info);
304 + //return theater_info;
305 + selectable_theaters.push(theater_info);
306 + }
307 + });
308 + }
309 + console.log(selectable_theaters);
310 + MegaboxKakaoResultTheater = selectable_theaters;
311 + return;
312 + });
313 +
314 +}
315 +
316 +//메세지 전송하는 function 모음
317 +function SendMessage(eventObj, text1, text2 = "") { //reply message
318 + request.post(
319 + {
320 + url: REPLY_TARGET_URL,
321 + headers: {
322 + 'Authorization': `Bearer ${TOKEN}`
323 + },
324 + json: {
325 + "replyToken": eventObj.replyToken,
326 + "messages": [
327 + {
328 + "type": "text",
329 + "text": text1
330 + },
331 + {
332 + "type": "text",
333 + "text": text2
334 + }
335 + ]
336 + }
337 + }, (error, response, body) => {
338 + console.log(body);
339 + });
340 +}
341 +function PushMessage(text1, text2 = "") { //push two message
342 + request.post(
343 + {
344 + url: PUSH_TARGET_URL,
345 + headers: {
346 + 'Authorization': `Bearer ${TOKEN}`
347 + },
348 + json: {
349 + "to": `${USER_ID}`,
350 + "messages": [
351 + {
352 + "type": "text",
353 + "text": text1
354 + },
355 + {
356 + "type": "text",
357 + "text": text2
358 + }
359 + ]
360 + }
361 + }, (error, response, body) => {
362 + console.log(body)
363 + });
364 +}
365 +function PushSingleMessage(text1) {//push single message
366 + request.post(
367 + {
368 + url: PUSH_TARGET_URL,
369 + headers: {
370 + 'Authorization': `Bearer ${TOKEN}`
371 + },
372 + json: {
373 + "to": `${USER_ID}`,
374 + "messages": [
375 + {
376 + "type": "text",
377 + "text": text1
378 + }
379 + ]
380 + }
381 + }, (error, response, body) => {
382 + console.log(body)
383 + });
384 +}
385 +function PushURLMessage(pcurl, smartphoneurl) {//push single message
386 + request.post(
387 + {
388 + url: PUSH_TARGET_URL,
389 + headers: {
390 + 'Authorization': `Bearer ${TOKEN}`
391 + },
392 + json: {
393 + "to": `${USER_ID}`,
394 + "messages": [
395 + {
396 + "type": "text",
397 + "text": "pc버전 url입니다\n\n" + pcurl
398 + },
399 + {
400 + "type": "text",
401 + "text": "mobile버전 url입니다\n\n" + smartphoneurl
402 + }
403 + ]
404 + }
405 + }, (error, response, body) => {
406 + console.log(body)
407 + });
408 +}
This diff could not be displayed because it is too large.
1 +{
2 + "name": "megabox",
3 + "version": "1.0.0",
4 + "description": "",
5 + "main": "app.js",
6 + "scripts": {
7 + "test": "echo \"Error: no test specified\" && exit 1"
8 + },
9 + "keywords": [],
10 + "author": "",
11 + "license": "ISC",
12 + "dependencies": {
13 + "async": "^3.2.3",
14 + "body-parser": "^1.20.0",
15 + "cheerio": "^1.0.0-rc.11",
16 + "chromedriver": "^101.0.0",
17 + "express": "^4.18.1",
18 + "express-async-handler": "^1.2.0",
19 + "moment": "^2.29.3",
20 + "puppeteer": "^14.1.1",
21 + "request": "^2.88.2",
22 + "selenium-webdriver": "^4.1.2"
23 + }
24 +}
1 +const chatbot = require("./app.js");
2 +const request = require('request');
3 +const cheerio = require('cheerio');
4 +const puppeteer = require('puppeteer');
5 +require('chromedriver');
6 +const {Builder,until} = require('selenium-webdriver'); //모듈 불러오기
7 +var webdriver = require('selenium-webdriver');
8 +var By = webdriver.By;
9 +const chrome = require('selenium-webdriver/chrome');//크롬 사용시
10 +const async = require('async')
11 +let express = require('express');
12 +let app = express();
13 +let bodyParser = require('body-parser');
14 +const { timeout } = require('async');
15 +app.use(bodyParser.urlencoded({ extended: false }));
16 +app.use(bodyParser.json());
17 +const booking_url = "https://megabox.co.kr/booking?";
18 +exports.booking_url = booking_url;
19 +const rate_url = "https://www.megabox.co.kr/movie";
20 +let r =0;
21 +let movie_data = [];
22 +exports.movie_data = movie_data;
23 +let location_data = [];
24 +exports.location_data = location_data;
25 +let index = 0;
26 +exports.init = ()=>{async.waterfall([//for 동기적 처리
27 + async () => {
28 + const driver = new webdriver.Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless()).build();//
29 + driver.get(booking_url);
30 + driver.switchTo().frame(0)//frameBokdMBooking 프레임 가져옴
31 + let seoul = await driver.wait(until.elementsLocated(By.css('#mCSB_4_container>ul>li>#btn')));
32 + let Gyeonggi = await driver.wait(until.elementsLocated(By.css('#mCSB_5_container>ul>li>#btn')));
33 + const Incheon = await driver.wait(until.elementsLocated(By.css('#mCSB_6_container>ul>li>#btn')));
34 + const DCS = await driver.wait(until.elementsLocated(By.css('#mCSB_7_container>ul>li>#btn')));//Daejeon Chungcheong Sejong
35 + const BDG = await driver.wait(until.elementsLocated(By.css('#mCSB_8_container>ul>li>#btn')));//Busan Daegu Gyeongsang
36 + const GJ= await driver.wait(until.elementsLocated(By.css('#mCSB_9_container>ul>li>#btn')));//gwangju_jeonla
37 + const Gangwon = await driver.wait(until.elementsLocated(By.css('#mCSB_10_container>ul>li>#btn')));
38 + const location_list = [seoul, Gyeonggi, Incheon, DCS, BDG, GJ, Gangwon]//
39 + for(let i = 0; i < location_list.length; i++){
40 + for (item of location_list[i]) {
41 + location_data[index++] = {
42 + 'LocationName':await item.getAttribute("brch-nm"),
43 + 'LocationNum' : await item.getAttribute("brch-no")
44 + }
45 + // let location_name = await item.getAttribute("brch-nm");
46 + // let location_num = await item.getAttribute("brch-no");
47 + // let obj = {};
48 + // obj[location_name]= location_num
49 + // location_data[index++] = obj;
50 + }
51 + }
52 + let movie_list = await driver.wait(until.elementsLocated(By.css('#mCSB_1_container>ul>li>.btn')));
53 + r = 0;
54 + for (item of movie_list) {
55 + //Using getAttribute to get the data
56 + movie_data[r++] = {
57 + 'rank' : r,
58 + 'title' : await item.getAttribute("movie-nm"),
59 + 'movie_num':await item.getAttribute("movie-no"),
60 + }
61 + }
62 +
63 + driver.close();
64 +
65 + },
66 + async () => {
67 + r = 0;
68 + const browser = await puppeteer.launch({
69 + headless: true
70 + });
71 + const page = await browser.newPage();
72 + await page.goto(rate_url);
73 + const content = await page.content();
74 +
75 + const $ = cheerio.load(content);
76 + const $rate_lists = $("ol.list>li");
77 + $rate_lists.each((index, list) => {
78 + const name = $(list).find('div.tit-area > p.tit').attr('title');
79 + const rate = $(list).find('div.rate-date > span.rate').text();
80 +
81 + if(movie_data[r].title === name){
82 + movie_data[r++]['rate'] = rate;
83 + }
84 + });
85 + for(i of movie_data){
86 + if(Object.keys(i).length==3){
87 + movie_data[r++]['rate'] = '예매율 0%';
88 + }
89 + }
90 +
91 + browser.close();
92 + console.log("Comepleted!");
93 + },
94 +
95 +])}
96 +const appdriver = new webdriver.Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless()).build();
97 +exports.using_PlayingMovieURL = async(PlayingMovieURL) => {
98 + appdriver.get(PlayingMovieURL);
99 + //appdriver.switchTo().frame(0)
100 + //frameBokdMBooking 프레임 가져옴
101 +}
102 +exports.geting_PlayingMovie= async() => {
103 + let movie_list = await appdriver.wait(until.elementsLocated(By.css('#mCSB_1_container>ul>li>.btn')));
104 + let n = 0;
105 + for (item of movie_list) {
106 + movie_data[n++]['running'] = await item.getAttribute('form-at');
107 + }
108 + console.log("Completed get Running");
109 +}
110 +// let userData = {
111 +// 'Date': '',
112 +// 'location':''
113 +// };
114 +// // const _sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
115 +// app.get('/Megabox', (req, res) => {
116 +// res.send(movie_data);
117 +// })
118 +// app.post('/Megabox', (req, res) => {//사용자에게 Date와 location(영화관 장소) 받아옴
119 +// let PlayingMovieURL;
120 +// userData['Date'] = req.body.Date;
121 +// for(i of location_data){
122 +// if(i['LocationName'] == req.body.location){
123 +// userData['location']=i['LocationNum'];
124 +// break;
125 +// }
126 +// }
127 +// PlayingMovieURL = booking_url + '?brchNo1='+userData['location']+'&playDe='+userData['Date'];//사용자 정보 바탕으로 해당 일자 영화관 영화 상영 여부 확인
128 +
129 +// appdriver.get(PlayingMovieURL);
130 +// appdriver.switchTo().frame(0)//frameBokdMBooking 프레임 가져옴
131 +// res.send(movie_data);
132 +// })
133 +// app.post('/Megabox', (req, res) => {//사용자에게 Date와 location(영화관 장소) 받아옴
134 +// userData['Date'] = req.body.Date;
135 +// for(i of location_data){
136 +// if(i['LocationName'] == req.body.location){
137 +// userData['location']=i['LocationNum'];
138 +// break;
139 +// }
140 +// }
141 +// let PlayingMovieURL = booking_url + '?brchNo1='+userData['location']+'&playDe='+userData['Date'];//사용자 정보 바탕으로 해당 일자 영화관 영화 상영 여부 확인
142 +
143 +// appdriver.get(PlayingMovieURL);
144 +// appdriver.switchTo().frame(0)//frameBokdMBooking 프레임 가져옴
145 +// res.send(movie_data);
146 +// })
147 +app.get('/Megabox/GetPlayingMovie', async(req, res, next) => {//영화 상영 여부 객체에 넣음
148 +
149 + // let movie_list = await appdriver.wait(until.elementsLocated(By.css('#mCSB_1_container>ul>li>.btn')));
150 + // let n = 0;
151 + // for (item of movie_list) {
152 + // movie_data[n++]['running'] = await item.getAttribute('form-at')
153 + // }
154 + using_PlayingMovieURL('https://megabox.co.kr/booking?brchNo1=4451&playDe=20220606');
155 + geting_PlayingMovie();
156 + res.send(PlayingMovieList);
157 +})
158 +app.listen(5000);
...\ No newline at end of file ...\ No newline at end of file
1 +const megabox = require('./Megabox.js');
2 +//const SearchingTheaterAPI = require('./SearchingTheaterAPI');
3 +const async = require('async');
4 +megabox.init(); //메가박스 코드 시작(영화관 리스트 가져오기)
5 +
6 +const PUSH_TARGET_URL = 'https://api.line.me/v2/bot/message/push'
7 +const REPLY_TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
8 +const asyncHandler = require('express-async-handler')
9 +const bodyParser = require('body-parser');
10 +const request = require('request');
11 +const moment = require("moment");
12 +const HTTPS = require('https');
13 +
14 +const path = require('path');
15 +const fs = require('fs');
16 +const sslport = 23023;
17 +
18 +var express = require('express');
19 +var app = express();
20 +app.use(bodyParser.json());
21 +
22 +/////////////////////////////////////////////////
23 +// commit 할때 지워야 할것들
24 +
25 +
26 +const USER_ID = '';
27 +const TOKEN = '';
28 +const domain = "";
29 +/////////////////////////////////////////////////
30 +
31 +let MEGA_date;
32 +let MEGA_TheaterLocation;
33 +let MEGA_TheaterLocationCode;
34 +let MEGA_PlayingMovieList = [];
35 +let MEGA_title;
36 +let MEGA_PlayingMovieURL;
37 +
38 +let initFlag = false; //브랜드 선택 flag
39 +let MEGA_flag = -1; //메가박스 인지 확인하는 flag
40 +
41 +let MEGA_count; //메가박스에서 영화관 판단하는 count
42 +let MEGA_AbleLocationList = []; //메가박스에서 영화관 이름 매치하는 것 저장하는 list
43 +
44 +exports.MEGA_PlayingMovieURL = MEGA_PlayingMovieURL;
45 +////////////////////////////////////////////////
46 +
47 +
48 +//처음 영화관을 가져오는 것까지 대략 30초가 걸림 => 30초 기다리고 메세지 전송
49 +setTimeout(function () {
50 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
51 +}, 30000);
52 +
53 +//app.post('/hook', function (req, res) {
54 +app.post('/hook', asyncHandler(async (req, res, next) => {
55 + var eventObj = req.body.events[0];
56 + var source = eventObj.source;
57 + var message = eventObj.message;
58 + // request log
59 + console.log('======================', new Date(), '======================');
60 + console.log('[request]', req.body);
61 + console.log('[request source] ', eventObj.source);
62 + console.log('[request message]', eventObj.message);
63 +
64 + //어느 순간에서든 "브랜드"를 입력해 원하는 브랜드 선택
65 + //initFlag : false ==> 브랜드 선택 전
66 + //initFlag : true ==> 브랜드 선택 됨
67 + if (eventObj.message.text == "브랜드") {
68 + initFlag = false;
69 + MEGA_flag = -1;
70 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
71 + }
72 +
73 + //브랜드 선택- 메가박스 인 경우 MEGA_flag를 0으로 두어 메가박스 임을 확인
74 + if (initFlag == false && eventObj.message.text == 3) {
75 + initFlag = true;
76 + MEGA_flag = 0;
77 + }
78 +
79 + //메가박스로 브랜드 선택된 경우
80 + if (initFlag == true && MEGA_flag != -1) {
81 + if (MEGA_flag == 0) {
82 + const text1 = "영화관 위치를 입력해주세요";
83 + const text2 = "ex1)강남";
84 + SendMessage(eventObj, text1, text2);
85 + MEGA_flag++;
86 + //PusbuttonhMessage("https://developers.line.biz/en/reference/messaging-api/#message-common-properties");
87 + //console.log(MEGA_flag)
88 + }else if (MEGA_flag === 1) {
89 + MEGA_count = 0; //MEGA_count 초기화
90 + MEGA_AbleLocationList.length = 0; //MEGA_AbleLocationList 초기화
91 + for (i of megabox.location_data) {
92 + if (i['LocationName'].includes(message.text)) {
93 + MEGA_AbleLocationList[MEGA_count++] = i;
94 + }
95 + }
96 +
97 + if (MEGA_count == 1) { //결과 1개 => 바로 다음 단계 넘어가기
98 + MEGA_TheaterLocation = MEGA_AbleLocationList[0].LocationName;
99 + MEGA_TheaterLocationCode = MEGA_AbleLocationList[0].LocationNum;
100 + console.log(MEGA_TheaterLocation, MEGA_TheaterLocationCode);
101 + MEGA_flag++;
102 + } else if (MEGA_count > 1) { //결과 2개 이상 => 리스트 출력해주고 번호로 입력받아 넘어가기
103 + console.log(MEGA_AbleLocationList[0], MEGA_AbleLocationList[1]);
104 + let MEGA_OutputString = "원하시는 상영관의 번호를 정확히 입력해주세요\n"; //메가박스 영화관 가능 정보 string
105 + //PushSingleMessage("원하시는 상영관의 번호를 정확히 입력해주세요");
106 +
107 + for (let x = 0; x < MEGA_count; x++) {
108 + //PushSingleMessage(String(x + 1) + ": " + MEGA_AbleLocationList[x].LocationName);
109 + MEGA_OutputString += String(x + 1) + ": " + MEGA_AbleLocationList[x].LocationName + "\n";
110 + console.log(String(x + 1), MEGA_AbleLocationList[x].LocationName);
111 + }
112 + MEGA_OutputString += String(MEGA_count + 1) + ": 다시 검색하기";
113 + PushSingleMessage(MEGA_OutputString);
114 + MEGA_flag = 101;
115 + } else {
116 + PushSingleMessage("다시 입력해주세요.");
117 + }
118 +
119 +
120 + //원본 코드
121 + //console.log(MEGA_flag);
122 + // for (i of megabox.location_data) {
123 + // if (i['LocationName'] === message.text) {
124 + // MEGA_TheaterLocationCode = i['LocationNUm'];
125 + // console.log(MEGA_TheaterLocationCode);
126 + // MEGA_flag++;
127 + // console.log(MEGA_flag)
128 + // break;
129 + // }
130 + // }
131 + } else if (MEGA_flag == 101) {
132 +
133 + // 0< input || input > MEGA_count+1 : 다시 검색
134 + let tempNum = parseInt(message.text);
135 +
136 + if (tempNum > 0 && tempNum < MEGA_count + 1) {
137 + //번호에 맞는 LocationCode 전달
138 + MEGA_TheaterLocation = MEGA_AbleLocationList[tempNum - 1].LocationName;
139 + MEGA_TheaterLocationCode = MEGA_AbleLocationList[tempNum - 1].LocationNum;
140 + console.log(MEGA_TheaterLocation, MEGA_TheaterLocationCode);
141 + MEGA_flag = 2;
142 + } else {
143 + //다시 장소 입력받기
144 + const text1 = "영화관 위치를 입력해주세요";
145 + const text2 = "ex1)강남";
146 + SendMessage(eventObj, text1, text2);
147 + MEGA_flag = 1;
148 + }
149 + }
150 + //날짜 입력 받기
151 + if (MEGA_flag == 2) {
152 + const text1 = "현재 영화관은 " + MEGA_TheaterLocation + " 입니다.\n영화를 보실 날짜를 입력해주세요.";
153 + const text2 = "ex)20020409";
154 + SendMessage(eventObj, text1, text2);
155 + MEGA_flag = 3;
156 + }
157 +
158 + //날짜 확인 및 날짜, 장소에 대해 상영중인 영화 리스트 가져오기
159 + if (moment(message.text, "YYYYMMDD", true).isValid() && MEGA_flag == 3) {
160 + MEGA_date = parseInt(message.text);
161 + //console.log(MEGA_date, MEGA_TheaterLocation);
162 + if (MEGA_date && MEGA_TheaterLocationCode) {
163 + const text1 = "현재상영작을 가져오는 중입니다.";
164 + const text2 = "잠시만 기다려주세요.";
165 + PushMessage(text1, text2);
166 + MEGA_PlayingMovieURL = "https://megabox.co.kr/on/oh/ohb/SimpleBooking/simpleBookingPage.do" + '?brchNo1=' + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
167 + megabox.using_PlayingMovieURL(MEGA_PlayingMovieURL);
168 + await megabox.geting_PlayingMovie();
169 + console.log(MEGA_PlayingMovieURL, megabox.movie_data);
170 + MEGA_flag = 4;
171 + }
172 +
173 + //원본 코드
174 + // MEGA_date = parseInt(eventObj.message.text);
175 +
176 + // if (MEGA_date && MEGA_TheaterLocationCode) {
177 + // MEGA_PlayingMovieURL = "https://megabox.co.kr/on/oh/ohb/SimpleBooking/simpleBookingPage.do" + '?brchNo1=' + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
178 + // console.log(MEGA_PlayingMovieURL)
179 + // async.waterfall[
180 + // megabox.using_PlayingMovieURL(MEGA_PlayingMovieURL),
181 + // megabox.geting_PlayingMovie()
182 + // ]
183 + // MEGA_flag++
184 + // console.log(MEGA_flag);
185 + // }
186 + }
187 +
188 + if (MEGA_flag == 4) {
189 + let obj = {};
190 + let n;
191 + let PlayingMovie = "-현재 상영작-\n\n";
192 + let movietitle;
193 + console.log(megabox.movie_data);
194 + for (n = 0; n < Object.keys(megabox.movie_data).length; n++) {
195 + if (megabox.movie_data[n].running == 'Y') {
196 + console.log(megabox.movie_data[n]);
197 + movietitle = megabox.movie_data[n].title;
198 + MEGA_PlayingMovieList[movietitle] = megabox.movie_data[n].movie_num;
199 + }
200 + }
201 + console.log(Object.keys(megabox.movie_data).length);
202 + if (Object.keys(megabox.movie_data).length == 0) {
203 + PushMessage("현재상영작이 없습니다.","영화관 선택 단계로 이동합니다.");
204 + setTimeout(function () {
205 + PushMessage("영화관 위치를 입력해주세요", "ex1)강남");
206 + }, 1000);
207 + MEGA_flag = 1;
208 + }else if (Object.keys(MEGA_PlayingMovieList).length == 1) {
209 + PlayingMovie += '1. ' + Object.keys(MEGA_PlayingMovieList)[0];
210 + PushMessage(PlayingMovie, "바로 링크가 보내집니다.");
211 + MEGA_title = MEGA_PlayingMovieList[Object.keys(MEGA_PlayingMovieList)[0]];
212 + setTimeout(function () {
213 + const final_URL = "https://www.megabox.co.kr/booking?rpstMovieNo=" + MEGA_title + "&brchNo1=" + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
214 + console.log(final_URL)
215 + PushMessage(final_URL, "링크를 누르면 예매창으로 바로 이동합니다.");
216 + }, 1000);
217 +
218 + setTimeout(function () {
219 + initFlag = false;
220 + MEGA_flag = -1;
221 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
222 + }, 1000);
223 + } else {
224 + let index = 0;
225 + for (let playingmovie = 0; playingmovie < Object.keys(MEGA_PlayingMovieList).length; playingmovie++) {
226 + PlayingMovie += (playingmovie + 1).toString() + '. ' + Object.keys(MEGA_PlayingMovieList)[index++];
227 + PlayingMovie += "\n";
228 + }
229 + console.log(PlayingMovie);
230 + await PushMessage(PlayingMovie, "예매할 영화 번호를 입력해주세요.\n ex)1 (영화 앞 숫자만 입력)");
231 + MEGA_flag = 5;
232 + }
233 + }else if (MEGA_flag == 5) {
234 + const index = parseInt(message.text) - 1;
235 + MEGA_title = MEGA_PlayingMovieList[Object.keys(MEGA_PlayingMovieList)[index]];
236 + const final_URL = "https://www.megabox.co.kr/booking?rpstMovieNo=" + MEGA_title + "&brchNo1=" + MEGA_TheaterLocationCode + '&playDe=' + MEGA_date;
237 + console.log(final_URL);
238 + PushMessage(final_URL, "예매창으로 바로 이동합니다.");
239 + setTimeout(function () {
240 + initFlag = false;
241 + MEGA_flag = -1;
242 + PushSingleMessage("원하시는 브랜드의 번호를 입력해주세요.\n1: CGV\n2: LotteCinema\n3: Megabox\n언제든 브랜드를 바꾸고 싶으시다면 '브랜드'를 입력해주세요.");
243 + }, 1000);
244 + }
245 + }
246 +
247 + res.sendStatus(200);
248 +}))
249 +//});
250 +
251 +try {
252 + const option = {
253 + ca: fs.readFileSync('/etc/letsencrypt/live/' + domain + '/fullchain.pem'),
254 + key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/privkey.pem'), 'utf8').toString(),
255 + cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/cert.pem'), 'utf8').toString(),
256 + };
257 +
258 + HTTPS.createServer(option, app).listen(sslport, () => {
259 + console.log(`[HTTPS] Server is started on port ${sslport}`);
260 + });
261 +} catch (error) {
262 + console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.');
263 + console.log(error);
264 +}
265 +
266 +
267 +//메세지 전송하는 function 모음
268 +function SendMessage(eventObj, text1, text2 = "") { //reply message
269 + request.post(
270 + {
271 + url: REPLY_TARGET_URL,
272 + headers: {
273 + 'Authorization': `Bearer ${TOKEN}`
274 + },
275 + json: {
276 + "replyToken": eventObj.replyToken,
277 + "messages": [
278 + {
279 + "type": "text",
280 + "text": text1
281 + },
282 + {
283 + "type": "text",
284 + "text": text2
285 + }
286 + ]
287 + }
288 +
289 + }, (error, response, body) => {
290 + console.log(body);
291 + });
292 +}
293 +
294 +function PushMessage(text1, text2 = "") { //push two message
295 + request.post(
296 + {
297 + url: PUSH_TARGET_URL,
298 + headers: {
299 + 'Authorization': `Bearer ${TOKEN}`
300 + },
301 + json: {
302 + "to": `${USER_ID}`,
303 + "messages": [
304 + {
305 + "type": "text",
306 + "text": text1
307 + },
308 + {
309 + "type": "text",
310 + "text": text2
311 + }
312 + ]
313 + }
314 + }, (error, response, body) => {
315 + console.log(body)
316 + });
317 +}
318 +
319 +function PushSingleMessage(text1) {//push single message
320 + request.post(
321 + {
322 + url: PUSH_TARGET_URL,
323 + headers: {
324 + 'Authorization': `Bearer ${TOKEN}`
325 + },
326 + json: {
327 + "to": `${USER_ID}`,
328 + "messages": [
329 + {
330 + "type": "text",
331 + "text": text1
332 + }
333 + ]
334 + }
335 + }, (error, response, body) => {
336 + console.log(body)
337 + });
338 +}
339 +
340 +function PusbuttonhMessage(final_URL) {
341 + request.post(
342 + {
343 + url: PUSH_TARGET_URL,
344 + headers: {
345 + 'Authorization': `Bearer ${TOKEN}`
346 + },
347 + json:
348 +
349 + {
350 + "to": `${USER_ID}`,
351 + "type": "template",
352 + "altText": "this is a carousel template",
353 + "template": {
354 + "type": "carousel",
355 + "columns": [
356 + {
357 + "thumbnailImageUrl": "https://megabox.co.kr/SharedImg/2022/05/16/WApIttC9CrStYU7j7jzFRlc2HsIXBQtY_150.jpg",
358 + "imageBackgroundColor": "#FFFFFF",
359 + "title": "this is menu",
360 + "text": "description",
361 + "defaultAction": {
362 + "type": "uri",
363 + "label": "View detail",
364 + "uri": "https://megabox.co.kr/"
365 + },
366 + "actions": [
367 + {
368 + "type": "message",
369 + "label": "Yes",
370 + "text": "Yes"
371 + },
372 + {
373 + "type": "message",
374 + "label": "Yes",
375 + "text": "Yes"
376 + },
377 + {
378 + "type": "uri",
379 + "label": "View detail",
380 + "uri": "https://megabox.co.kr/"
381 + }
382 + ]
383 + },
384 +
385 + {
386 + "thumbnailImageUrl": "https://example.com/bot/images/item2.jpg",
387 + "imageBackgroundColor": "#000000",
388 + "title": "this is menu",
389 + "text": "description",
390 + "defaultAction": {
391 + "type": "uri",
392 + "label": "View detail",
393 + "uri": "http://example.com/page/222"
394 + },
395 + "actions": [
396 + {
397 + "type": "message",
398 + "label": "Yes",
399 + "text": "Yes"
400 +
401 + },
402 + {
403 + "type": "message",
404 + "label": "Yes",
405 + "text": "Yes"
406 +
407 + },
408 + {
409 + "type": "uri",
410 + "label": "View detail",
411 + "uri": "https://megabox.co.kr/"
412 + }
413 + ]
414 + }
415 + ],
416 + "imageAspectRatio": "rectangle",
417 + "imageSize": "cover"
418 + }
419 + }
420 + // {
421 + // "type": "template",
422 + // //"altText": "This is a buttons template",
423 + // "template": {
424 + // "type": "buttons",
425 + // "thumbnailImageUrl": "https://megabox.co.kr/SharedImg/2022/05/16/WApIttC9CrStYU7j7jzFRlc2HsIXBQtY_150.jpg",
426 + // "imageAspectRatio": "rectangle",
427 + // "imageSize": "cover",
428 + // "imageBackgroundColor": "#FFFFFF",
429 + // "title": "Menu",
430 + // "text": "Please select",
431 + // "actions": [
432 + // {
433 + // "type": "message",
434 + // "label": "Yes",
435 + // "text": "yes"
436 + // },
437 + // {
438 + // "type": "uri",
439 + // "label": "View detail",
440 + // "uri": final_URL
441 + // }
442 + // ]
443 + // }
444 + //}
445 + }
446 + )
447 +}
1 +{
2 + "name": "megabox",
3 + "version": "1.0.0",
4 + "description": "",
5 + "main": "app.js",
6 + "scripts": {
7 + "test": "echo \"Error: no test specified\" && exit 1"
8 + },
9 + "keywords": [],
10 + "author": "",
11 + "license": "ISC",
12 + "dependencies": {
13 + "async": "^3.2.3",
14 + "body-parser": "^1.20.0",
15 + "cheerio": "^1.0.0-rc.11",
16 + "chromedriver": "^101.0.0",
17 + "express": "^4.18.1",
18 + "puppeteer": "^14.1.1",
19 + "express-async-handler": "^1.2.0",
20 + "selenium-webdriver": "^4.1.2"
21 + }
22 +}
...\ No newline at end of file ...\ No newline at end of file
1 +[![node](https://img.shields.io/badge/Node-v16.15.0-important?logo=nodedotjs)](https://nodejs.org/ko/) [![express](https://img.shields.io/badge/Express-4.18.1-important?logo=express)](https://expressjs.com/ko/)
2 +[![puppeteer](https://img.shields.io/badge/puppeteer-v14.1.1-success?logo=Puppeteer)](https://github.com/puppeteer/puppeteer) [![selenium-webdriver](https://img.shields.io/badge/selenium--webdriver-v4.1.2-success?logo=Selenium)](https://www.selenium.dev/documentation/webdriver/) [![express-async-handler](https://img.shields.io/badge/express--async--handler-v1.2.0-success)](https://www.npmjs.com/package/express-async-handler) [![cheerio](https://img.shields.io/badge/cheerio-v1.0.0--rc.11-success)](https://cheerio.js.org/)
1 # 3대 멀티플렉스 통합 예매 챗봇 3 # 3대 멀티플렉스 통합 예매 챗봇
2 4
3 5
...@@ -20,14 +22,46 @@ CGV, 롯데시네마, MEGABOX 영화관의 정보를 통합 제공 및 예매를 ...@@ -20,14 +22,46 @@ CGV, 롯데시네마, MEGABOX 영화관의 정보를 통합 제공 및 예매를
20 + Line Messaging API 22 + Line Messaging API
21 + Kakao Search-by-Keyword API 23 + Kakao Search-by-Keyword API
22 24
23 -## Getting Started
24 25
25 -### Prerequisites 26 +## Getting Started
26 27
27 ### Installation 28 ### Installation
28 29
30 +1. Kakao REST API관련 KEY를 발급받습니다.
31 + [Kakao Search API](https://developers.kakao.com/)
32 +2. 해당 Repository를 Clone합니다.
33 + `git clone http://khuhub.khu.ac.kr/{YourID}/Multiplex_Ticketing_Platform.git`
34 +3. 코드를 실행하는데 필요한 npm 요소들을 Install합니다.
35 + `npm install`
36 +4. Line Messaging API - Webhook 설정에서 본인의 domain을 입력합니다.
37 +![webhook](https://ifh.cc/g/gQCJw4.png)
38 +5. 코드에 본인이 발급받은 API KEY, Domain을 입력합니다.
39 + `const USER_ID = '{YOUR OWN LINE MESSAGING API USER_ID}';`
40 + `const TOKEN = '{YOUR OWN LINE MESSAGING API TOKEN}';`
41 + `const domain = '{YOUR OWN DOMAIN}';`
42 + `const KAKAO_KEY = '{YOUR OWN KAKAO REST API KEY}';`
43 +6. QR 코드를 휴대폰의 카메라로 스캔하거나 <__@583zdtpz__>을 친구 찾기에 입력하여 "영화관통합예매챗봇"을 추가합니다.
44 +![](https://qr-official.line.me/sid/L/583zdtpz.png)
45 +
46 +
47 +## Usage
48 +
49 +챗봇을 추가하게 되면 자동으로 다음과 같은 메세지가 전송됩니다.
50 +
51 +![chatbot start message](https://ifh.cc/g/xfZdhM.png)
52 +
53 +영화 예매 링크를 받는데 까지는 총 4가지의 단계를 거치게 됩니다!
29 54
30 -# Contributing 55 +1. 브랜드 선택
56 +2. 영화관 선택
57 + 2-1.영화관 세부 선택
58 +3. 날짜 선택
59 +4. 상영 중인 영화 목록에서 원하는 영화 선택
60 +
61 +위와 같은 단계로 입력이 모두 완료되면 선택하신 영화 예매 링크 및 영화관 위치 링크를 챗봇을 통해 바로 전달받으실 수 있습니다!!
62 +
63 +
64 +## Contributing
31 65
32 1. 해당 Repository를 Fork합니다. 66 1. 해당 Repository를 Fork합니다.
33 `git fork http://khuhub.khu.ac.kr/2021105632/Multiplex_Ticketing_Platform.git` 67 `git fork http://khuhub.khu.ac.kr/2021105632/Multiplex_Ticketing_Platform.git`
...@@ -51,9 +85,7 @@ Apache License를 사용합니다. LICENSE.txt를 통해 자세한 정보를 확 ...@@ -51,9 +85,7 @@ Apache License를 사용합니다. LICENSE.txt를 통해 자세한 정보를 확
51 ## Contact 85 ## Contact
52 86
53 > 임승현 - kevinlsh17@khu.ac.kr 87 > 임승현 - kevinlsh17@khu.ac.kr
54 -
55 > 이혜인 - hil0409@khu.ac.kr 88 > 이혜인 - hil0409@khu.ac.kr
56 -
57 > 신승민 - s091506@khu.ac.kr 89 > 신승민 - s091506@khu.ac.kr
58 - 90 +>
59 > Project Link: [http://khuhub.khu.ac.kr/2021105632/Multiplex_Ticketing_Platform.git](http://khuhub.khu.ac.kr/2021105632/Multiplex_Ticketing_Platform.git) 91 > Project Link: [http://khuhub.khu.ac.kr/2021105632/Multiplex_Ticketing_Platform.git](http://khuhub.khu.ac.kr/2021105632/Multiplex_Ticketing_Platform.git)
...\ No newline at end of file ...\ No newline at end of file
......