簡報支援
github 支援
程式中一個迷途的小書僮
Hackathon Taiwan 合作講師
Node.js Party 籌辦人
JSDC 2015 總召集人
當然包括我 Orz
為什麼要叫做「月牙天衝」?
剛好最近又在看死神XD
因為我想不到一個帥氣的題目
如果我最近在看一拳超人
題目應該會是「Node.js One Punch Bot」XD
事前準備
Line BOT
Facebook BOT
Q & A
請相信我...準備那些 #$@% 才是花最多時間的...
Server
LINE developer
Domain
SSL
Faceboook developer
我是用 DigitalOcean
用好了大概是這樣XD
我用 godaddy
獲得新的 domain
設定 domain 指向哪一台主機 ip
我是用某位大大建議的 gogetssl
有一批 ssl 好便宜啊 !!
先在 server 上產生 key 與 csr
第一次操作可參考熱血漢誌的資料唷
server 上先安裝 openssl
simon@simon:~$ openssl req -new -newkey rsa:2048 -nodes
-sha256 -days 730 -keyout ~/XXX.key -out ~/XXX.csr
然後到你的設定頁面,把 csr 貼上去
認證過後,他們會寄 crt 到你的信箱
下載完整的檔案
解開檔案後會出現這些資料
把以下這些資料串聯在一起
產生出來的 real.crt 是真正要給 nginx 用的
simon@simon:~$ cat COMODORSADomainValidationSecureServerCA.crt
COMODORSAAddTrustCA.crt XXX.crt >> real.crt
把 XXX.key 與產生的 real.crt 擺放到 server 去
設定 nginx 並重啟
server {
listen 443 ssl;
root /usr/share/nginx/html;
index index.html index.htm;
server_name xxx.com;
ssl_certificate /etc/nginx/ssl/real.crt;
ssl_certificate_key /etc/nginx/ssl/XXX.key;
location / {
proxy_pass https://localhost:9898;
}
}
準備動作終於告一段落了
可是我不知道他現在還有沒有開放申請XD
先註冊一個新的 channel
這個頻道的 QR code
/*
* 處理 ssl 相關事務
*/
let config = require('./config.js');
let fs = require('fs');
let https = require('https');
let sslKey = fs.readFileSync(config.ssl.key, 'utf8');
let sslCrt = fs.readFileSync(config.ssl.cert, 'utf8');
let sslOptions = {
key: sslKey,
cert: sslCrt
};
/*
* server
*/
let express = require('express');
let app = express();
/*
* body parser 很重要,我卡了半天 Orz
*/
let bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
/*
* Line Bot 會用到的相關端點
*/
let lineBot = require('./lineBot');
/*
* Routers
*/
app.post('/line/callback', lineBot.callback);
/*
* 啟動 server
*/
let httpsServer = https.createServer(sslOptions, app);
httpsServer.listen(3000);
console.log('Listen https server at port 3000');
let request = require('request-promise');
let config = require('./config');
/*
* 這兩個值是固定的,一定要固定唷
*/
const eventType = '138311608800106203';
const toChannel = '1383378250';
module.exports = {
/*
* Line channal 傳過來的資料
*/
callback: function(req, res, next) {
// 1. 處理 line 傳過來的訊息
// 2. 分辨不同的內容
// 3. 組成回傳的物件
// 4. 回傳的訊息
}
};
// 1. 處理 line 傳過來的訊息
let data = req.body.result[0]; // 從 channels post 過來的資料
let contentType = data.content.contentType; // 傳過來的資料類型
let fromWho = data.content.from; // 誰傳過來的
// 2. 分辨不同的內容
let content;
switch(contentType) {
case 1:
content = {
toType: 1,
contentType: 1,
text: '你傳文字訊息給我'
};
break;
case 2:
// 照片處理
break;
case 8:
// 貼圖處理
break;
default:
content = {
toType: 1,
contentType: 1,
text: '我現在分別不出來你傳什麼碗糕給我'
};
}
// 3. 組成回傳的物件
let options = {
method: 'POST',
uri: 'https://trialbot-api.line.me/v1/events',
body: {
to: [fromWho],
toChannel: toChannel,
eventType: eventType,
content: content
},
headers: {
'Content-Type': 'application/json; charser=UTF-8',
'X-Line-ChannelID': config.line.channelId,
'X-Line-ChannelSecret': config.line.channelSecret,
'X-Line-Trusted-User-With-ACL': config.line.channelMID
},
json: true
};
// 4. 回傳的訊息
request(options)
.then(function (body) {
return res.status(200).send();
})
.catch(function (err) {
console.log(err);
return res.status(400).send();
});
It's Work!!!
參考資料
小心得
Line 的文件可以再更加強XD
創立粉絲專頁
新增應用程式
新增應用程式
產生粉絲專頁的 access_token
綁定 webhook
/*
* Facebook Bot 會用到的相關端點
*/
let facebookBot = require('./facebookBot');
app.get('/facebook/callback', facebookBot.verify);
app.post('/facebook/callback', facebookBot.callback);
多增加兩個 facebook 端點
module.exports = {
/*
* 驗證 Facebook message webhook
*/
verify: function(req, res, next) {
// 驗證這個 url 是否正確
if (req.query['hub.verify_token'] === '阿不就好棒棒') {
return res.send(req.query['hub.challenge']);
} else {
return res.send('Error, wrong validation token');
}
}
};
驗證 webhook 正確性
認證完成
module.exports = {
/*
* 驗證 Facebook message webhook
*/
verify: function(req, res, next) {
......
},
/*
* Facebook message
*/
callback: function(req, res, next) {
// 1. 處理傳進來的訊息
// 2. 處理發訊息,收訊息,訊息的內容
// 3. 要送出去的訊息格式
// 4. 訊息選項
// 5. 送出訊息
}
};
// 1. 處理傳進來的訊息
let messaging_events = req.body.entry[0].messaging; // 訊息的內容
let sender; // 送出訊息的人
let recipient; // 收到訊息的人
// 2. 處理發訊息,收訊息,訊息的內容
for(let i = 0; i < messaging_events.length; i++) {
let event = req.body.entry[0].messaging[i];
sender = event.sender.id;
recipient = event.recipient.id;
if (event.message && event.message.text) {
let text = event.message.text;
}
}
// 3. 要送出去的訊息格式
let messageData = {
text: 'JavaScript 好棒棒'
};
// 4. 訊息選項
let options = {
method: 'POST',
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: {
access_token: config.facebook.accessToken
},
body: {
message: messageData,
recipient: {
id: sender
}
},
json: true
};
// 5. 送出訊息
request(options)
.then(function (body) {
return res.status(200).send();
})
.catch(function (err) {
console.log(err);
return res.status(400).send();
});
It's work!!!!
參考資料
小心得
反應速度較慢
文件比 Line 清楚
官方 demo code 是用 Node.js
我不小心趴在桌子上睡著了.....
我夢到 vue.js
我夢到 Netflix
我夢到 Angular.js 2.0
我夢到 universal
啊....夢醒了,怎麼這麼真實!!!!