2025-06-06 16:07:58 +08:00
2025-06-06 15:10:15 +08:00
2025-06-06 15:10:15 +08:00
2025-06-06 15:10:15 +08:00
2025-06-06 15:10:15 +08:00
2025-06-06 15:10:15 +08:00
2025-06-06 15:10:15 +08:00
2025-06-06 16:07:58 +08:00
2025-06-06 16:07:58 +08:00

Anki-Connect

Anki-Connect 使外部应用程序(如 Yomichan能够通过简单的 HTTP API 与Anki进行通信。它的功能包括对用户卡片组执行查询、自动创建新卡片等。Anki-Connect 与最新的稳定版(2.1.x)Anki 兼容;旧版本(2.0.x 及以下)不再受支持。

安装

安装过程与其他 Anki 插件类似,可以通过以下三个步骤完成:

  1. 在 Anki 中选择工具 | 插件 | 获取插件...,打开安装插件对话框。
  2. 在标有代码的文本框中输入2055492159,然后按确定按钮继续。
  3. 当提示重启 Anki 时,请按照要求进行操作,以完成 Anki-Connect 的安装。

Anki 必须在后台保持运行,以便其他应用程序能够使用 Anki-Connect。您可以随时通过在浏览器中访问localhost:8765来验证 Anki-Connect 是否在运行。如果服务器正在运行,您将在浏览器窗口中看到Anki-Connect的消息。

Windows 用户注意事项

Windows 用户可能会在 Anki 启动时看到防火墙提示对话框。这是因为 Anki-Connect 运行了本地 HTTP 服务器,以便其他应用程序能够连接到它。主应用程序 Anki 必须被允许通过防火墙,此插件才能正常运行。

MacOS 用户注意事项

Mac OS X Mavericks开始,操作系统引入了名为App Nap的功能。此功能会使某些已打开但不可见的应用程序进入挂起状态。由于此行为会导致 Anki-Connect 在前台显示其他窗口时停止工作,因此应为 Anki 禁用 App Nap

  1. 启动终端应用程序。
  2. 在终端窗口中执行以下命令:
    defaults write net.ankiweb.dtop NSAppSleepDisabled -bool true
    defaults write net.ichi2.anki NSAppSleepDisabled -bool true
    defaults write org.qt-project.Qt.QtWebEngineCore NSAppSleepDisabled -bool true
    
  3. 重启 Anki。

开发者应用程序接口

Anki-Connect 通过易于使用的 API 向外部应用程序公开 Anki 的内部功能。安装后,只要启动 Anki该插件就会在 8765 端口启动 HTTP 服务器。其他应用程序(包括浏览器扩展)可以通过 HTTP 请求与其通信。

默认情况下Anki-Connect 只会将 HTTP 服务器绑定到127.0.0.1IP 地址,因此您只能从运行它的同一主机访问它。如果您需要通过网络访问,可以在配置中更改绑定地址。进入工具->插件->AnkiConnect->配置,更改"webBindAddress"值。例如,您可以将其设置为0.0.0.0,以将其绑定到主机上的所有网络接口。这也需要重启 Anki。

调用示例

每个请求都由一个包含actionversion、上下文params和用于认证的key值(可选,默认可以省略)的 JSON 编码对象组成。Anki-Connect 将返回一个包含两个字段的对象:resulterrorresult字段包含执行的 API 的返回值,而error字段是在 API 执行期间抛出的任何异常的描述(如果执行成功,则使用值null)。

成功响应示例

{ "result": ["Default", "Filtered Deck 1"], "error": null }

失败响应示例

{ "result": null, "error": "unsupported action" }
{ "result": null, "error": "guiBrowse() got an unexpected keyword argument 'foobar'" }

为了与旧版本 Anki-Connect 设计的客户端兼容,如果请求中未提供version字段,版本将默认为 4。此外当提供的版本为 4 级或以下时API 响应将只包含result的值;没有error字段可用于错误处理。

您可以使用任何语言或工具向 Anki-Connect 发出请求,但下面包含了几个简单的示例作为参考。

Curl

curl localhost:8765 -X POST -d '{"action": "deckNames", "version": 6}'

Powershell

(Invoke-RestMethod -Uri http://localhost:8765 -Method Post -Body '{"action": "deckNames", "version": 6}').result

Python

import json
import urllib.request

def request(action, **params):
    return {'action': action, 'params': params, 'version': 6}

def invoke(action, **params):
    requestJson = json.dumps(request(action, **params)).encode('utf-8')
    response = json.load(urllib.request.urlopen(urllib.request.Request('http://127.0.0.1:8765', requestJson)))
    if len(response) != 2:
        raise Exception('response has an unexpected number of fields')
    if 'error' not in response:
        raise Exception('response is missing required error field')
    if 'result' not in response:
        raise Exception('response is missing required result field')
    if response['error'] is not None:
        raise Exception(response['error'])
    return response['result']

invoke('createDeck', deck='test1')
result = invoke('deckNames')
print('got list of decks: {}'.format(result))

JavaScript

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 }));
  });
}

await invoke('createDeck', 6, { deck: 'test1' });
const result = await invoke('deckNames', 6);
console.log(`got list of decks: ${result}`);

认证

Anki-Connect 支持要求认证以便进行 API 请求。 默认情况下,此支持是禁用的,但可以通过在 Anki-Config 的设置(工具->插件->AnkiConnect->配置)中设置apiKey字段为所需的字符串来启用。 如果您已经这样做,您应该会看到requestPermission API 请求返回true作为requireApiKey。 然后您必须在任何进一步的 API 请求体中包含一个名为key的附加参数,其值必须与配置的 API 密钥匹配。

嘿,你能添加一个新的 action 来支持$FEATURE 吗?

Anki-Connect 的主要目标是支持来自 Yomichan 浏览器扩展的实时闪卡创建。当前的 API 提供了所有必要的动作来实现这一点。我认识到 Anki-Connect 的角色已经从这一最初愿景演变,而且我很乐意审查新的功能请求。

话虽如此,本项目采用自助服务模式。如果你想要一个新功能,请创建一个 PR。我会审查它如果看起来不错就会合并。没有附带拉取请求的添加新功能的请求将不会得到处理。确保你的拉取请求满足以下标准:

  • 尝试匹配周围代码的风格。
  • 有附带的文档和示例。
  • 有验证操作的附带测试。
  • 实现在其他应用中有用的功能。

支持的动作

当前支持的动作的文档按类别分类并在下面引用。请注意,已弃用的 API 将继续运行,尽管未在此页面上列出,只要您的请求标有对应 API 可用时的版本号。搜索参数传递给 Anki更多信息请查看文档https://docs.ankiweb.net/searching.html


卡片操作

getEaseFactors

  • 返回一个数组,包含给定卡片的简易度因子(按相同顺序)。

    示例请求:
    {
      "action": "getEaseFactors",
      "version": 6,
      "params": {
        "cards": [1483959291685, 1483959293217]
      }
    }
    
    示例结果:
    {
      "result": [4100, 3900],
      "error": null
    }
    

setEaseFactors

  • 通过卡片 ID 设置卡片的简易度因子;如果成功(所有卡片都存在)则返回true,否则返回false

    示例请求:
    {
      "action": "setEaseFactors",
      "version": 6,
      "params": {
        "cards": [1483959291685, 1483959293217],
        "easeFactors": [4100, 3900]
      }
    }
    
    示例结果:
    {
      "result": [true, true],
      "error": null
    }
    

setSpecificValueOfCard

  • 设置单个卡片的特定值。由于更改卡片的某些值可能会在数据库中造成混乱,一些键需要将参数"warning_check"设置为 True。 这可用于设置卡片的标志、更改其简易度因子、更改筛选卡组中的复习顺序以及更改列"data"(目前显然未被 anki 使用),以及许多其他值。 可以在AnkiDroid 的 wiki上找到值的列表及其各自的用途解释。

    示例请求:
    {
      "action": "setSpecificValueOfCard",
      "version": 6,
      "params": {
        "card": 1483959291685,
        "keys": ["flags", "odue"],
        "newValues": ["1", "-100"]
      }
    }
    
    示例结果:
    {
      "result": [true, true],
      "error": null
    }
    

