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

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

しかし、Tumblrには**自分のブログ内の投稿を検索する機能**がありません。
また、困ったことに、Tumblrの投稿は検索エンジンにも引っ掛かりづらい特徴があります。[*参考](https://www.nagahitoyuki.com/2017/09/why-is-tumblr-blog-almost-unable-to-increase-traffic-from-search-engine.html)
そのため、「あの投稿の詳細なんだっけ？」と思っても、その投稿を検索できる手段が無いのです。

<B>それならば、Tumblrの投稿をEvernoteに移植して検索できるようにしよう！</B>
<img src="https://qiita-image-store.s3.amazonaws.com/0/162655/948fde45-df5a-77b7-f8d7-4338417e2a11.png" width="450px">
ということで、この記事では<B>自分のTumblrの投稿をEvernoteに移植する方法</B>を紹介します。


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

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

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

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

この手順では、[**Tumblr API**](https://www.tumblr.com/docs/en/api/v2)を利用して、Tumblrから投稿データを取得します。

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

- [Node.jsでTumblr APIのAccess Tokenを取得する - Qiita](https://qiita.com/n0bisuke/items/c12963e0bde614443adf)

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

```js: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を超えると、メモリの関係で扱いが少し面倒になるためです [*参考](https://github.com/nodejs/node/issues/3175)）

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

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

### 参考サイト
- [tumblr.js / README.md - Github](https://github.com/tumblr/tumblr.js/blob/master/README.md)
- [Tumblr APIでwebサービスを作りたい全ての人に向けて書きました - Syncer](https://syncer.jp/tumblr-api-matome)

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

この手順では、取得したTumblrの投稿データを読み込んで、[**Evernote API**](https://dev.evernote.com/)を用いてEvernoteに投稿します。

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

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

- [Developer Tokens - Evernote Developers](https://dev.evernote.com/doc/articles/dev_tokens.php)

ただし、現在取得可能な認証情報はSandbox環境のみのようです。
（申請すれば、Production環境の認証情報を取得できるとの情報もあります [*参考](http://d.hatena.ne.jp/kkobayashi_a/20180529/p1)）

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

```js: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をブラウザで開くことで確認することができます。（下図参照）
<img src="https://qiita-image-store.s3.amazonaws.com/0/162655/37e000d0-e0cd-d86a-dd41-d4d0f8839a5f.png" width="600px">

### 参考サイト
- [Creating Notes - Evernote Developers](https://dev.evernote.com/doc/articles/creating_notes.php)
- [PythonからEvernote APIを使う方法 - MyEnigma](https://myenigma.hatenablog.com/entry/2016/01/23/090212)

### 画像を投稿したい場合
別途記事を書きましたので、そちらをご覧ください。
▶︎ [Evernote APIで画像URLから画像投稿する（Node.js）](https://qiita.com/Hirosaji/items/a58d80bfef9135a59dbd)

# デモ
今回紹介した方法により、Tumblrの投稿をEvernoteで検索できるようになりました！
<img src="https://qiita-image-store.s3.amazonaws.com/0/162655/1c41a4b1-0a30-8246-e260-8f6949abfc3c.gif" width="600px">
おぉ... この検索の早さ...。
Tumblrに負けず劣らず、Evernoteも素晴らしいサービスですね...。


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

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