์ด ๊ธ์ Nodejs, Heroku server๋ฅผ ์ด์ฉํ์ฌ ์์ ๋ง์ ํ์ด์ค๋ถ ์ฑ๋ด์ ๋ง๋ค์ด๋ณด๋ ํ ํ๋ฆฟ ์์ ์ ๋๋ค. ์ดํ์ Api.ai๋ฅผ ์ด์ฉํ์ฌ ๋ ๋๋ํ ์ฑ๋ด์ ๋ง๋๋ ๊ณผ์ ์ ํฌ์คํ ํ๊ฒ ์ต๋๋ค.
์ฑ๋ด์ ์ฌ์ฉ์๊ฐ ๋ณ๋๋ก ์น์ฌ์ดํธ๋ ์ฑ์ ๋ฐ๋ก ์คํํ์ง ์๊ณ ๋ ๋ํํ๋ฏ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ ์๋น์ค๋ค. ๊ธฐ์กด ์ฌ์ฉ์ ์์ ์ด ์ฐ๋ ๋ฉ์ ์ ๋ฅผ ํตํด ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค๋ ์ ์ด ํ์ฌ ๊ตฌ๊ธ, ํ์ด์ค๋ถ, ๋ง์ดํฌ๋ก์ํํธ, ํ ๋ ๊ทธ๋จ์ ๋น๋กฏํด ๊ตญ๋ด ๋ค์ด๋ฒ, ๋ค์ ๋ฑ IT ๋ถ์ผ ๊ธฐ์ ๋ค์ด ์ฑ๋ด์ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ฉ์ ์ ํ๋ซํผ์ ์ ๋ณด์ด๋ ์ค์ด๋ค.
[๋ค์ด๋ฒ ์ง์๋ฐฑ๊ณผ] ์ฑํ ๋ด, ์ฑ๋ด - ๋ฉ์ ์ ์๋น์ค ์ธ๊ณต์ง๋ฅ(AI)๊ณผ ๋ง๋๋ค (์ฉ์ด๋ก ๋ณด๋ IT)
- Javascript์ ๋ํ ๊ธฐ๋ณธ ์ง์(๋ฌธ๋ฒ)
- ์ํ์ฝ๋ฉ ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ณธ๊ฐ์ ์ถ์ฒํฉ๋๋ค.
- Nodejs
- Nodejs์์ ๋ค์ด๋ก๋ํฉ๋๋ค. LTS ๋ฒ์ ์ ์ถ์ฒํฉ๋๋ค.
- Git
- Git ์ค์น๋ ์ํ์ฝ๋ฉ ์ง์ฅ์์ ์จ Git ์ค ์ค์น๋ฐฉ๋ฒ ๊ฐ์๋ฅผ ๋ณด์๋ฉด ์์ํ๊ฒ ์งํํ์ค ์ ์์ต๋๋ค.
- Heroku
- heroku ์ ๊ฐ์ ํฉ๋๋ค.
- Facebook Account
- Facebook account๊ฐ ํ์ํฉ๋๋ค.
Nodejs์ค์นํ ํ์ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ด๋ก ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค. ์ค์น๋ ์ํ์ฝ๋ฉ Nodejs ์ค์น ๊ฐ์๋ฅผ ๋ณด์๋ฉด ์์ํ๊ฒ ์งํํ์ค ์ ์์ต๋๋ค.
์ค์น๋ฅผ ์๋ฃํ์ ํ, ์ํ๋ ํด๋/๋๋ ํ ๋ฆฌ์์ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ด๋ก ๊ธฐ๋ณธ ํ๋ก์ ํธ๋ฅผ ์์ฑํฉ๋๋ค.
์ ๊ฐ์ ๊ฒฝ์ฐ์๋ dev๋ผ๋ ํด๋๋ฅผ ์๋ก ์์ฑํ ํ(mkdir dev
)์, dev๋ก ๋ค์ด๊ฐ์(cd dev
) ํ๋ก์ ํธํ์ผ์ ์์ฑํ์์ต๋๋ค.
mkdir dev
cd dev
sudo npm install npm -g
npm init
npm install express request body-parser --save
npm init๋ฅผ ์คํํ์๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ฌผ์ด๋ณผํ
๋ฐ entry point
๋ง app.js
๋ก ์ค์ ํด์ฃผ์ ํ ๋๋จธ์ง๋ ์์ ๋กญ๊ฒ ์ค์ ํด์ฃผ์๋ฉด ๋ฉ๋๋ค.
package name: (dev)
version: (1.0.0)
description:
entry point: (index.js) app.js
test command:
git repository:
keywords:
author:
license: (ISC)
์๋์ ๊ฐ์ด ๋์ค๋ฉด ์ฑ๊ณต์ ๋๋ค. version์ ๋ค๋ฅด์ ๋ ๊ด์ฐฎ์ต๋๋ค.
+ [email protected]
+ [email protected]
+ [email protected]
added 96 packages in 5.53s
- Facebook Page
- Chat bot์ ์ ์ฉ์ํฌ
Facebook Page
๋ฅผ ๋ง๋์ ํ์ Facebook Developer Page์ ์ ์ํฉ๋๋ค.
- Chat bot์ ์ ์ฉ์ํฌ
- Facebook App
- Add a new App์ ๋๋ฅด์๊ณ ์๋ก์ด App์ ๋ง๋ญ๋๋ค.
- Messenger์์ set up๋ฒํผ์ ๋๋ฆ ๋๋ค.
์ด์ Heroku ์๋ฒ์ ๋ฐฐํฌ์ํฌ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ์์ฑํฉ๋๋ค.
app.js
๋ผ๋ ์ด๋ฆ์ผ๋ก ์ฒ์ nodejs๋ฅผ ํตํด npm install์ ์งํํ๋ ํด๋(์ด ๊ธ์ ๊ฒฝ์ฐ, devํด๋)์ ์ ์ฅํฉ๋๋ค.
'use strict'
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
app.set('port', (process.env.PORT || 5000));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', function(req, res) {
res.send('Hello world');
})
app.get('/webhook', function(req, res) {
if (req.query['hub.verify_token'] === 'VERIFY_TOKEN') {
res.send(req.query['hub.challenge']);
}
res.send('Error, wrong token');
})
app.listen(app.get('port'), function() {
console.log('running on port', app.get('port'));
})
app.js๋ฅผ ์์ฑํ์
จ๋ค๋ฉด ํด๋ ์์ ์๋ package.json
์ ์์ ํ์
์ผ ํฉ๋๋ค. ํ์ผ ๋ด์ main๊ณผ scripts ์์ ์๋ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํด์ค๋๋ค.
...
"main": "app.js",
"scripts": {
"start": "node app.js"
},
...
์ด์ ๋ฐฐํฌ ๋จ๊ณ์ ๋๋ค. git์ ์ฅ์๋ฅผ ๋ง๋์๊ณ heroku server๋ฅผ ๋ง๋์ ํ์, git push๋ฅผ ํตํด heroku์ ๋ฐฐํฌํด์ค๋๋ค.
git init
git add .
git commit -m 'init'
heroku create
git push heroku master
์ ๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์์ต๋๋ค.
KorChris$ heroku create
Creating app... done, โฌข YOUR_DYNO_NAME
https://YOUR_DYNO_NAME.herokuapp.com/ | https://git.heroku.com/YOUR_DYNO_NAME.git
KorChris$ git push heroku master
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1018 bytes | 0 bytes/s, done.
...
...
...
remote: Verifying deploy... done.
To https://git.heroku.com/YOUR_DYNO_NAME.git
199.........73c master -> master
์ด์ Heroku server์ ํ์ด์ค๋ถ App์ ์ฐ๊ฒฐ์์ผ์ค๋๋ค. ํ์ด์ค๋ถ ์ฑ ๊ด๋ฆฌ์ฐฝ์ ๊ฐ์ ์ ์ ๋จ๊ณ์ ๊ฐ์ด Messenger ํญ์ ํด๋ฆญํฉ๋๋ค.
Token Generation
- Token Generation์์ ์์ ์ด ๋ง๋ page๋ฅผ ๊ณ ๋ฅด์๊ณ
- ์์ฑ๋ Token์ Clickํด์ ๋ณธ์ธ๋ง ์ ์ ์๋๋ก ๊ธฐ๋กํด๋ก๋๋ค. ๋์ค์ ์ด token์ ์ด์ฉํด์ ํ๋ก๊ทธ๋๋ฐ์ ํ๊ฒ ๋ฉ๋๋ค.
๊ทธ ํ์๋ Webhook์ ์ค์ ํด์ผํฉ๋๋ค.
Webhook Setting
- token generation ํ๋จ์ ๋ค์๊ณผ ๊ฐ์ด Webhook์ ์ค์ ํ ์ ์๋ ํญ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
์๋์ ๊ฐ์ด heroku์์ ์์ฑ๋ Dyno์ URL์ ์
๋ ฅํ๊ณ ๋ค์ /webhook์ ๋ฃ์ด์ฃผ์๊ณ
VERIFY TOKEN์๋ 'VERIFY_TOKEN'์ ๋ฃ์ด์ค๋๋ค.
Webhook set up์ด ๋๋ฌ๋ค๋ฉด token generation๋ ์ฌ์ฉํ๋ page๋ฅผ ๋ค์ ์ ํํด์ฃผ์๊ณ , subscribe๋ฒํผ์ ํด๋ฆญํด์ค๋๋ค.
app.js๋ฅผ ์์ ํ์ฌ ์ฌ์ฉ์๊ฐ ๋ณด๋ธ text๋ฅผ ๊ทธ๋๋ก ๋ค์ ๋ณด๋ด๋ Echo Bot์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค. Token generation๋จ๊ณ์์ ๋ฐ์ token์ PAGE_ACCESS_TOKEN์ ๋ฃ์ด์ฃผ๊ณ , app.js๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค. ์์ธํ ์ฝ๋ ์ค๋ช ์ ๋ค์ ๊ธ์์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
'use strict'
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
//์์ ๋ฐ์ดํ ์ฌ์ด์ ๋ณธ์ธ์ด ๋ฐ์ผ์ token์ pasteํฉ๋๋ค.
//๋์ค์ ๋ณด์์ ์ํด์ ๋ฐ๋ก setting์ ํ๋ ๋ฐฉ๋ฒ์ ์๋ ค๋๋ฆฌ๊ฒ ์ต๋๋ค.
//์ด ํ ํฐ์ด ํฌํจ๋ ํ์ผ์ ์ ๋ ์
๋ก๋ํ๊ฑฐ๋ github์ ์ ์ฉ์ํค์ง ๋ง์ธ์.
var PAGE_ACCESS_TOKEN = 'YOUR TOKEN HERE';
app.set('port', (process.env.PORT || 5000));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', function(req, res) {
res.send('Hello world');
})
app.get('/webhook', function(req, res) {
if (req.query['hub.verify_token'] === 'VERIFY_TOKEN') {
res.send(req.query['hub.challenge']);
}
res.send('Error, wrong token');
})
app.post("/webhook", function(req, res) {
console.log("WEBHOOK GET IT WORKS");
var data = req.body;
console.log(data);
// Make sure this is a page subscription
if (data.object == 'page') {
// Iterate over each entry
// There may be multiple if batched
data.entry.forEach(function(pageEntry) {
var pageID = pageEntry.id;
var timeOfEvent = pageEntry.time;
// Iterate over each messaging event
pageEntry.messaging.forEach(function(messagingEvent) {
if (messagingEvent.optin) {
receivedAuthentication(messagingEvent);
} else if (messagingEvent.message) {
receivedMessage(messagingEvent);
} else if (messagingEvent.postback) {
receivedPostback(messagingEvent);
} else {
console.log("Webhook received unknown messagingEvent: ", messagingEvent);
}
});
});
res.sendStatus(200);
}
});
function receivedMessage(event) {
var senderId = event.sender.id;
var content = event.message.text;
var echo_message = "ECHO : " + content;
sendTextMessage(senderId, echo_message);
}
function receivedPostback(event) {
console.log("RECEIVED POSTBACK IT WORKS");
var senderID = event.sender.id;
var recipientID = event.recipient.id;
var timeOfPostback = event.timestamp;
var payload = event.postback.payload;
console.log("Received postback for user %d and page %d with payload '%s' " +
"at %d", senderID, recipientID, payload, timeOfPostback);
sendTextMessage(senderID, "Postback called");
}
function sendTextMessage(recipientId, message) {
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: {
recipient: { id: recipientId },
message: { text: message }
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ' + response.error);
}
});
}
app.listen(app.get('port'), function() {
console.log('running on port', app.get('port'));
})
app.js๋ฅผ ๋ชจ๋ ์์ฑํ์ จ์ผ๋ฉด Git์ ์ด์ฉํ์ฌ ์์ ๋ ํ์ผ์ ๋ค์ ๋ฐฐํฌํด์ค๋๋ค.
git add .
git commit -m 'echo bot'
git push heroku master
์ด์ Echo bot์ด ์์ฑ๋์์ต๋๋ค.
ํ์ด์ค๋ถ์ ํตํด์ ๋ฉ์ธ์ง๋ฅผ ๋ณด๋ด๋ด ์๋ค.
๋ค์ ๊ธ์์๋ ์ฝ๋ ๋ถ์ ๋ฐ ๋ ๋ง์ ํ์ด์ค๋ถ ๋ฉ์ ์ ๊ธฐ๋ฅ์ ์ ์ฉํ๋ ๋ฒ์ ๋ค๋ฃจ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ ๊ฐ ๋ค๋ฃฌ ์ฝ๋๋ ์ Github์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค.
Ref :