Skip to content

Instantly share code, notes, and snippets.

@ahomu
Created April 17, 2011 15:07
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahomu/924104 to your computer and use it in GitHub Desktop.
Save ahomu/924104 to your computer and use it in GitHub Desktop.
nodeでTwitterのUser Streamを取得して,scoket.ioを通してwebkitNotificationsに渡す
uu.ready(function() {
var socket, notify, enable;
// デスクトップ通知をサポートしているかを判定しておく
if ( window.webkitNotifications ) {
notify = true;
uu("#detect").add('<p>READY: your browser is supported webkitNotifications.</p>');
} else {
notify = false;
uu("#detect").add('<p>ERROR: your browser does not support webkitNotifications.</p>');
}
// すでにOKしてもらっているなら,さっさとnotificationを有効にする
if ( window.webkitNotifications && (window.webkitNotifications.checkPermission() === 0) ) {
enable = true;
} else {
enable = false;
}
// 許可を求めてみる
uu('#allow_notification').click(function(evt)
{
evt.preventDefault();
// コラー
if ( !notify ) {
alert('サポートしてないってば');
} else {
window.webkitNotifications.requestPermission(function()
{
// OKしてもらえていれば,その時点でnotificationを有効にする
if ( window.webkitNotifications && window.webkitNotifications.checkPermission() === 0 ) {
enable = true;
}
});
}
});
// socket.io を接続するよー
socket = new io.Socket(null, { port: port });
socket.connect();
// 接続時にセッション判別用のcookieを送信
socket.on('connect', function() {
socket.send({
token: document.cookie
});
console.log('connect');
});
// サーバーからデータを受信
socket.on('message', function(msg) {
var date, chunk, popup;
date = new Date();
if ( msg == '' ) {
console.log(date + ': chunk data is empty');
} else {
chunk = uu.json.decode(msg);
console.log(chunk);
if ( !!chunk.text && !!chunk.user.screen_name ) {
if ( !!enable ) {
popup = window.webkitNotifications.createNotification(
chunk.user.profile_image_url,
chunk.user.screen_name,
chunk.text
);
popup.show();
setTimeout(function(){
popup.cancel();
}, 10000);
}
// とりあえず出力
uu('#list').add('<dt>' + date + ':' + chunk.user.screen_name + '</dt><dd>' + chunk.text + '</dd>');
}
}
});
// 切断
socket.on('disconnect', function(){
console.log('disconnect');
});
});
<!DOCTYPE html>
<html>
<head>
<title>hoge</title>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">var port = <%= port %>;</script>
<script type="text/javascript" src="/js/uupaa.js"></script>
<script type="text/javascript" src="/js/remotter.js"></script>
</head>
<body>
<div id="detect"></div>
<form action="" id="form">
<input id="allow_notification" type="submit" value="許可してちょ" />
</form>
<hr />
<dl id="list">
</dl>
</body>
</html>
/**
* what's port?
*/
var port = 3333;
/**
* require
*/
var express = require('express');
var ejs = require('ejs');
var io = require('socket.io');
var OAuth = require('oauth').OAuth;
/**
* server
*/
var app = express.createServer();
// セッション使うよ
var store = new (require('connect').session.MemoryStore)({
cookie : { httpOnly: false } // websocketからも参照するよ
});
app.use(express.cookieDecoder());
app.use(express.session({
store : store,
secret : 'himitsu'
}));
app.configure(function(){
app.use(express.staticProvider(__dirname + '/client', {
maxAge: 0 // キャッシュ,だめ,ぜったい
}));
app.use(express.bodyDecoder());
});
app.set('view engine', 'ejs');
app.set('view options', { layout: false });
app.listen(port);
/**
* oauth
*/
var oa = new OAuth("https://twitter.com/oauth/request_token",
"https://twitter.com/oauth/access_token",
"token",
"secret",
"1.0",
null,
"HMAC-SHA1");
/**
* action
*/
app.get('/', function(req, res)
{
var req_token = req.query.oauth_token,
req_secret= req.session.secret,
verifier = req.query.oauth_verifier;
// access
if ( req_token && verifier && req_secret ) {
console.log('------- use request token');
console.log(req_token);
console.log(req_secret);
oa.getOAuthAccessToken(req_token, req_secret, verifier, function(error, oauth_access_token, oauth_access_secret, results) {
if (error) {
console.log('get access token failed');
res.send(error, 500);
} else {
console.log('------- access token');
console.log(oauth_access_token);
console.log(oauth_access_secret);
console.log(results);
req.session.acs_token = oauth_access_token;
req.session.acs_secret = oauth_access_secret;
res.redirect('/');
}
});
// request
} else if ( !req.session.acs_token && !req.session.acs_secret ) {
oa.getOAuthRequestToken(function(error, oauth_request_token, oauth_request_secret, results) {
if (error) {
console.log('get request token faield');
res.send(error, 500);
} else {
console.log('------- request token');
console.log(oauth_request_token);
console.log(oauth_request_secret);
// request secretをsessionに格納
req.session.secret = oauth_request_secret;
// request token をauthorize URLに預けてリダイレクト
res.redirect('https://api.twitter.com/oauth/authorize?oauth_token=' + oauth_request_token);
}
});
// maybe authorized
} else {
res.render('remotter', { locals: { port: port } });
}
});
/**
* scoket connection
*/
var socket = io.listen(app);
socket.on('connection', function(client) {
console.log('--------client connected');
console.log(client.sessionId);
client.on('message', function(msg) {
console.log('--------received message');
console.log(msg);
var token = msg.token;
if ( token ) {
var parseCookie = require('connect').utils.parseCookie,
sess_id = parseCookie(token)['connect.sid'];
console.log('--------sess_id');
console.log(sess_id);
store.get(sess_id, function(error, session) {
if ( error ) {
console.log('fetch session data faield');
res.send(error, 500);
} else {
console.log('----------session');
console.log(session);
// クライアント切断時の破棄の仕方が不明
oa.getProtectedResource(
'https://userstream.twitter.com/2/user.json',
'GET',
session.acs_token,
session.acs_secret,
function (error, data, response) {
// Streamでなく,ふつうのHTTPレスポンスなモノはここに帰ってくる,はず
},
function (chunk) {
console.log('send chunk data');
client.send(chunk);
}
);
}
});
}
});
client.on('disconnect', function() {
console.log('disconnect');
});
});
/**
* startup message
*/
console.log('Server running at http://127.0.0.1:' + port + '/');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment