読者です 読者をやめる 読者になる 読者になる

ツタンラーメンの忘備録

プログラミングや精神疾患、ラーメンについて書いていきます。たぶん。

node.jsでPromiseを勉強しながら自分の過去ツイートを削除した(node-twitter)

Promiseはけっこうわかりづらいと思う(独断)のだけど、node.jsにおいて使えないとけっこうつらいです。つらいです。つらいです。

Promiseがどういうものでどういうふうに使うかというと下の記事がわかりやすいです。
qiita.com

むっちゃ雑に説明するとnode.js(javascript)における同期処理を非同期っぽく使いたいときに見た目がきれいになるものです。(独断)

ここでPromiseを解説しても仕方ないというかできないので、どういうことをしたくて、どういうふうにしたら動いたか軽く書いておきます。

twitter APIを叩いて

  1. 自分のアカウントのidを調べて
  2. 自分のツイートを辿って
  3. 全削除

したかった。でも、node.jsはツイッターのデータの取得を待っている間に次の処理が始まるんですよね。で、Promise。

大雑把に下のようなコードを描いています。例外処理とかきちんとしてくださいね。
node v6.2.1
npm v3.9.3
twitter v1.7.0

var Twitter = require('twitter');

var twitter = new Twitter({
    consumer_key: process.env.CONSUMER_KEY,
    consumer_secret: process.env.CONSUMER_SECRET,
    access_token_key: process.env.OAUTH_TOKEN,
    access_token_secret: process.env.OAUTH_TOKEN_SECRET,
});

var get_screen_name = function(){
  return new Promise(function(resolve, reject){
    twitter.get('account/settings', function(error, data, res){
      if(!error){
        resolve(data.screen_name);
      }
    });
  });
};

var get_tweets = function(screen_name){
  return new Promise(function(resolve, reject){
    var params = {
      count: 100,
      screen_name: screen_name,
    };
    twitter.get('statuses/user_timeline', params, function (error, tweets, response) {
      if (!error) {
        resolve(tweets);
      }
    });
  });
};

var delete_tweets = function(tweets){
  var promises = [];
  for (var i = 0; i < tweets.length; i++) {
    promises.push(delete_tweet(tweets[i]));
  }
  Promise.all(promises)
    .then(function (results) {
      console.log(results);
  });
};

var delete_tweet = function(tweet){
  return new Promise(function(resolve, reject){
    twitter.post('statuses/destroy', {id: tweet.id_str}, function(error, data){
      if(!error){
        resolve(data);
      }
    });
  });
};

get_screen_name()
  .then(get_tweets)
  .then(delete_tweets);

ツイートを一つずつdelete_tweetに放り込むんだけど、普通に

var delete_tweets = function(tweets){
  for(var i = 0; i < tweets.length; i++){
    delete_tweet(tweets[i]);
  }
};

とかやると同期非同期問題で順番がずれて死ぬ。
参考にしたのは下の記事
qiita.com

あとtwitter APIの使い方がいくつもなんかうまくいかなかった。
まずしばらく自分のタイムラインを取得する方法を探したのだけど、結果、自分のscreen_name(一般的に言えば@を抜いたユーザid)を取得後、そのidのツイートを遡るということをした。

あと意外と詰まったのがツイートのidの取得方法。
普通に

tweet.id;

で取れるんだけど、オーバーフローする?らしく全桁取得できていないっぽい。普通に

tweet.id_str;

にすれば文字列として出てくるので、処理できました。
あとこれはnode-twitterの仕様なのだけど
POST statuses/destroy/:id — Twitter Developers
ここを見て

    twitter.post('statuses/destroy/:id', {id: tweet.id_str}, function(error, data){

    });

ってしていたのだけど、これじゃ動かないです。

うーん…node.jsでtwitter弄る人が少ないせいか資料が少ない…。