suspend

  • 通过卡片 ID 暂停卡片;如果成功(至少有一张卡片之前没有被暂停)则返回true,否则返回false

    示例请求:
    {
      "action": "suspend",
      "version": 6,
      "params": {
        "cards": [1483959291685, 1483959293217]
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

unsuspend

  • 通过卡片 ID 取消暂停卡片;如果成功(至少有一张卡片之前被暂停)则返回true,否则返回false

    示例请求:
    {
      "action": "unsuspend",
      "version": 6,
      "params": {
        "cards": [1483959291685, 1483959293217]
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

suspended

  • 通过 ID 检查卡片是否被暂停。如果被暂停则返回true,否则返回false

    示例请求:
    {
      "action": "suspended",
      "version": 6,
      "params": {
        "card": 1483959293217
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

areSuspended

  • 返回一个数组,表示每张给定卡片是否被暂停(按相同顺序)。如果卡片不存在,则返回null

    示例请求:
    {
      "action": "areSuspended",
      "version": 6,
      "params": {
        "cards": [1483959291685, 1483959293217, 1234567891234]
      }
    }
    
    示例结果:
    {
      "result": [false, true, null],
      "error": null
    }
    

areDue

  • 返回一个数组,表示每张给定卡片是否到期(按相同顺序)。注意:学习队列中有大间隔(超过 20 分钟)的卡片被视为未到期,直到其间隔时间过去为止,这与 Anki 在复习时对待它们的方式相匹配。

    示例请求:
    {
      "action": "areDue",
      "version": 6,
      "params": {
        "cards": [1483959291685, 1483959293217]
      }
    }
    
    示例结果:
    {
      "result": [false, true],
      "error": null
    }
    

getIntervals

  • 返回一个数组,包含每个给定卡片 ID 的最近间隔,或者当completetrue时,返回每个给定卡片 ID 的所有间隔的二维数组。负间隔以秒为单位,正间隔以天为单位。

    示例请求1
    {
      "action": "getIntervals",
      "version": 6,
      "params": {
        "cards": [1502298033753, 1502298036657]
      }
    }
    
    示例结果1
    {
      "result": [-14400, 3],
      "error": null
    }
    
    示例请求2
    {
      "action": "getIntervals",
      "version": 6,
      "params": {
        "cards": [1502298033753, 1502298036657],
        "complete": true
      }
    }
    
    示例结果2
    {
      "result": [
        [-120, -180, -240, -300, -360, -14400],
        [-120, -180, -240, -300, -360, -14400, 1, 3]
      ],
      "error": null
    }
    

findCards

  • 返回给定查询的卡片 ID 数组。功能上与guiBrowse相同,但不使用 GUI 以获得更好的性能。

    示例请求:
    {
      "action": "findCards",
      "version": 6,
      "params": {
        "query": "deck:current"
      }
    }
    
    示例结果:
    {
      "result": [1494723142483, 1494703460437, 1494703479525],
      "error": null
    }
    

cardsToNotes

  • 返回给定卡片 ID 的笔记 ID 的无序数组。对于具有相同笔记的卡片ID 在数组中只给出一次。

    示例请求:
    {
      "action": "cardsToNotes",
      "version": 6,
      "params": {
        "cards": [1502098034045, 1502098034048, 1502298033753]
      }
    }
    
    示例结果:
    {
      "result": [1502098029797, 1502298025183],
      "error": null
    }
    

cardsModTime

  • 返回一个对象列表,包含每个卡片 ID 的修改时间。 此功能比执行cardsInfo快约 15 倍。

    示例请求:
    {
      "action": "cardsModTime",
      "version": 6,
      "params": {
        "cards": [1498938915662, 1502098034048]
      }
    }
    
    示例结果:
    {
      "result": [
        {
          "cardId": 1498938915662,
          "mod": 1629454092
        }
      ],
      "error": null
    }
    

cardsInfo

  • 返回一个对象列表,包含每个卡片 ID 的卡片字段、正反面(包括 CSS、笔记类型、卡片所属的笔记、卡组名称、最后修改时间戳以及简易度和间隔。

    示例请求:
    {
      "action": "cardsInfo",
      "version": 6,
      "params": {
        "cards": [1498938915662, 1502098034048]
      }
    }
    
    示例结果:
    {
      "result": [
        {
          "answer": "back content",
          "question": "front content",
          "deckName": "Default",
          "modelName": "Basic",
          "fieldOrder": 1,
          "fields": {
            "Front": { "value": "front content", "order": 0 },
            "Back": { "value": "back content", "order": 1 }
          },
          "css": "p {font-family:Arial;}",
          "cardId": 1498938915662,
          "interval": 16,
          "note": 1502298033753,
          "ord": 1,
          "type": 0,
          "queue": 0,
          "due": 1,
          "reps": 1,
          "lapses": 0,
          "left": 6,
          "mod": 1629454092
        },
        {
          "answer": "back content",
          "question": "front content",
          "deckName": "Default",
          "modelName": "Basic",
          "fieldOrder": 0,
          "fields": {
            "Front": { "value": "front content", "order": 0 },
            "Back": { "value": "back content", "order": 1 }
          },
          "css": "p {font-family:Arial;}",
          "cardId": 1502098034048,
          "interval": 23,
          "note": 1502298033753,
          "ord": 1,
          "type": 0,
          "queue": 0,
          "due": 1,
          "reps": 1,
          "lapses": 0,
          "left": 6
        }
      ],
      "error": null
    }
    

forgetCards

  • 忘记卡片,使卡片再次成为新卡片。

    示例请求:
    {
      "action": "forgetCards",
      "version": 6,
      "params": {
        "cards": [1498938915662, 1502098034048]
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

relearnCards

  • 使卡片成为"重新学习"状态。

    示例请求:
    {
      "action": "relearnCards",
      "version": 6,
      "params": {
        "cards": [1498938915662, 1502098034048]
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

answerCards

  • 回答卡片。简易度在 1重来到 4简单之间。将在回答前立即开始计时器。如果卡片存在则返回true,否则返回false

    示例请求:
    {
      "action": "answerCards",
      "version": 6,
      "params": {
        "answers": [
          {
            "cardId": 1498938915662,
            "ease": 2
          },
          {
            "cardId": 1502098034048,
            "ease": 4
          }
        ]
      }
    }
    
    示例结果:
    {
      "result": [true, true],
      "error": null
    }
    

setDueDate

  • 设置到期日期。如果是新卡片,则将其转为复习卡片,并使其在特定日期到期。

    • 0 = 今天
    • 1! = 明天 + 将间隔更改为 1
    • 3-7 = 随机选择 3-7 天
    示例请求:
    {
      "action": "setDueDate",
      "version": 6,
      "params": {
        "cards": [1498938915662, 1502098034048],
        "days": "3-7"
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

卡组操作

deckNames

  • 获取当前用户的完整卡组名称列表。

    示例请求:
    {
      "action": "deckNames",
      "version": 6
    }
    
    示例结果:
    {
      "result": ["Default"],
      "error": null
    }
    

deckNamesAndIds

  • 获取当前用户的完整卡组名称及其对应 ID 的列表。

    示例请求:
    {
      "action": "deckNamesAndIds",
      "version": 6
    }
    
    示例结果:
    {
      "result": { "Default": 1 },
      "error": null
    }
    

getDecks

  • 接受一个卡片 ID 数组,并返回一个对象,其中每个卡组名称作为键,其值是属于该卡组的给定卡片数组。

    示例请求:
    {
      "action": "getDecks",
      "version": 6,
      "params": {
        "cards": [1502298036657, 1502298033753, 1502032366472]
      }
    }
    
    示例结果:
    {
      "result": {
        "Default": [1502032366472],
        "Japanese::JLPT N3": [1502298036657, 1502298033753]
      },
      "error": null
    }
    

createDeck

  • 创建一个新的空卡组。不会覆盖同名的已存在卡组。

    示例请求:
    {
      "action": "createDeck",
      "version": 6,
      "params": {
        "deck": "Japanese::Tokyo"
      }
    }
    
    示例结果:
    {
      "result": 1519323742721,
      "error": null
    }
    

changeDeck

  • 将具有给定 ID 的卡片移动到不同的卡组,如果卡组尚不存在则创建它。

    示例请求:
    {
      "action": "changeDeck",
      "version": 6,
      "params": {
        "cards": [1502098034045, 1502098034048, 1502298033753],
        "deck": "Japanese::JLPT N3"
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

deleteDecks

  • 删除具有给定名称的卡组。 参数cardsToo 必须被指定并设置为true

    示例请求:
    {
      "action": "deleteDecks",
      "version": 6,
      "params": {
        "decks": ["Japanese::JLPT N5", "Easy Spanish"],
        "cardsToo": true
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

getDeckConfig

  • 获取给定卡组的配置组对象。

    示例请求:
    {
      "action": "getDeckConfig",
      "version": 6,
      "params": {
        "deck": "Default"
      }
    }
    
    示例结果:
    {
      "result": {
        "lapse": {
          "leechFails": 8,
          "delays": [10],
          "minInt": 1,
          "leechAction": 0,
          "mult": 0
        },
        "dyn": false,
        "autoplay": true,
        "mod": 1502970872,
        "id": 1,
        "maxTaken": 60,
        "new": {
          "bury": true,
          "order": 1,
          "initialFactor": 2500,
          "perDay": 20,
          "delays": [1, 10],
          "separate": true,
          "ints": [1, 4, 7]
        },
        "name": "Default",
        "rev": {
          "bury": true,
          "ivlFct": 1,
          "ease4": 1.3,
          "maxIvl": 36500,
          "perDay": 100,
          "minSpace": 1,
          "fuzz": 0.05
        },
        "timer": 0,
        "replayq": true,
        "usn": -1
      },
      "error": null
    }
    

saveDeckConfig

  • 保存给定的配置组,成功时返回true,如果配置组的 ID 无效(例如不存在)则返回false

    示例请求:
    {
      "action": "saveDeckConfig",
      "version": 6,
      "params": {
        "config": {
          "lapse": {
            "leechFails": 8,
            "delays": [10],
            "minInt": 1,
            "leechAction": 0,
            "mult": 0
          },
          "dyn": false,
          "autoplay": true,
          "mod": 1502970872,
          "id": 1,
          "maxTaken": 60,
          "new": {
            "bury": true,
            "order": 1,
            "initialFactor": 2500,
            "perDay": 20,
            "delays": [1, 10],
            "separate": true,
            "ints": [1, 4, 7]
          },
          "name": "Default",
          "rev": {
            "bury": true,
            "ivlFct": 1,
            "ease4": 1.3,
            "maxIvl": 36500,
            "perDay": 100,
            "minSpace": 1,
            "fuzz": 0.05
          },
          "timer": 0,
          "replayq": true,
          "usn": -1
        }
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

setDeckConfigId

  • 将给定卡组的配置组更改为具有给定 ID 的配置组。成功时返回true,如果给定的配置组或任何给定的卡组不存在则返回false

    示例请求:
    {
      "action": "setDeckConfigId",
      "version": 6,
      "params": {
        "decks": ["Default"],
        "configId": 1
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

cloneDeckConfigId

  • 使用给定的名称创建一个新的配置组,从具有给定 ID 的组克隆,或者如果未指定,则从默认组克隆。返回新配置组的 ID或者如果指定的要克隆的组不存在则返回false

    示例请求:
    {
      "action": "cloneDeckConfigId",
      "version": 6,
      "params": {
        "name": "Copy of Default",
        "cloneFrom": 1
      }
    }
    
    示例结果:
    {
      "result": 1502972374573,
      "error": null
    }
    

removeDeckConfigId

  • 移除具有给定 ID 的配置组,如果成功则返回true如果尝试移除默认配置组ID = 1或不存在的配置组则返回false

    示例请求:
    {
      "action": "removeDeckConfigId",
      "version": 6,
      "params": {
        "configId": 1502972374573
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

getDeckStats

  • 获取给定卡组的统计信息,如总卡片数和到期卡片数。

    示例请求:
    {
      "action": "getDeckStats",
      "version": 6,
      "params": {
        "decks": ["Japanese::JLPT N5", "Easy Spanish"]
      }
    }
    
    示例结果:
    {
      "result": {
        "1651445861967": {
          "deck_id": 1651445861967,
          "name": "Japanese::JLPT N5",
          "new_count": 20,
          "learn_count": 0,
          "review_count": 0,
          "total_in_deck": 1506
        },
        "1651445861960": {
          "deck_id": 1651445861960,
          "name": "Easy Spanish",
          "new_count": 26,
          "learn_count": 10,
          "review_count": 5,
          "total_in_deck": 852
        }
      },
      "error": null
    }
    

图形界面操作

guiBrowse

  • 调用卡片浏览器对话框并搜索给定查询。返回找到的卡片标识符数组。查询语法在此处有文档

    可选地,可以提供reorderCards属性来重新排序卡片浏览器中显示的卡片。 这是一个包含ordercolumnId对象的数组。order可以是ascendingdescending,而columnId可以是几个列标识符之一(如在Anki 源代码中记录的)。 指定的列需要在卡片浏览器中可见。

    示例请求:
    {
      "action": "guiBrowse",
      "version": 6,
      "params": {
        "query": "deck:current",
        "reorderCards": {
          "order": "descending",
          "columnId": "noteCrt"
        }
      }
    }
    
    示例结果:
    {
      "result": [1494723142483, 1494703460437, 1494703479525],
      "error": null
    }
    

guiSelectCard

  • 找到卡片浏览器对话框的打开实例,并根据卡片标识符选择一张卡片。 如果卡片浏览器是打开的,返回true,否则返回false

    示例请求:
    {
      "action": "guiSelectCard",
      "version": 6,
      "params": {
        "card": 1494723142483
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiSelectedNotes

  • 找到卡片浏览器对话框的打开实例,并返回选中笔记的标识符数组。如果浏览器未打开,则返回空列表。

    示例请求:
    {
      "action": "guiSelectedNotes",
      "version": 6
    }
    
    示例结果:
    {
      "result": [1494723142483, 1494703460437, 1494703479525],
      "error": null
    }
    

guiAddCards

  • 调用添加卡片对话框,使用给定的卡组和模型预设笔记,带有提供的字段值和标签。 多次调用会关闭旧窗口并重新打开窗口,使用新提供的值。

    可以通过audiovideopicture键将音频、视频和图片文件嵌入到字段中。 请参考addNotestoreMediaFile的文档,了解这些字段的说明。

    结果是如果用户选择确认添加卡片对话框,将添加的笔记的 ID。

    示例请求:
    {
      "action": "guiAddCards",
      "version": 6,
      "params": {
        "note": {
          "deckName": "Default",
          "modelName": "Cloze",
          "fields": {
            "Text": "The capital of Romania is {{c1::Bucharest}}",
            "Extra": "Romania is a country in Europe"
          },
          "tags": ["countries"],
          "picture": [
            {
              "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/13/EU-Romania.svg/285px-EU-Romania.svg.png",
              "filename": "romania.png",
              "fields": ["Extra"]
            }
          ]
        }
      }
    }
    
    示例结果:
    {
      "result": 1496198395707,
      "error": null
    }
    

guiEditNote

  • 打开编辑对话框,显示对应于给定笔记 ID 的笔记。 该对话框类似于编辑当前对话框,但:

    • 有一个预览按钮,用于预览笔记的卡片
    • 有一个浏览按钮,用于打开浏览器并显示这些卡片
    • 有上一个/后退按钮,用于导航对话框的历史
    • 没有带有关闭按钮的栏
    示例请求:
    {
      "action": "guiEditNote",
      "version": 6,
      "params": {
        "note": 1649198355435
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

guiCurrentCard

  • 返回有关当前卡片的信息,如果不在复习模式,则返回null

    示例请求:
    {
      "action": "guiCurrentCard",
      "version": 6
    }
    
    示例结果:
    {
      "result": {
        "answer": "back content",
        "question": "front content",
        "deckName": "Default",
        "modelName": "Basic",
        "fieldOrder": 0,
        "fields": {
          "Front": { "value": "front content", "order": 0 },
          "Back": { "value": "back content", "order": 1 }
        },
        "template": "Forward",
        "cardId": 1498938915662,
        "buttons": [1, 2, 3],
        "nextReviews": ["<1m", "<10m", "4d"]
      },
      "error": null
    }
    

guiStartCardTimer

  • 启动或重置当前卡片的timerStarted值。这对于将开始时间推迟到通过 API 显示卡片时很有用,从而在调用guiAnswerCard时使记录的回答卡片所花费的时间更准确。

    示例请求:
    {
      "action": "guiStartCardTimer",
      "version": 6
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiShowQuestion

  • 显示当前卡片的问题文本;如果处于复习模式则返回true,否则返回false

    示例请求:
    {
      "action": "guiShowQuestion",
      "version": 6
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiShowAnswer

  • 显示当前卡片的答案文本;如果处于复习模式则返回true,否则返回false

    示例请求:
    {
      "action": "guiShowAnswer",
      "version": 6
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiAnswerCard

  • 回答当前卡片;如果成功则返回true,否则返回false。注意,在 Anki 接受任何答案之前,必须先显示当前卡片的答案。

    示例请求:
    {
      "action": "guiAnswerCard",
      "version": 6,
      "params": {
        "ease": 1
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiUndo

  • 撤销最后一个动作/卡片;如果成功则返回true,否则返回false

    示例请求:
    {
      "action": "guiUndo",
      "version": 6
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiDeckOverview

  • 为具有给定名称的卡组打开卡组概览对话框;如果成功则返回true,否则返回false

    示例请求:
    {
      "action": "guiDeckOverview",
      "version": 6,
      "params": {
        "name": "Default"
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiDeckBrowser

  • 打开卡组浏览器对话框。

    示例请求:
    {
      "action": "guiDeckBrowser",
      "version": 6
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

guiDeckReview

  • 开始复习具有给定名称的卡组;如果成功则返回true,否则返回false

    示例请求:
    {
      "action": "guiDeckReview",
      "version": 6,
      "params": {
        "name": "Default"
      }
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

guiImportFile

  • 调用*导入...(Ctrl+Shift+I)*对话框,并可选择提供文件路径。弹出对话框供用户审核导入。支持 Anki 支持的所有文件类型。如果未提供路径,则显示打开文件对话框。在 Windows 上的路径中必须使用正斜杠。仅支持 Anki 2.1.52+。

    示例请求:
    {
      "action": "guiImportFile",
      "version": 6,
      "params": {
        "path": "C:/Users/Desktop/cards.txt"
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

guiExitAnki

  • 安排一个请求来优雅地关闭 Anki。此操作是异步的因此它会立即返回而不会等待 Anki 进程实际终止。

    示例请求:
    {
      "action": "guiExitAnki",
      "version": 6
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

guiCheckDatabase

  • 请求进行数据库检查,但立即返回而不等待检查完成。因此,即使在数据库检查过程中检测到错误,此操作也将始终返回true

    示例请求:
    {
      "action": "guiCheckDatabase",
      "version": 6
    }
    
    示例结果:
    {
      "result": true,
      "error": null
    }
    

媒体操作

storeMediaFile

  • 将具有指定 base64 编码内容的文件存储在媒体文件夹中。或者,您可以指定绝对文件路径,或者从中下载文件的 URL。如果提供了datapathurl中的多个,将首先使用data字段,然后是path,最后是url。为了防止 Anki 删除不被任何卡片使用的文件(例如配置文件),请在文件名前加下划线。这些文件仍然会同步到 AnkiWeb。 默认情况下,将删除任何同名的现有文件。设置deleteExisting为 false 可以通过让 Anki 为新文件提供非冲突的名称来防止这种情况。

    示例请求(相对路径):
    {
      "action": "storeMediaFile",
      "version": 6,
      "params": {
        "filename": "_hello.txt",
        "data": "SGVsbG8sIHdvcmxkIQ=="
      }
    }
    

    _hello.txt的内容:

    Hello world!
    
    示例结果(相对路径):
    {
      "result": "_hello.txt",
      "error": null
    }
    
    示例请求(绝对路径):
    {
      "action": "storeMediaFile",
      "version": 6,
      "params": {
        "filename": "_hello.txt",
        "path": "/path/to/file"
      }
    }
    
    示例结果(绝对路径):
    {
      "result": "_hello.txt",
      "error": null
    }
    
    示例请求url
    {
      "action": "storeMediaFile",
      "version": 6,
      "params": {
        "filename": "_hello.txt",
        "url": "https://url.to.file"
      }
    }
    
    示例结果url
    {
      "result": "_hello.txt",
      "error": null
    }
    

retrieveMediaFile

  • 检索指定文件的 base64 编码内容,如果文件不存在则返回false

    示例请求:
    {
      "action": "retrieveMediaFile",
      "version": 6,
      "params": {
        "filename": "_hello.txt"
      }
    }
    
    示例结果:
    {
      "result": "SGVsbG8sIHdvcmxkIQ==",
      "error": null
    }
    

getMediaFilesNames

  • 获取与模式匹配的媒体文件名。默认返回所有名称。

    示例请求:
    {
      "action": "getMediaFilesNames",
      "version": 6,
      "params": {
        "pattern": "_hell*.txt"
      }
    }
    
    示例结果:
    {
      "result": ["_hello.txt"],
      "error": null
    }
    

getMediaDirPath

  • 获取当前打开的配置文件的collection.media文件夹的完整路径。

    示例请求:
    {
      "action": "getMediaDirPath",
      "version": 6
    }
    
    示例结果:
    {
      "result": "/home/user/.local/share/Anki2/Main/collection.media",
      "error": null
    }
    

deleteMediaFile

  • 删除媒体文件夹中的指定文件。

    示例请求:
    {
      "action": "deleteMediaFile",
      "version": 6,
      "params": {
        "filename": "_hello.txt"
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

杂项操作

requestPermission

  • 请求使用此插件公开的 API 的权限。此方法不需要 API 密钥,是唯一接受来自任何来源的请求的方法;其他方法只接受来自受信任来源的请求,这些来源列在插件配置的webCorsOriginList下。默认情况下,localhost是受信任的。

    从不受信任的来源调用此方法将在 Anki 中显示一个弹出窗口,询问用户是否允许您的来源使用 API来自受信任来源的调用将返回结果而不显示弹出窗口。 在拒绝许可时,用户还可以选择忽略来自该来源的进一步许可请求。这些来源最终会出现在ignoreOriginList中,可通过插件配置进行编辑。

    结果始终包含permission字段,该字段反过来包含字符串granteddenied,对应于您的来源是否受信任。如果您的来源受信任,还将返回字段requireApiKey(如果需要则为true)和version

    这应该是您进行的第一个调用,以确保您的应用程序和 Anki-Connect 能够相互正确通信。新版本的 Anki-Connect 向后兼容;只要您使用在报告的 Anki-Connect 版本或更早版本中可用的操作,一切都应该正常工作。

    示例请求:
    {
      "action": "requestPermission",
      "version": 6
    }
    
    示例结果:
    {
      "result": {
        "permission": "granted",
        "requireApiKey": false,
        "version": 6
      },
      "error": null
    }
    
    {
      "result": {
        "permission": "denied"
      },
      "error": null
    }
    

version

  • 获取此插件公开的 API 的版本。目前定义了版本16

    示例请求:
    {
      "action": "version",
      "version": 6
    }
    
    示例结果:
    {
      "result": 6,
      "error": null
    }
    

apiReflect

  • 获取有关 AnkiConnect API 的信息。该请求支持以下参数:
    • scopes - 一个包含要获取反射信息的范围的数组。 当前唯一支持的值是 "actions"
    • actions - 为 null 或一个包含 API 方法名称的数组。 如果值为 null,结果将列出所有可用的 API 动作。 如果值是一个字符串数组,结果仅包含在该数组中的动作。 结果将包含使用的作用域列表以及每个作用域的值。 例如,"actions" 范围将包含一个 "actions" 属性,其中包含受支持的动作名称列表。
    示例请求: ```json { "action": "apiReflect", "version": 6, "params": { "scopes": ["actions", "invalidType"], "actions": ["apiReflect", "invalidMethod"] } } ```
    示例结果: ```json { "result": { "scopes": ["actions"], "actions": ["apiReflect"] }, "error": null } ```

sync

  • 将本地 Anki 集合与 AnkiWeb 同步。
    示例请求: ```json { "action": "sync", "version": 6 } ```
    示例结果: ```json { "result": null, "error": null } ```

getProfiles

  • 检索配置文件列表。
    示例请求: ```json { "action": "getProfiles", "version": 6 } ```
    示例结果: ```json { "result": ["User 1"], "error": null } ```

getActiveProfile

  • 检索活动的配置文件。
    示例请求: ```json { "action": "getActiveProfile", "version": 6 } ```
    示例结果: ```json { "result": "User 1", "error": null } ```

loadProfile

  • 选择请求中指定的配置文件。
    示例请求: ```json { "action": "loadProfile", "version": 6, "params": { "name": "user1" } } ```
    示例结果: ```json { "result": true, "error": null } ```

multi

  • 在一个请求中执行多个操作,返回一个包含每个操作响应的数组(按给定顺序)。
    示例请求: ```json { "action": "multi", "version": 6, "params": { "actions": [ { "action": "deckNames" }, { "action": "deckNames", "version": 6 }, { "action": "invalidAction", "params": {"useless": "param"} }, { "action": "invalidAction", "params": {"useless": "param"}, "version": 6 } ] } } ```
    示例结果: ```json { "result": [ ["Default"], {"result": ["Default"], "error": null}, {"result": null, "error": "unsupported action"}, {"result": null, "error": "unsupported action"} ], "error": null } ```

exportPackage

  • 将给定牌组导出为 .apkg 格式。如果成功则返回 true,否则返回 false。可选属性 includeSched(默认为 false)可以指定是否包含卡片的调度数据。
    示例请求: ```json { "action": "exportPackage", "version": 6, "params": { "deck": "Default", "path": "/data/Deck.apkg", "includeSched": true } } ```
    示例结果: ```json { "result": true, "error": null } ```

importPackage

  • 将以 .apkg 格式的文件导入到集合中。如果成功则返回 true,否则返回 false。 注意,文件路径相对于 Anki 的 collection.media 文件夹,而不是客户端。
    示例请求: ```json { "action": "importPackage", "version": 6, "params": { "path": "/data/Deck.apkg" } } ```
    示例结果: ```json { "result": true, "error": null } ```

reloadCollection

  • 告诉 Anki 从数据库重新加载所有数据。
    示例请求: ```json { "action": "reloadCollection", "version": 6 } ```
    示例结果: ```json { "result": null, "error": null } ```

模型操作

modelNames

  • 获取当前用户的所有模型名称的完整列表。
    示例请求: ```json { "action": "modelNames", "version": 6 } ```
    示例结果: ```json { "result": ["Basic", "Basic (and reversed card)"], "error": null } ```

modelNamesAndIds

  • 获取当前用户的所有模型名称及其对应 ID 的完整列表。
    示例请求: ```json { "action": "modelNamesAndIds", "version": 6 } ```
    示例结果: ```json { "result": { "Basic": 1483883011648, "Basic (and reversed card)": 1483883011644, "Basic (optional reversed card)": 1483883011631, "Cloze": 1483883011630 }, "error": null } ```

findModelsById

  • 从当前用户提供的模型 ID 中获取模型列表。
示例请求: `json { "action": "findModelsById", "version": 6, "params": { "modelIds": [1704387367119, 1704387398570] } } `
示例结果: ```json { "result": [ { "id": 1704387367119, "name": "Basic", "type": 0, "mod": 1704387367, "usn": -1, "sortf": 0, "did": null, "tmpls": [ { "name": "Card 1", "ord": 0, "qfmt": "{{Front}}", "afmt": "{{FrontSide}}
{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 9176047152973362695 } ], "flds": [ { "name": "Front", "ord": 0, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": 2453723143453745216, "tag": null, "preventDeletion": false }, { "name": "Back", "ord": 1, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": -4853200230425436781, "tag": null, "preventDeletion": false } ], "css": ".card { font-family: arial; font-size: 20px; text-align: center; color: black; background-color: white; } ", "latexPre": "\\documentclass[12pt]{article} \\special{papersize=3in,5in} \\usepackage[utf8]{inputenc} \\usepackage{amssymb,amsmath} \\pagestyle{empty} \\setlength{\\parindent}{0in} \\begin{document} ", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ] ], "originalStockKind": 1 }, { "id": 1704387398570, "name": "Basic (and reversed card)", "type": 0, "mod": 1704387398, "usn": -1, "sortf": 0, "did": null, "tmpls": [ { "name": "Card 1", "ord": 0, "qfmt": "{{Front}}", "afmt": "{{FrontSide}}
{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 1689886528158874152 }, { "name": "Card 2", "ord": 1, "qfmt": "{{Back}}", "afmt": "{{FrontSide}}
{{Front}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": -7839609225644824587 } ], "flds": [ { "name": "Front", "ord": 0, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": -7787837672455357996, "tag": null, "preventDeletion": false }, { "name": "Back", "ord": 1, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": 6364828289839985081, "tag": null, "preventDeletion": false } ], "css": ".card { font-family: arial; font-size: 20px; text-align: center; color: black; background-color: white; } ", "latexPre": "\\documentclass[12pt]{article} \\special{papersize=3in,5in} \\usepackage[utf8]{inputenc} \\usepackage{amssymb,amsmath} \\pagestyle{empty} \\setlength{\\parindent}{0in} \\begin{document} ", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ], [ 1, "any", [ 1 ] ] ], "originalStockKind": 1 } ], "error": null } ```

findModelsByName

  • 从当前用户提供的模型名称中获取模型列表。
示例请求: `json { "action": "findModelsByName", "version": 6, "params": { "modelNames": ["Basic", "Basic (and reversed card)"] } } `
示例结果: ```json { "result": [ { "id": 1704387367119, "name": "Basic", "type": 0, "mod": 1704387367, "usn": -1, "sortf": 0, "did": null, "tmpls": [ { "name": "Card 1", "ord": 0, "qfmt": "{{Front}}", "afmt": "{{FrontSide}}
{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 9176047152973362695 } ], "flds": [ { "name": "Front", "ord": 0, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": 2453723143453745216, "tag": null, "preventDeletion": false }, { "name": "Back", "ord": 1, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": -4853200230425436781, "tag": null, "preventDeletion": false } ], "css": ".card { font-family: arial; font-size: 20px; text-align: center; color: black; background-color: white; } ", "latexPre": "\\documentclass[12pt]{article} \\special{papersize=3in,5in} \\usepackage[utf8]{inputenc} \\usepackage{amssymb,amsmath} \\pagestyle{empty} \\setlength{\\parindent}{0in} \\begin{document} ", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ] ], "originalStockKind": 1 }, { "id": 1704387398570, "name": "Basic (and reversed card)", "type": 0, "mod": 1704387398, "usn": -1, "sortf": 0, "did": null, "tmpls": [ { "name": "Card 1", "ord": 0, "qfmt": "{{Front}}", "afmt": "{{FrontSide}}
{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 1689886528158874152 }, { "name": "Card 2", "ord": 1, "qfmt": "{{Back}}", "afmt": "{{FrontSide}}
{{Front}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": -7839609225644824587 } ], "flds": [ { "name": "Front", "ord": 0, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": -7787837672455357996, "tag": null, "preventDeletion": false }, { "name": "Back", "ord": 1, "sticky": false, "rtl": false, "font": "Arial", "size": 20, "description": "", "plainText": false, "collapsed": false, "excludeFromSearch": false, "id": 6364828289839985081, "tag": null, "preventDeletion": false } ], "css": ".card { font-family: arial; font-size: 20px; text-align: center; color: black; background-color: white; } ", "latexPre": "\\documentclass[12pt]{article} \\special{papersize=3in,5in} \\usepackage[utf8]{inputenc} \\usepackage{amssymb,amsmath} \\pagestyle{empty} \\setlength{\\parindent}{0in} \\begin{document} ", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ], [ 1, "any", [ 1 ] ] ], "originalStockKind": 1 } ], "error": null } ```

modelFieldNames

  • 获取提供模型名称的字段名称的完整列表。
    示例请求: ```json { "action": "modelFieldNames", "version": 6, "params": { "modelName": "Basic" } } ```
    示例结果: ```json { "result": ["Front", "Back"], "error": null } ```

modelFieldDescriptions

  • 获取提供模型名称的字段描述(在 GUI 编辑器中字段为空时看到的文本)的完整列表。
    示例请求: ```json { "action": "modelFieldDescriptions", "version": 6, "params": { "modelName": "Basic" } } ```
    示例结果: ```json { "result": ["", ""], "error": null } ```

modelFieldFonts

  • 获取字体及其字体大小的完整列表。
    示例请求: ```json { "action": "modelFieldFonts", "version": 6, "params": { "modelName": "Basic" } } ```
    示例结果: ```json { "result": { "Front": { "font": "Arial", "size": 20 }, "Back": { "font": "Arial", "size": 20 } }, "error": null } ```

modelFieldsOnTemplates

  • 返回一个对象,指示给定模型名称的每个卡模板的问题和答案侧的字段。问题侧在每个数组中首先给出。
    示例请求: ```json { "action": "modelFieldsOnTemplates", "version": 6, "params": { "modelName": "Basic (and reversed card)" } } ```
    示例结果: ```json { "result": { "Card 1": "Front"], ["Back", "Card 2": "Back"], ["Front" }, "error": null } ```

createModel

  • 创建一个用于 Anki 的新模型。用户必须提供 modelName, inOrderFieldscardTemplates。 可选字段有 cssisCloze。如果未指定,css 将使用默认的 Anki cssisCloze 将等于 false。如果 isClozetrue,则模型将作为 Cloze 创建。 可以为 cardTemplates 中的每个条目提供可选的 Name 字段。默认情况下,卡名称将是 Card 1Card 2 等等。
    示例请求: `json { "action": "createModel", "version": 6, "params": { "modelName": "newModelName", "inOrderFields": ["Field1", "Field2", "Field3"], "css": "Optional CSS with default to builtin css", "isCloze": false, "cardTemplates": [ { "Name": "My Card 1", "Front": "Front html {{Field1}}", "Back": "Back html {{Field2}}" } ] } } `
    示例结果: `json { "result":{ "sortf":0, "did":1, "latexPre":"\\documentclass[12pt]{article}

\special{papersize=3in,5in} \usepackage[utf8]{inputenc} \usepackage{amssymb,amsmath} \pagestyle{empty} \setlength{\parindent}{0in} \begin{document} ", "latexPost":"\end{document}", "mod":1551462107, "usn":-1, "vers":[ ], "type":0, "css":".card { font-family: arial; font-size: 20px; text-align: center; color: black; background-color: white; } ", "name":"TestApiModel", "flds":[ { "name":"Field1", "ord":0, "sticky":false, "rtl":false, "font":"Arial", "size":20, "media":[ ] }, { "name":"Field2", "ord":1, "sticky":false, "rtl":false, "font":"Arial", "size":20, "media":[ ] } ], "tmpls":[ { "name":"My Card 1", "ord":0, "qfmt":"", "afmt":"This is the back of the card {{Field2}}", "did":null, "bqfmt":"", "bafmt":"" } ], "tags":[ ], "id":1551462107104, "req":[ [ 0, "none", [ ] ] ] }, "error":null } `

modelTemplates

  • 返回一个对象,表示通过提供的模型名称连接的每张卡的模板内容。
示例请求: `json { "action": "modelTemplates", "version": 6, "params": { "modelName": "Basic (and reversed card)" } } `
示例结果: ```json { "result": { "Card 1": { "Front": "{{Front}}", "Back": "{{FrontSide}}
{{Back}}" }, "Card 2": { "Front": "{{Back}}", "Back": "{{FrontSide}}
{{Front}}" } }, "error": null } ```

modelStyling

  • 获取通过提供的模型名称的模型的 CSS 样式。
    示例请求: `json { "action": "modelStyling", "version": 6, "params": { "modelName": "Basic (and reversed card)" } } `
    示例结果: `json { "result": { "css": ".card {

font-family: arial; font-size: 20px; text-align: center; color: black; background-color: white; } " }, "error": null } `

updateModelTemplates

  • 通过名称修改现有模型的模板。仅修改请求中指定的卡和指定的侧面。 如果请求中未包含现有的卡或侧面,则不会进行任何更改。
    示例请求: ```json { "action": "updateModelTemplates", "version": 6, "params": { "model": { "name": "Custom", "templates": { "Card 1": { "Front": "{{Question}}?", "Back": "{{Answer}}!" } } } } ```
    示例结果: ```json { "result": null, "error": null } ```

updateModelStyling

  • 修改现有模型的 CSS 样式。
    示例请求: ```json { "action": "updateModelStyling", "version": 6, "params": { "model": { "name": "Custom", "css": "p { color: blue; }" } } ```
    示例结果: ```json { "result": null, "error": null } ```

findAndReplaceInModels

  • 在现有模型中查找并替换字符串。可以通过设置为 true/false 来自定义在 front、back 或 css 中替换。
    示例请求: ```json { "action": "findAndReplaceInModels", "version": 6, "params": { "model": { "modelName": "", "findText": "text_to_replace", "replaceText": "replace_with_text", "front": true, "back": true, "css": true } } ```
    示例结果: ```json { "result": 1, "error": null } ```

modelTemplateRename

  • 重命名现有模型中的模板。
    示例请求: ```json { "action": "modelTemplateRename", "version": 6, "params": { "modelName": "Basic", "oldTemplateName": "Card 1", "newTemplateName": "Card 1 renamed" } ```
    示例结果: ```json { "result": null, "error": null } ```

modelTemplateReposition

  • 重新定位现有模型中的模板。 index 的值从 0 开始。例如,索引为 0 时将模板放在第一个位置,索引为 2 时将模板放在第三个位置。
    示例请求: ```json { "action": "modelTemplateReposition", "version": 6, "params": { "modelName": "Basic", "templateName": "Card 1", "index": 1 } ```
    示例结果: ```json { "result": null, "error": null } ```

modelTemplateAdd

  • 通过名称向现有模型添加模板。如果您想更新现有模板,请使用 updateModelTemplates
    示例请求: ```json { "action": "modelTemplateAdd", "version": 6, "params": { "modelName": "Basic", "template": { "Name": "Card 3", "Front": "Front html {{Field1}}", "Back": "Back html {{Field2}}" } } ```
    示例结果: ```json { "result": null, "error": null } ```

modelTemplateRemove

  • 从现有模型中删除模板。
    示例请求: ```json { "action": "modelTemplateRemove", "version": 6, "params": { "modelName": "Basic", "templateName": "Card 1" } ```
    示例结果: ```json { "result": null, "error": null } ```

modelFieldRename

  • 重命名给定模型的字段名称。
    示例请求: ```json { "action": "modelFieldRename", "version": 6, "params": { "modelName": "Basic", "oldFieldName": "Front", "newFieldName": "FrontRenamed" } ```
    示例结果: ```json { "result": null, "error": null } ```

modelFieldReposition

  • 在给定模型的字段列表中重新定位字段。 index 的值从 0 开始。例如,索引为 0 时将字段放在第一个位置,索引为 2 时将字段放在第三个位置。
    示例请求: ```json { "action": "modelFieldReposition", "version": 6, "params": { "modelName": "Basic", "fieldName": "Back", "index": 0 } ```
    示例结果: ```json { "result": null, "error": null } ```

modelFieldAdd

  • 在给定模型中创建一个新字段。 可以选择性地提供 index 值,其工作方式与 modelFieldReposition 中的索引完全相同。默认情况下,字段会被添加到字段列表的末尾。
    示例请求: ```json { "action": "modelFieldAdd", "version": 6, "params": { "modelName": "Basic", "fieldName": "NewField", "index": 0 } ```
    示例结果: ```json { "result": null, "error": null } ```

modelFieldRemove

  • 删除给定模型内的字段。
    示例请求: ```json { "action": "modelFieldRemove", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front" } ```
    示例结果: ```json { "result": null, "error": null } ```

modelFieldSetFont

  • 设置给定模型内字段的字体。
    示例请求: ```json { "action": "modelFieldSetFont", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "font": "Courier" } ```
    示例结果: ```json { "result": null, "error": null } ```

modelFieldSetFontSize

  • 设置给定模型内字段的字体大小。
    示例请求: ```json { "action": "modelFieldSetFontSize", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "fontSize": 10 } ```
    示例结果: ```json { "result": null, "error": null } ```

modelFieldSetDescription

  • 设置给定模型内字段的描述(在字段为空时在 GUI 编辑器中看到的文本)。 较旧版本的 Anki2.1.49 及以下)没有字段描述。在这种情况下,这将返回 false
    示例请求: ```json { "action": "modelFieldSetDescription", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "description": "example field description" } ```
    示例结果: ```json { "result": true, "error": null } ```

笔记操作

addNote

  • 使用给定的牌组和模型,以及提供的字段值和标签创建笔记。在成功创建时返回创建的笔记标识符,在失败时返回 null。 Anki-Connect 可以下载音频、视频和图片文件并将它们嵌入到新创建的笔记中。相应的 audiovideopicture 笔记成员是可选的,可以省略。如果您选择包含其中任何一个,它们应该包含一个单个对象或一组具有必填 filename 字段和 datapathurl 其中之一的对象。请参阅 storeMediaFile 文档以了解这些字段的解释。 可以选择性地提供 skipHash 字段以跳过包含与提供的 MD5 哈希匹配的文件。这对于避免保存错误页面和存根文件很有用。 fields 成员是一个应播放音频或视频或在 Anki 中显示卡片时显示图片的字段列表。options 组内的 allowDuplicate 成员可以设置为 true 以启用添加重复卡片。通常重复卡片不能被添加,并会触发异常。 duplicateScope 成员可以在 options 内用于指定检查重复项的范围。值为 "deck" 将只在目标牌组中检查重复项;其他任何值将在整个集合中检查。 duplicateScopeOptions 对象可用于指定一些额外的设置:
    • duplicateScopeOptions.deckName 将指定在检查重复项时使用的牌组。如果未定义或为 null,将使用目标牌组。
    • duplicateScopeOptions.checkChildren 将改变是否在子牌组中检查重复卡片。默认值为 false
    • duplicateScopeOptions.checkAllModels 指定是否在所有笔记类型之间执行重复检查。默认值为 false
    示例请求: ```json { "action": "addNote", "version": 6, "params": { "note": { "deckName": "Default", "modelName": "Basic", "fields": { "Front": "front content", "Back": "back content" }, "options": { "allowDuplicate": false, "duplicateScope": "deck", "duplicateScopeOptions": { "deckName": "Default", "checkChildren": false, "checkAllModels": false } }, "tags": [ "yomichan" ], "audio": [{ "url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ", "filename": "yomichan_ねこ_猫.mp3", "skipHash": "7e2c2f954ef6051373ba916f000168dc", "fields": [ "Front" ] }], "video": [{ "url": "https://cdn.videvo.net/videvo_files/video/free/2015-06/small_watermarked/Contador_Glam_preview.mp4", "filename": "countdown.mp4", "skipHash": "4117e8aab0d37534d9c8eac362388bbe", "fields": [ "Back" ] }], "picture": [{ "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/A_black_cat_named_Tilly.jpg/220px-A_black_cat_named_Tilly.jpg", "filename": "black_cat.jpg", "skipHash": "8d6e4646dfae812bf39651b59d7429ce", "fields": [ "Back" ] }] } } ```
    示例结果: ```json { "result": 1496198395707, "error": null } ```

addNotes

  • 使用给定的牌组和模型,以及提供的字段值和标签创建多个笔记。返回创建的笔记标识符的数组。在发生任何错误的情况下,将收集所有错误并返回。
  • 请参阅 addNote 的文档以了解 notes 数组中的对象的解释。
    示例请求: ```json { "action":"addNotes", "version":6, "params":{ "notes":[ { "deckName":"College::PluginDev", "modelName":"non_existent_model", "fields":{ "Front":"front", "Back":"bak" } }, { "deckName":"College::PluginDev", "modelName":"Basic", "fields":{ "Front":"front", "Back":"bak" } } ] } ```
    示例结果: ```json { "result":null, "error":"['model was not found: non_existent_model']" } ```

canAddNotes

  • 接收一个定义候选笔记参数的对象数组(参见 addNote),并返回一个布尔数组,指示相应索引处的参数是否可以用于创建新笔记。
    示例请求: ```json { "action": "canAddNotes", "version": 6, "params": { "notes": [ { "deckName": "Default", "modelName": "Basic", "fields": { "Front": "front content", "Back": "back content" }, "tags": [ "yomichan" ] } ] } ```
    示例结果: ```json { "result": [true], "error": null } ```

canAddNotesWithErrorDetail

  • 接收一个定义候选笔记参数的对象数组(参见 addNote),并返回一个包含 canAdderror 字段的对象数组。
    • canAdd 表示相应索引处的参数是否可以用于创建新笔记。
    • error 包含无法添加笔记的原因说明。
    示例请求: ```json { "action": "canAddNotesWithErrorDetail", "version": 6, "params": { "notes": [ { "deckName": "Default", "modelName": "Basic", "fields": { "Front": "front content", "Back": "back content" }, "tags": [ "yomichan" ] }, { "deckName": "Default", "modelName": "Basic", "fields": { "Front": "front content 2", "Back": "back content 2" }, "tags": [ "yomichan" ] } ] } ```
    示例结果: ```json { "result": [ { "canAdd": false, "error": "cannot create note because it is a duplicate" }, { "canAdd": true } ], "error": null } ```

updateNoteFields

  • 修改现有笔记的字段。您还可以包括音频、视频或图片文件,这些文件将使用可选的 audiovideopicture 属性添加到笔记中。请参阅 addNote 的文档以了解 audiovideopicture 数组中的对象的解释。

    警告 您不能在 Anki 浏览器中查看正在更新的笔记,否则字段不会更新。详情请参见 此问题

    示例请求: ```json { "action": "updateNoteFields", "version": 6, "params": { "note": { "id": 1514547547030, "fields": { "Front": "new front content", "Back": "new back content" }, "audio": [{ "url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ", "filename": "yomichan_ねこ_猫.mp3", "skipHash": "7e2c2f954ef6051373ba916f000168dc", "fields": [ "Front" ] }] } } ```
    示例结果: ```json { "result": null, "error": null } ```

updateNote

  • 修改现有笔记的字段和/或标签。 换句话说,结合了 updateNoteFieldsupdateNoteTags。 请参阅它们的文档以了解所有属性的解释。 可以省略 fieldstags 属性而不影响另一个。 因此,对 updateNoteFields 的有效请求也适用于 updateNote。 如果既不提供 fields 也不提供 tags,该方法将失败。 首先更新字段,如果更新标签失败,字段不会回滚。 如果更新字段失败,则不会更新标签。

    警告 您不能在 Anki 浏览器中查看正在更新的笔记,否则字段不会更新。详情请参见 此问题

    示例请求: ```json { "action": "updateNote", "version": 6, "params": { "note": { "id": 1514547547030, "fields": { "Front": "new front content", "Back": "new back content" }, "tags": ["new", "tags"] } } ```
    示例结果: ```json { "result": null, "error": null } ```

updateNoteModel

  • 更新现有笔记的模型、字段和标签。 这允许您更改笔记的模型,使用新内容更新其字段,并设置新的标签。
    示例请求: ```json { "action": "updateNoteModel", "version": 6, "params": { "note": { "id": 1514547547030, "modelName": "NewModel", "fields": { "NewField1": "new field 1", "NewField2": "new field 2", "NewField3": "new field 3" }, "tags": ["new", "updated", "tags"] } } ```
    示例结果: ```json { "result": null, "error": null } ```

updateNoteTags

  • 通过笔记 ID 设置笔记的标签。旧标签将被移除。
    示例请求: ```json { "action": "updateNoteTags", "version": 6, "params": { "note": 1483959289817, "tags": ["european-languages"] } ```
    示例结果: ```json { "result": null, "error": null } ```

getNoteTags

  • 通过笔记 ID 获取笔记的标签。
    示例请求: ```json { "action": "getNoteTags", "version": 6, "params": { "note": 1483959289817 } ```
    示例结果: ```json { "result": ["european-languages"], "error": null } ```

addTags

  • 通过笔记 ID 向笔记添加标签。
    示例请求: ```json { "action": "addTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tags": "european-languages" } ```
    示例结果: ```json { "result": null, "error": null } ```

removeTags

  • 通过笔记 ID 从笔记中移除标签。
    示例请求: ```json { "action": "removeTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tags": "european-languages" } ```
    示例结果: ```json { "result": null, "error": null } ```

getTags

  • 获取当前用户的完整标签列表。
    示例请求: ```json { "action": "getTags", "version": 6 ```
    示例结果: ```json { "result": ["european-languages", "idioms"], "error": null } ```

clearUnusedTags

  • 清除当前用户笔记中所有未使用的标签。
    示例请求: ```json { "action": "clearUnusedTags", "version": 6 ```
    示例结果: ```json { "result": null, "error": null } ```

replaceTags

  • 替换笔记中的标签。
    示例请求: ```json { "action": "replaceTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tag_to_replace": "european-languages", "replace_with_tag": "french-languages" } ```
    示例结果: ```json { "result": null, "error": null } ```

replaceTagsInAllNotes

  • 替换当前用户所有笔记中的标签。
    示例请求: ```json { "action": "replaceTagsInAllNotes", "version": 6, "params": { "tag_to_replace": "european-languages", "replace_with_tag": "french-languages" } ```
    示例结果: ```json { "result": null, "error": null } ```

findNotes

  • 返回给定查询的笔记 ID 数组。查询语法记录在 此处
    示例请求: ```json { "action": "findNotes", "version": 6, "params": { "query": "deck:current" } ```
    示例结果: ```json { "result": [1483959289817, 1483959291695], "error": null } ```

notesInfo

  • 返回一个对象列表,包含每个笔记 ID 的笔记字段、标签、笔记类型、修改时间、属于该笔记的卡片以及创建该笔记的配置文件。

    示例请求笔记ID ```json { "action": "notesInfo", "version": 6, "params": { "notes": [1502298033753] } ```
    示例请求(查询): ```json { "action": "notesInfo", "version": 6, "params": { "query": "deck:current" } ```
    示例结果: ```json { "result": [ { "noteId":1502298033753, "profile": "User_1", "modelName": "Basic", "tags":["tag","another_tag"], "fields": { "Front": {"value": "front content", "order": 0}, "Back": {"value": "back content", "order": 1} }, "mod": 1718377864, "cards": [1498938915662] } ], "error": null } ```

    notesModTime

  • 返回一个对象列表,每个对象包含对应笔记 ID 的修改时间。

    示例请求:
    {
      "action": "notesModTime",
      "version": 6,
      "params": {
        "notes": [1502298033753]
      }
    }
    
    示例结果:
    {
      "result": [
        {
          "noteId": 1498938915662,
          "mod": 1629454092
        }
      ],
      "error": null
    }
    

deleteNotes

  • 删除指定 ID 的笔记。如果某个笔记关联了多张卡片,则所有关联的卡片也会被删除。

    示例请求:
    {
      "action": "deleteNotes",
      "version": 6,
      "params": {
        "notes": [1502298033753]
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

removeEmptyNotes

  • 移除当前用户所有空的笔记。

    示例请求:
    {
      "action": "removeEmptyNotes",
      "version": 6
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    

统计操作

getNumCardsReviewedToday

  • 获取当天已复习卡片的数量(以 Anki 用户配置的起始时间为准)。

    示例请求:
    {
      "action": "getNumCardsReviewedToday",
      "version": 6
    }
    
    示例结果:
    {
      "result": 0,
      "error": null
    }
    

getNumCardsReviewedByDay

  • 获取每天复习卡片的数量,返回一个包含 (日期字符串, 数量) 对的列表。

    示例请求:
    {
      "action": "getNumCardsReviewedByDay",
      "version": 6
    }
    
    示例结果:
    {
      "result": [
        ["2021-02-28", 124],
        ["2021-02-27", 261]
      ],
      "error": null
    }
    

getCollectionStatsHTML

  • 获取整套卡组的统计报告HTML 格式)。

    示例请求:
    {
      "action": "getCollectionStatsHTML",
      "version": 6,
      "params": {
        "wholeCollection": true
      }
    }
    
    示例结果:
    {
      "result": "<center> lots of HTML here </center>",
      "error": null
    }
    

cardReviews

  • 请求指定牌组在某一时间之后的所有卡片复习记录。 startID 是不会包含在结果中的最新 unix 时间。 返回值为一个包含 9 个元素的元组列表,格式为 (复习时间, 卡片ID, usn, 按下的按钮, 新间隔, 上次间隔, 新因子, 复习时长, 复习类型)

    示例请求:
    {
      "action": "cardReviews",
      "version": 6,
      "params": {
        "deck": "default",
        "startID": 1594194095740
      }
    }
    
    示例结果:
    {
      "result": [
        [1594194095746, 1485369733217, -1, 3, 4, -60, 2500, 6157, 0],
        [1594201393292, 1485369902086, -1, 1, -60, -60, 0, 4846, 0]
      ],
      "error": null
    }
    

getReviewsOfCards

  • 请求每个卡片 ID 的所有复习记录。 返回一个字典,将每个卡片 ID 映射到一个由下述格式字典组成的列表:

    {
        "id": reviewTime,
        "usn": usn,
        "ease": buttonPressed,
        "ivl": newInterval,
        "lastIvl": previousInterval,
        "factor": newFactor,
        "time": reviewDuration,
        "type": reviewType,
    }
    

    之所以使用这些键名而不是更具描述性的名称,是因为这些是 Anki 数据库中使用的实际键名。

    示例请求:
    {
      "action": "getReviewsOfCards",
      "version": 6,
      "params": {
        "cards": ["1653613948202"]
      }
    }
    
    示例结果:
    {
      "result": {
        "1653613948202": [
          {
            "id": 1653772912146,
            "usn": 1750,
            "ease": 1,
            "ivl": -20,
            "lastIvl": -20,
            "factor": 0,
            "time": 38192,
            "type": 0
          },
          {
            "id": 1653772965429,
            "usn": 1750,
            "ease": 3,
            "ivl": -45,
            "lastIvl": -20,
            "factor": 0,
            "time": 15337,
            "type": 0
          }
        ]
      },
      "error": null
    }
    

getLatestReviewID

  • 返回指定牌组最近一次复习的 unix 时间。如果该牌组从未被复习过,则返回 0。

    示例请求:
    {
      "action": "getLatestReviewID",
      "version": 6,
      "params": {
        "deck": "default"
      }
    }
    
    示例结果:
    {
      "result": 1594194095746,
      "error": null
    }
    

insertReviews

  • 将给定的复习记录插入数据库。所需格式为 9 元素元组列表:(复习时间, 卡片ID, usn, 按下的按钮, 新间隔, 上次间隔, 新因子, 复习时长, 复习类型)

    示例请求:
    {
      "action": "insertReviews",
      "version": 6,
      "params": {
        "reviews": [
          [1594194095746, 1485369733217, -1, 3, 4, -60, 2500, 6157, 0],
          [1594201393292, 1485369902086, -1, 1, -60, -60, 0, 4846, 0]
        ]
      }
    }
    
    示例结果:
    {
      "result": null,
      "error": null
    }
    
Description
自定义的anki-connect,添加一些自己的注释和使用说明文档。
Readme 156 KiB
Languages
Python 99.7%
Shell 0.3%