Help us understand the problem. What is going on with this article?

Tumblrの投稿をEvernoteに移植して、検索機能を補完する(Node.js)

More than 1 year has passed since last update.

はじめに

Tumblrは、Web上のすべての情報が集約される素晴らしいSNSです。
ダッシュボードから気に入った投稿をリブログし続けるだけで、自分のブログページをアイデアやインスピレーションの宝庫にすることができます。

しかし、Tumblrには自分のブログ内の投稿を検索する機能がありません。
また、困ったことに、Tumblrの投稿は検索エンジンにも引っ掛かりづらい特徴があります。*参考
そのため、「あの投稿の詳細なんだっけ?」と思っても、その投稿を検索できる手段が無いのです。

それならば、Tumblrの投稿をEvernoteに移植して検索できるようにしよう!

ということで、この記事では自分のTumblrの投稿をEvernoteに移植する方法を紹介します。

手順

Tumblrの投稿をEvernoteに移植する手順は、次の通りです。

  1. Tumblrから投稿データを取得
  2. 取得した投稿データを読み込んでEvernoteに投稿

以下、それぞれの手順で使えるソースコードの一例を示します。

1. Tumblrから投稿データを取得

この手順では、Tumblr APIを利用して、Tumblrから投稿データを取得します。

Tumblr APIを利用するには、OAuthの認証情報が必要です。
認証情報の取得には、以下の記事が参考になります。

認証情報が取得できたら、下記コードの所定の箇所にコピペして実行してください。

getTumblrPosts.js
var fs = require('fs');

// Authenticate via OAuth
var tumblr = require('tumblr.js');
var client = new tumblr.createClient({
    consumer_key: '**********',
    consumer_secret: '**********',
    token: '**********',
    token_secret: '**********'
});

// Set method option
var blogName = '**********';
var offsetRange = 20,
    postNum = *****
    loopCount = Math.round(postNum/offsetRange);

var i = 0;
var outputJSON = {
    "posts": []
};

// Call recursive function
loop();

// Recursive function for to get blog post data
function loop() {
    // Get blog post data per 20 posts
    var thisOffset = 20 * i,
        option = { offset: thisOffset };
    client.blogPosts(blogName, option, function (_, data) {
        outputJSON.posts = outputJSON.posts.concat(data.posts);
    });
    i++;

    console.log(i + '投稿目');

    // Save blog post data per 1000 posts
    if(i%1000 === 0) {
        fs.writeFileSync('./data/blogPosts'+i+'.json', JSON.stringify(outputJSON, null, '    '));
        outputJSON = { "posts": [] };  // Reset variable
    }

    if (i < loopCount) {
        setTimeout(loop, 5000);  // Run per 5 seconds
    } else {
        // Save fractional blog post data
        fs.writeFileSync('./data/blogPosts'+i+'.json', JSON.stringify(outputJSON, null, '    '));
        console.log('Complete!');
    }
}

このコードを実行すると、1000投稿ごとの投稿データをローカルに保存することができます。
(ちなみに1000投稿ごとに切り分けた理由は、JSONなどのテキストファイルが256MBを超えると、メモリの関係で扱いが少し面倒になるためです *参考

なお、上記コードのblogName(ブログ名)postNum(投稿総数)は、userInfoメソッドで取得することができます。

userInfoメソッドの利用コード例
client.userInfo(function (_, data) {
    fs.writeFileSync('./userInfo.json', JSON.stringify(data, null, '    '));
});

参考サイト

2. 取得した投稿データを読み込んでEvernoteに投稿

この手順では、取得したTumblrの投稿データを読み込んで、Evernote APIを用いてEvernoteに投稿します。

Evernote APIを利用する際も、Tumblr APIと同様に、認証情報を取得する必要があります。
OAuth認証での利用も可能ですが、Developer Token一つだけで利用することも可能です。

Developer Tokenの取得は、以下のページより行なってください。

ただし、現在取得可能な認証情報はSandbox環境のみのようです。
(申請すれば、Production環境の認証情報を取得できるとの情報もあります *参考

今回の例では、Sandbox環境のEvernoteにTumblrのテキスト投稿のみを投稿します。

post2Evernote.js
var Evernote = require('evernote'),
    sleep = require('system-sleep'),
    fs = require('fs');

var DEVELOPER_TOKEN = "**********";

var option = { token: DEVELOPER_TOKEN, sandbox: true },
    client = new Evernote.Client(option),
    noteStore = client.getNoteStore();

// Read Tumblr data files in data dir
var dataDirPath = './data/';
fs.readdir(dataDirPath, function(err, fileNameList){
    if (err) throw err;
    // handle each post data
    fileNameList.forEach(fileName => {
        var jsonData = fs.readFileSync(dataDirPath + fileName, 'utf-8');
        JSON.parse(jsonData).posts.forEach(post => {
            // Post to Evernote if text post ('quote' and 'text')
            if(post.type === "quote" && post.slug) {
                createNote(post.slug, handleENML(post.text));
            }
            else if(post.type === "text" && post.slug) {
                createNote(post.slug, handleENML(post.trail[0].content_raw));
            }
        });
    });
});

// Upload post to Evernote
function createNote(postTitle, postBody) {

    // Set ENML(Evernote Markup Language)
    var nBody = '<?xml version="1.0" encoding="UTF-8"?>';
    nBody += '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">';
    nBody += "<en-note>" + postBody + "</en-note>";

    // Create note object
    var ourNote = new Evernote.Types.Note();
    ourNote.title = postTitle;
    ourNote.content = nBody;
    ourNote.notebookGuid = "*****";  // evernote notebook guid

    // Create Note by createNote method
    noteStore.createNote(ourNote).then(function(note) {
        console.log("Posted: " + note.title);
    }).catch(function (err) {
        console.log(err);
    });

    sleep(5000);  // Wait 5 seconds
}

// Remove HTML incompatible with ENML
function handleENML(text) {
    return text.replace(/<a .+?>/g, "").replace(/<\/a>/g, "").replace(/<br>/g, "<br/>").replace(/<figure .*?>(.*?)<\/figure>/g, "");
}

なお、ソースコード内のNotebookGUIDは、投稿先にしたいNotebookをブラウザで開くことで確認することができます。(下図参照)

参考サイト

画像を投稿したい場合

別途記事を書きましたので、そちらをご覧ください。
▶︎ Evernote APIで画像URLから画像投稿する(Node.js)

デモ

今回紹介した方法により、Tumblrの投稿をEvernoteで検索できるようになりました!

おぉ... この検索の早さ...。
Tumblrに負けず劣らず、Evernoteも素晴らしいサービスですね...。

終わりに

この記事では、自分のTumblrの投稿をEvernoteに移植する方法と、そのためのソースコードを紹介しました。
この方法により、Tumblrの投稿をEvernoteで検索できるようになります。

これで、どれだけリブログしても、投稿が埋もれてしまう心配がなくなることでしょう。
皆さんのリブログがもっと捗るようになることを祈ります。

Hirosaji
ゲーム実況を観ながらプログラミングをするのが好きなWebエンジニアです。
https://bl.ocks.org/hirosaji
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away