はじめに

英単語を覚えるのにAnkiを使っている。単語の暗記には便利な一方で、単語を追加するのが結構面倒くさい。Obsidianからプラグイン経由で追加するようにしてみる。

Anki Connectを導入

Anki Connectはデスクトップ版のAnkiアプリにAPI経由でアクセスできるようになる神アドオン。Export to Ankiなどの既存のプラグインもこれを利用している。これをAnkiアプリの設定画面にインストールする。

このとき、上記の様にapp://obsidian.mdを追加しておかないとObsidianからのアクセスが拒否されるので追記する。

実装する

Document通りに実装する。invokeというfunctionを定義さえしておけば、あとはDocumentに記載のアクションが使いたい放題となる。

function invoke(action, version, params={}) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.addEventListener('error', () => reject('failed to issue request'));
        xhr.addEventListener('load', () => {
            try {
                const response = JSON.parse(xhr.responseText);
                if (Object.getOwnPropertyNames(response).length != 2) {
                    throw 'response has an unexpected number of fields';
                }
                if (!response.hasOwnProperty('error')) {
                    throw 'response is missing required error field';
                }
                if (!response.hasOwnProperty('result')) {
                    throw 'response is missing required result field';
                }
                if (response.error) {
                    throw response.error;
                }
                resolve(response.result);
            } catch (e) {
                reject(e);
            }
        });
 
        xhr.open('POST', 'http://127.0.0.1:8765');
        xhr.send(JSON.stringify({action, version, params}));
    });
}

invokeにアクション名とバージョン(現在は基本的に6)、あとは必要なパラメータを渡せば機能する仕組みだ。

例えばノートを追加する場合は

function addNote(front: string, back: string) {
        return this.invoke("addNote", 6, {
            "note": {
                "deckName": "Default",
                "modelName": "基本",
                "fields": {
                    "表面": front,
                    "裏面": back
                },
                "options": {
                    "allowDuplicate": false
                }
            }
        });
    }

みたいな感じ。デッキ名やモデル名、fields名とかは正確に入力しないといけない。Documentは英語で書いてあるが、アプリを日本語化している場合は日本語に直さないといけない(1敗)。alloDuplicateは重複を許すかどうかで、基本falseでよさそう。

あとは無限にありそうなアクションをどう使うか。今回はシンプルにカードを追加したいだけなので、これだけを使うことにする。

使用例

詳細な実装は省略。すでに作ってあるプロンプトボックスやGeminiとの統合をしてみた。

コマンドを2種類作った。Geminiの方はたとえば、

英単語を表面に打ち込む。

次に裏面が表示されて、自動でGeminiが生成した日本語訳が表示される。ここでEnterを押すとAnkiに登録される。Geminiじゃない方はGeminiの自動翻訳が出ないだけでほぼ同じ動きをする。

おわりに

Anki Connect、Documentが充実していてかつかなり簡便に使えるように工夫されている。Geminiを噛ませることで色々な使い方が考えられそう。このくらいの単純作業はgemini-2.0-flashで十分なので1日1500回は無料。素晴らしい。