Twilioのcallback statusを保存するために必要になったのでサクッと作る
Twilio
status-callbacks
Node/Expressを使用するので、"ベスト・プラクティス: セキュリティー"を考慮する
Express
security
1.構成
Node : v0.10.48
Express : 4.15.4
OS : CentOS release 6.8
Port : 8443
2. 準備
HTTPS化するので事前に証明書を用意
今回は"letsencrypt"を使用
logディレクトリを作成
#mkdir -p /var/log/access
Postされたデータを保存するためredisを用意
#rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
#rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
#yum --enablerepo=remi,remi-test install redis
#/etc/init.d/redis start
iptablesを許可
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8443 -j ACCEPT
Node/Express/foreverなどpackegeをinstallする
2. Node script
app.js
// set modules
const basicAuth = require('basic-auth-connect');
const bodyParser = require('body-parser');
const express = require('express');
const fs = require('fs');
const helmet = require('helmet');
const https = require('https');
const morgan = require('morgan');
const client = require('redis').createClient();
// init express
const app = express();
// set cert and key
var options = {
key: fs.readFileSync( '/etc/letsencrypt/hoge/privkey.pem' ),
cert: fs.readFileSync( '/etc/letsencrypt/hoge/fullchain.pem' )
};
// post param parser
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// set basic auth
app.use(basicAuth('user_name', 'password'));
// set logging
var stream = fs.createWriteStream('/var/log/access/access.log', { flags: 'a' });
app.use(morgan({ stream: stream }));
// check header
app.use(helmet());
// set route
app.post('/', function(req, res) {
// save redis
var key = req.body.To;
var value = req.body.CallStatus;
client.set(key, value, function(){
});
// return mesg
res.send('POST request to the example.api.jp');
})
app.get('/CallStatus/:num?', function(req, res) {
// restrict source ip
var ip = req.connection.remoteAddress || req.socket.remoteAddress;
var key = req.params.num
if (ip.match(/xx\.xx\.xx\.xx/)){;
client.get(key, function(err, val){
if (err) return console.log(err);
res.send(val);
});
}else{
res.send('403 Forbidden', 403)};
});
// define server
var server = https.createServer(options,app);
server.listen(8443);
// console debug
console.log('Server start!');
3.起動
forever start app.js
3.Twilio設定
call.py
call = client.calls.create(
to = "+81XXXXXXXXX",
from_ = "+81XXXXXXXXX",
timeout = "15",
url = "https://example.api.ppsys.jp/message",
status_callback = "https://user_name:password@example.api.ppsys.jp:8443",
status_callback_method = "POST",
tatus_callback_event = ["completed"]
)
5.確認
今回は
callback statusの"To"を"key", "callstatus"を"value"とする
var key = req.body.To; // call number
var value = req.body.CallStatus; // completed|no-answer など
PostはソースIP制限なし、GetはソースIP制限あり
Basic認証はGet/Post両方で行う
Get
# curl https://user_name:password@example.api.jp:8443/CallStatus/+81xxxxxxx
架電後、値を取得できれば問題なし