post Image
golang で Evernote のノートを Jekyll 用の HTML に書き出すツールを書いた

はじめに

私、postach.io というサービスが大好きで、何ができるサービスかというと、Evernoteのノートを元にブログを作れるという素敵サービスなんです。ただ、使っているうちに、速度が遅い、カスタマイズできる項目が少ない、フォーマット機能が乏しいなど、いくつか不満が出てしまい、自分で似たようなツールを作りました。

それが chiepomme/chienote です!
(適当につけた名前だったので本当は別の名前が良いんですが Evernote での登録がこの名前だったのでそのままにしてます・・・)

せっかくなので golang で Evernote から情報を取得した時の流れをメモとして残しておきます。

golang で Evernote から情報を取得する

必要なもの

SDK

Evernote は Apache Thrift というプロトコルジェネレーターを使っているので、非公式ではありますが golang 用の SDK もあります。例えば、dreampuf/evernote-sdk-golang です。これを使うと他言語と同じように golang でも Evernote へのアクセスができます。

ドキュメント

開発者ドキュメント と他言語のサンプルコードが参考になります。

開発者 API キー

開発者ドキュメント から API キーを申請することで、すぐに開発に必要なキーを発行してもらうことができました。

API認証

通常外部に公開するサービスの場合 OAuth を使用して認証する必要があるのですが、Evernote では開発者自身がユーザーの場合に使用できるデベロッパトークンの発行もしています。これはそのまま認証トークンとして使用することができます。こちらのページから発行が可能です。即時で発行されます。

情報取得の手順

詳しいことはソース見たほうがはやいです。
https://github.com/chiepomme/chienote/blob/master/sync/sync.go

簡単な流れを紹介すると

1. クライアントの作成

これを使って Evernote の API を叩きます。

cli := client.NewClient(clientKey, clientSecret, client.SANDBOX)

2. UserStore を取得する。

UserStore にはユーザーの情報や NoteStore の場所が入っています。

us, err := cli.GetUserStore()
if err != nil {
    return
}

versionOk, err := us.CheckVersion("your_client_name", userstore.EDAM_VERSION_MAJOR, userstore.EDAM_VERSION_MINOR)
if !versionOk {
    return
}
if err != nil {
    return
}

3. UserStore から NoteStore を取得する。

NoteStore にはノートブックやノート、そこで使用されているリソースの情報が入っています。

url, err := us.GetNoteStoreUrl(developerToken)
if err != nil {
    return
}
if url == "" {
    return
}

ns, err := cli.GetNoteStoreWithURL(url)
if err != nil {
    return
}

4. UserStore から SyncState を取得して前回から更新がないかをチェックする。

頻繁にポーリングを行うと怒られちゃうので、前回から更新がないか確認する必要があります。詳しくは、ドキュメントの変更の監視をみてください。

syncState, err := ns.GetSyncState(developerToken)
if err != nil {
    return
}

prevState := // 何らかの方法で前回の情報を取得
if prevState.UpdateCount == syncState.UpdateCount {
    return
}

if syncState.CurrentTime-prevState.CurrentTime < 15 * 60 * 1000 { // ポーリングは 15 分以上あけてというお願い
    return
}

// SyncState を次回の同期に備えて保存しておく

5. NoteStore から ほしいノートブックの GUID を取得する。

ノートブックのリストをもらえるのでそこから、ほしいノートを探して GUID を取得します。
なおデフォルトのノートブックは ns.getDefaultNotebook() で取得できます。

notebooks, err := ns.ListNotebooks(developerToken)
if err != nil {
    return
}

var notebookGUID *types.GUID
for _, book := range notebooks {
    if *book.Name == "ほしいノートブックの名前" {
        notebookGUID = book.GUID
        break
    }
}

if notebookGUID == nil || *notebookGUID == "" {
    return
}

6. ノートブックの GUID を使って、ノートメタデータの検索クエリを投げる。

ascending := false

// 当該 GUID のノートブックのノート検索クエリを作成。GUID を設定しないと全てのノートが返ってきます
filter := &notestore.NoteFilter{NotebookGuid: *notebookGUID, Ascending: &ascending}

var resultSpec notestore.NotesMetadataResultSpec
includeUpdateSequenceNum := true // 後にこのアップデート回数を比較して更新されたかどうかをチェックする
resultSpec.IncludeUpdateSequenceNum = &includeUpdateSequenceNum
metadatas, err = ns.FindNotesMetadata(developerToken, filter, 0, 1000, &resultSpec)
if err != nil {
    return
}

7. ノートのメタデータからノートの GUID を取得して NoteStore からノートを取得。

あとは GUID を使ってノートを取得するだけです。なおノートの本文は ENML フォーマット*note.Content に入っています。

for _, note := range metadatas.GetNotes() {
    cachedNote := // 同じ GUID のノートのキャッシュを読み込んでおく

    // ノートの更新をチェック。新しく作られた物には UpdateSequenceNum が存在しないので注意
    if cachedNote == nil || cachedNote.UpdateSequenceNum == nil || note.UpdateSequenceNum == nil || *cachedNote.UpdateSequenceNum != *note.UpdateSequenceNum {

        // 実際にノートのデータを取得。引数によってはリソースも一緒に取得できる。
        note, err := ns.GetNote(developerToken, note.GUID, true, false, false, false)
        if err != nil {
            return
        }
        // 次回の同期に備えてノートをキャッシュする
    }
}

プロダクション環境へ

サンドボックス環境で動作が確認できたら、プロダクション環境へ移行します。その際にはプロダクション環境用の API キーとデベロッパトークンを発行する必要があります。

API キーは、よくある質問のサンドボックス環境で使っている API キーをプロダクション環境に移行するには、何が必要ですか?からリクエストを投げることができます。ただし何故か日本語環境からは投げられなかったので、ページ右下にある言語設定を英語にしてから、リクエストを投げてください。だいたい3日位でメールが来ます。

デベロッパトークンはサンドボックス環境と同じでこちらのページから発行できます。こちらは即時です。

おわりに

今回 golang を使って初めてアプリケーションを書いたのですが、golang のエコシステムや、 VSCode の golang プラグイン、Thrift で書かれた Evernote SDK のおかげもあって、スムーズに書くことができました。 Evernote で情報管理されている方は、せっかく多言語に対応した SDK があるので何かツールを作ってみてはいかがでしょうか!


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。