tkm_71のブログ

自分のための備考録みたいなものです。

Node.js + Express + Twitter streamingAPI + Socket.io で下ネタにモザイクをかけるTwitterクライアントを作ってみる

今回は、Node.js + Twitter streamingAPI + Socket.io を用いて簡単なクライアントを作ってみた。
ただのクライアントだと面白く無いので、NGワード(下ネタ系)を含むツイートがあると、NGワードのみモザイクをしちゃう!

準備

Node.jsでのTwitterモジュールにはいくつかあるが、今回は以下のモジュールを使用.

(npm twitter)

$ npm install twitter


ブラウザにリアルタイムに反映させるために、ソケットも使用するため以下も準備。

$ npm install socket.io

あと個人的にExpressも使用してみたかったので、以下をグローバルインストール。あとexpress-generatorもインストール。

$ npm install -g express
$ npm install -g express-generator


とりあえず必要なものは揃った気がする。あとは他の方の記事を参考に実装。

実装

どんな感じにするのがいいのかわからないけど、とりあえず書いてみる。

・bin/wwwに追記

bin/www
var server = http.createServer(app);
var socket = require('../models/socket');
socket(server);

../models/socket.jsに、ソケット周りの処理と、twitter StreamingAPI周りの処理を書いちゃう。
※これでいいのかわからん。

socket.js
var socket = require('socket.io');
var twitter = require('twitter');

/*
以下の4つのxxは自分で調べて入力.
https://apps.twitter.com/
*/
var twit = new twitter({
  consumer_key: 'xx',
  consumer_secret: 'xx',
  access_token_key: 'xx',
  access_token_secret: 'xx'
});

function socket(server){
  io = socket.listen(server);
  var current_stream;

  io.on('connection', function(socket){
    socket.on('disconnect', function(){
        console.log('user disconnected');
        current_stream.destroy();
        current_stream = null;
    });

    socket.on('tweet', function(tweet){
      //ツイートする
      twit.post('statuses/update', {status : tweet}, function(err, tw, res){
        console.log ("tweeted");
      });
    });

    socket.on('msg', function(msg){
      twit.get('users/show', params, function(err, tw, res){
        //必要な情報だけクライアント側に送信
        var user_info = {
          id : tw.id,
          name : tw.name,
          s_name : tw.screen_name,
          icon : tw.profile_image_url
        };
        io.emit('msg', user_info);
      });
    });
    
    //(自分がフォローしているユーザの)TLを取得
    twit.stream('user', {}, function(stream) {
      current_stream = stream;
      stream.on('data', function(tweet) {
        if(tweet.user !== undefined){
          socket.emit('tw', tweet);
        }
      });
     
      stream.on('error', function(error) {
        throw error;
      });
    });
    
  });
}

module.exports = socket;
クライアント側(index.ejsなど)
<script src="/socket.io/socket.io.js"></script>
<script>
  $(function(){
    var socket = io();
    socket.emit('msg', "msg");
    socket.on('msg', function(data){
      console.log (data);
    });
    socket.on('tw', function(data){
      console.log (data);
    });
  });
  </script>

ソケットで受け取っている部分だけ。受け取ったあとは上手いこと書く。
まあこんな感じ書いておいてあとは実行したら上手いこといくと良いな。

$ npm start

認証機能について

一応、勉強のためにpassportを使ってみた。(一応ね)

app.js
//----------------------------------------
//passportの設定
app.use(require('express-session')({
  secret: 'catcatcat',
  resave: false,
  saveUninitialized: false
}));
var passport = require('passport');
var TwitterStrategy = require('passport-twitter').Strategy;

var TWITTER_CONSUMER_KEY = "xx";
var TWITTER_CONSUMER_SECRET = "xx";

app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function (user, done) {
  done(null, user.id);
});
 
passport.deserializeUser(function (obj, done) {
  done(null, obj);
});

passport.use(new TwitterStrategy({
        consumerKey: TWITTER_CONSUMER_KEY,
        consumerSecret: TWITTER_CONSUMER_SECRET,
        callbackURL: "http://localhost:3000/oauth/callback/" 
    },
    function (token, tokenSecret, profile, done) {
        console.log(token, tokenSecret);
        passport.session.id = profile.id;
        profile.twitter_token = token;
        profile.twitter_token_secret = tokenSecret;

        process.nextTick(function () {
            return done(null, profile);
        });
    }
));

//セッションの設定
var oauth = require('./routes/oauth');
app.use('/oauth', oauth);

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

ググりながら見よう見まねで書いてます。
ここで少し躓いたのですが、「app.use(cookieParser());」や「app.use('/', routes);」をする前にpassportの設定を済ませておかないとダメそう。

app.use(passport.initialize());
app.use(passport.session());

も忘れずに書いておく。

モザイクをかけたい!

今回はNGワードにモザイクをかけたい、ということでJSのライブラリを使ってクライアント側でモザイクを掛けてみる。

使い方はJavaScriptで画像やテキストにモザイクをかける方法【SPOILER ALERT!】を参考に、
予めモザイクをかけたいところにクラス(blur)を指定しておいて、スクリプトで任意のタイミングで発火させるだけ。

動かして見た

とりあえず起動して、「http://localhost:3000」にブラウザからアクセス。

f:id:tkm_71:20160215160016p:plain


このような感じで、自分のタイムラインをリアルタイムに持ってきてブラウザに表示させ、NGワード(今回は「下ネタ」、「おっぱい」)をモザイクで覆って見えないようにできました。クリックでモザイクを消したり、もう一度かけたり…あとミュートしてるという設定のユーザはツイート全体がモザイク。