193 KiB
Anki-Connect
Anki-Connect使外部应用程序(如Yomichan)能够通过简单的HTTP API与Anki进行通信。它的功能包括对用户卡片组执行查询、自动创建新卡片等。Anki-Connect与最新的稳定版(2.1.x)Anki兼容;旧版本(2.0.x及以下)不再受支持。
安装
安装过程与其他Anki插件类似,可以通过以下三个步骤完成:
- 在Anki中选择
工具
|插件
|获取插件...
,打开安装插件
对话框。 - 在标有
代码
的文本框中输入2055492159,然后按确定
按钮继续。 - 当提示重启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:
- 启动终端应用程序。
- 在终端窗口中执行以下命令:
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
- 重启Anki。
开发者应用程序接口
Anki-Connect通过易于使用的API向外部应用程序公开Anki的内部功能。安装后,只要启动Anki,该插件就会在8765端口启动HTTP服务器。其他应用程序(包括浏览器扩展)可以通过HTTP请求与其通信。
默认情况下,Anki-Connect只会将HTTP服务器绑定到127.0.0.1
IP地址,因此您只能从运行它的同一主机访问它。如果您需要通过网络访问,可以在配置中更改绑定地址。进入工具->插件->AnkiConnect->配置,更改"webBindAddress"值。例如,您可以将其设置为0.0.0.0
,以将其绑定到主机上的所有网络接口。这也需要重启Anki。
调用示例
每个请求都由一个包含action
、version
、上下文params
和用于认证的key
值(可选,默认可以省略)的JSON编码对象组成。Anki-Connect将返回一个包含两个字段的对象:result
和error
。result
字段包含执行的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的最近间隔,或者当
complete
为true
时,返回每个给定卡片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
属性来重新排序卡片浏览器中显示的卡片。 这是一个包含order
和columnId
对象的数组。order
可以是ascending
或descending
,而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
-
调用添加卡片对话框,使用给定的卡组和模型预设笔记,带有提供的字段值和标签。 多次调用会关闭旧窗口并_重新打开窗口_,使用新提供的值。
可以通过
audio
、video
和picture
键将音频、视频和图片文件嵌入到字段中。 请参考addNote
和storeMediaFile
的文档,了解这些字段的说明。结果是如果用户选择确认添加卡片对话框,将添加的笔记的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。如果提供了
data
、path
和url
中的多个,将首先使用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
字段,该字段反过来包含字符串granted
或denied
,对应于您的来源是否受信任。如果您的来源受信任,还将返回字段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的版本。目前定义了版本
1
到6
。示例请求:
{ "action": "version", "version": 6 }
示例结果:
{ "result": 6, "error": null }
apiReflect
-
获取有关可用AnkiConnect API的信息。请求支持以下参数:
Anki-Connect
Anki-Connect使外部应用程序(如Yomichan)能够通过简单的HTTP API与Anki进行通信。它的功能包括对用户卡片组执行查询、自动创建新卡片等。Anki-Connect与最新的稳定版(2.1.x)Anki兼容;旧版本(2.0.x及以下)不再受支持。
安装
安装过程与其他Anki插件类似,可以通过以下三个步骤完成:
- 在Anki中选择
工具
|插件
|获取插件...
,打开安装插件
对话框。 - 在标有
代码
的文本框中输入2055492159,然后按确定
按钮继续。 - 当提示重启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:
- 启动终端应用程序。
- 在终端窗口中执行以下命令:
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
- 重启Anki。
开发者应用程序接口
Anki-Connect通过易于使用的API向外部应用程序公开Anki的内部功能。安装后,只要启动Anki,该插件就会在8765端口启动HTTP服务器。其他应用程序(包括浏览器扩展)可以通过HTTP请求与其通信。
默认情况下,Anki-Connect只会将HTTP服务器绑定到127.0.0.1
IP地址,因此您只能从运行它的同一主机访问它。如果您需要通过网络访问,可以在配置中更改绑定地址。进入工具->插件->AnkiConnect->配置,更改"webBindAddress"值。例如,您可以将其设置为0.0.0.0
,以将其绑定到主机上的所有网络接口。这也需要重启Anki。
调用示例
每个请求都由一个包含action
、version
、上下文params
和用于认证的key
值(可选,默认可以省略)的JSON编码对象组成。Anki-Connect将返回一个包含两个字段的对象:result
和error
。result
字段包含执行的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的最近间隔,或者当
complete
为true
时,返回每个给定卡片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
属性来重新排序卡片浏览器中显示的卡片。 这是一个包含order
和columnId
对象的数组。order
可以是ascending
或descending
,而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
-
调用添加卡片对话框,使用给定的卡组和模型预设笔记,带有提供的字段值和标签。 多次调用会关闭旧窗口并_重新打开窗口_,使用新提供的值。
可以通过
audio
、video
和picture
键将音频、视频和图片文件嵌入到字段中。 请参考addNote
和storeMediaFile
的文档,了解这些字段的说明。结果是如果用户选择确认添加卡片对话框,将添加的笔记的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。如果提供了
data
、path
和url
中的多个,将首先使用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
字段,该字段反过来包含字符串granted
或denied
,对应于您的来源是否受信任。如果您的来源受信任,还将返回字段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的版本。目前定义了版本
1
到6
。示例请求:
{ "action": "version", "version": 6 }
示例结果:
{ "result": 6, "error": null }
apiReflect
-
获取有关可用 AnkiConnect API 的信息。请求支持以下参数:
scopes
- 要获取反射信息的作用域数组。 目前唯一支持的值是"actions"
。actions
- 可以是null
或者 API 方法名称的数组。 如果值为null
,结果将列出所有可用的 API 动作。 如果值是字符串数组,结果将只包含该数组中存在的动作。
结果将包含使用了哪些作用域及每个作用域的值。 例如,
"actions"
作用域将包含一个"actions"
属性,其中包含支持的动作名称列表。请求示例:
{ "action": "apiReflect", "version": 6, "params": { "scopes": ["actions", "invalidType"], "actions": ["apiReflect", "invalidMethod"] } }
结果示例:
{ "result": { "scopes": ["actions"], "actions": ["apiReflect"] }, "error": null }
sync
-
将本地 Anki 集合与 AnkiWeb 同步。
请求示例:
{ "action": "sync", "version": 6 }
结果示例:
{ "result": null, "error": null }
getProfiles
-
获取个人资料列表。
请求示例:
{ "action": "getProfiles", "version": 6 }
结果示例:
{ "result": ["User 1"], "error": null }
getActiveProfile
-
获取当前活动个人资料。
请求示例:
{ "action": "getActiveProfile", "version": 6 }
结果示例:
{ "result": "User 1", "error": null }
loadProfile
-
选择请求中指定的个人资料。
请求示例:
{ "action": "loadProfile", "version": 6, "params": { "name": "user1" } }
结果示例:
{ "result": true, "error": null }
multi
-
在一个请求中执行多个操作,返回一个数组,其中包含每个操作的响应(按给定顺序)。
请求示例:
{ "action": "multi", "version": 6, "params": { "actions": [ { "action": "deckNames" }, { "action": "deckNames", "version": 6 }, { "action": "invalidAction", "params": {"useless": "param"} }, { "action": "invalidAction", "params": {"useless": "param"}, "version": 6 } ] } }
结果示例:
{ "result": [ ["Default"], {"result": ["Default"], "error": null}, {"result": null, "error": "unsupported action"}, {"result": null, "error": "unsupported action"} ], "error": null }
exportPackage
-
将指定的牌组以
.apkg
格式导出。如果成功则返回true
,否则返回false
。可以指定可选属性includeSched
(默认为false
)以包含卡片的调度数据。请求示例:
{ "action": "exportPackage", "version": 6, "params": { "deck": "Default", "path": "/data/Deck.apkg", "includeSched": true } }
结果示例:
{ "result": true, "error": null }
importPackage
-
将
.apkg
格式的文件导入集合中。如果成功则返回true
,否则返回false
。 注意,文件路径是相对于 Anki 的 collection.media 文件夹,而不是相对于客户端。请求示例:
{ "action": "importPackage", "version": 6, "params": { "path": "/data/Deck.apkg" } }
结果示例:
{ "result": true, "error": null }
reloadCollection
-
告诉 Anki 从数据库重新加载所有数据。
请求示例:
{ "action": "reloadCollection", "version": 6 }
结果示例:
{ "result": null, "error": null }
模型(笔记类型)操作
modelNames
-
获取当前用户的完整模型名称列表。
请求示例:
{ "action": "modelNames", "version": 6 }
结果示例:
{ "result": ["Basic", "Basic (and reversed card)"], "error": null }
modelNamesAndIds
-
获取当前用户的完整模型名称及其对应的 ID 列表。
请求示例:
{ "action": "modelNamesAndIds", "version": 6 }
结果示例:
{ "result": { "Basic": 1483883011648, "Basic (and reversed card)": 1483883011644, "Basic (optional reversed card)": 1483883011631, "Cloze": 1483883011630 }, "error": null }
findModelsById
-
根据提供的模型 ID 从当前用户获取模型列表。
请求示例:
{ "action": "findModelsById", "version": 6, "params": { "modelIds": [1704387367119, 1704387398570] } }
结果示例:
{ "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}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "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}}\n\n<hr id=answer>\n\n{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 1689886528158874152 }, { "name": "Card 2", "ord": 1, "qfmt": "{{Back}}", "afmt": "{{FrontSide}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ], [ 1, "any", [ 1 ] ] ], "originalStockKind": 1 } ], "error": null }
findModelsByName
-
根据提供的模型名称从当前用户获取模型列表。
请求示例:
{ "action": "findModelsByName", "version": 6, "params": { "modelNames": ["Basic", "Basic (and reversed card)"] } }
结果示例:
{ "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}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "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}}\n\n<hr id=answer>\n\n{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 1689886528158874152 }, { "name": "Card 2", "ord": 1, "qfmt": "{{Back}}", "afmt": "{{FrontSide}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ], [ 1, "any", [ 1 ] ] ], "originalStockKind": 1 } ], "error": null }
modelFieldNames
-
获取提供的模型名称的完整字段名称列表。
请求示例:
{ "action": "modelFieldNames", "version": 6, "params": { "modelName": "Basic" } }
结果示例:
{ "result": ["Front", "Back"], "error": null }
modelFieldDescriptions
-
获取提供的模型名称的完整字段描述列表(当字段为空时在 GUI 编辑器中显示的文本)。
请求示例:
{ "action": "modelFieldDescriptions", "version": 6, "params": { "modelName": "Basic" } }
结果示例:
{ "result": ["", ""], "error": null }
modelFieldFonts
-
获取完整的字体列表及其字体大小。
请求示例:
{ "action": "modelFieldFonts", "version": 6, "params": { "modelName": "Basic" } }
结果示例:
{ "result": { "Front": { "font": "Arial", "size": 20 }, "Back": { "font": "Arial", "size": 20 } }, "error": null }
modelFieldsOnTemplates
-
返回一个对象,指示给定模型名称的每个卡片模板的问题侧和答案侧的字段。 问题侧在每个数组中首先给出。
请求示例:
{ "action": "modelFieldsOnTemplates", "version": 6, "params": { "modelName": "Basic (and reversed card)" } }
结果示例:
{ "result": { "Card 1": [["Front"], ["Back"]], "Card 2": [["Back"], ["Front"]] }, "error": null }
createModel
-
创建一个新模型以在 Anki 中使用。用户必须提供
modelName
、inOrderFields
和cardTemplates
来 在模型中使用。有可选字段css
和isCloze
。如果未指定,css
将使用默认的 Anki CSS,isCloze
将等于false
。如果isCloze
为true
,则模型将创建为填空题型。可以为
cardTemplates
的每个条目提供可选的Name
字段。默认情况下, 卡片名称将是Card 1
,Card 2
等。请求示例:
{ "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}}" } ] } }
结果示例:
{ "result":{ "sortf":0, "did":1, "latexPre":"\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "latexPost":"\\end{document}", "mod":1551462107, "usn":-1, "vers":[ ], "type":0, "css":".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "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
-
返回一个对象,指示与提供的模型名称相连接的每个卡片的模板内容。
请求示例:
{ "action": "modelTemplates", "version": 6, "params": { "modelName": "Basic (and reversed card)" } }
结果示例:
{ "result": { "Card 1": { "Front": "{{Front}}", "Back": "{{FrontSide}}\n\n<hr id=answer>\n\n{{Back}}" }, "Card 2": { "Front": "{{Back}}", "Back": "{{FrontSide}}\n\n<hr id=answer>\n\n{{Front}}" } }, "error": null }
modelStyling
-
获取按名称提供的模型的 CSS 样式。
请求示例:
{ "action": "modelStyling", "version": 6, "params": { "modelName": "Basic (and reversed card)" } }
结果示例:
{ "result": { "css": ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n" }, "error": null }
updateModelTemplates
-
修改现有模型的模板(通过名称指定)。只有指定的卡片和指定的侧面会被修改。 如果请求中不包括现有卡片或侧面,它将保持不变。
请求示例:
{ "action": "updateModelTemplates", "version": 6, "params": { "model": { "name": "Custom", "templates": { "Card 1": { "Front": "{{Question}}?", "Back": "{{Answer}}!" } } } } }
结果示例:
{ "result": null, "error": null }
updateModelStyling
-
修改现有模型的 CSS 样式(通过名称指定)。
请求示例:
{ "action": "updateModelStyling", "version": 6, "params": { "model": { "name": "Custom", "css": "p { color: blue; }" } } }
结果示例:
{ "result": null, "error": null }
findAndReplaceInModels
-
在现有模型中查找并替换字符串(通过模型名称)。通过设置为 true/false 自定义在前面、后面或 CSS 中替换。
请求示例:
{ "action": "findAndReplaceInModels", "version": 6, "params": { "model": { "modelName": "", "findText": "text_to_replace", "replaceText": "replace_with_text", "front": true, "back": true, "css": true } } }
结果示例:
{ "result": 1, "error": null }
modelTemplateRename
-
重命名现有模型中的模板。
请求示例:
{ "action": "modelTemplateRename", "version": 6, "params": { "modelName": "Basic", "oldTemplateName": "Card 1", "newTemplateName": "Card 1 renamed" } }
结果示例:
{ "result": null, "error": null }
modelTemplateReposition
-
重新定位现有模型中的模板。
index
的值从 0 开始。例如,索引0
将模板放在第一个位置,索引2
将模板放在第三个位置。请求示例:
{ "action": "modelTemplateReposition", "version": 6, "params": { "modelName": "Basic", "templateName": "Card 1", "index": 1 } }
结果示例:
{ "result": null, "error": null }
modelTemplateAdd
-
通过名称向现有模型添加模板。如果要更新现有模板,请使用
updateModelTemplates
。请求示例:
{ "action": "modelTemplateAdd", "version": 6, "params": { "modelName": "Basic", "template": { "Name": "Card 3", "Front": "Front html {{Field1}}", "Back": "Back html {{Field2}}" } } }
结果示例:
{ "result": null, "error": null }
modelTemplateRemove
-
从现有模型中移除模板。
请求示例:
{ "action": "modelTemplateRemove", "version": 6, "params": { "modelName": "Basic", "templateName": "Card 1" } }
结果示例:
{ "result": null, "error": null }
modelFieldRename
-
重命名给定模型的字段名称。
请求示例:
{ "action": "modelFieldRename", "version": 6, "params": { "modelName": "Basic", "oldFieldName": "Front", "newFieldName": "FrontRenamed" } }
结果示例:
{ "result": null, "error": null }
modelFieldReposition
-
重新定位给定模型的字段列表中的字段。
index
的值从 0 开始。例如,索引0
将字段放在第一个位置,索引2
将字段放在第三个位置。请求示例:
{ "action": "modelFieldReposition", "version": 6, "params": { "modelName": "Basic", "fieldName": "Back", "index": 0 } }
结果示例:
{ "result": null, "error": null }
modelFieldAdd
-
在给定模型中创建新字段。
可以选择提供
index
值,其工作方式与modelFieldReposition
中的索引完全相同。默认情况下,字段将添加到字段列表的末尾。请求示例:
{ "action": "modelFieldAdd", "version": 6, "params": { "modelName": "Basic", "fieldName": "NewField", "index": 0 } }
结果示例:
{ "result": null, "error": null }
modelFieldRemove
-
删除给定模型中的字段。
请求示例:
{ "action": "modelFieldRemove", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front" } }
结果示例:
{ "result": null, "error": null }
modelFieldSetFont
-
设置给定模型中字段的字体。
请求示例:
{ "action": "modelFieldSetFont", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "font": "Courier" } }
结果示例:
{ "result": null, "error": null }
modelFieldSetFontSize
-
设置给定模型中字段的字体大小。
请求示例:
{ "action": "modelFieldSetFontSize", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "fontSize": 10 } }
结果示例:
{ "result": null, "error": null }
modelFieldSetDescription
-
设置给定模型中字段的描述(当字段为空时在 GUI 编辑器中看到的文本)。
旧版本的 Anki(2.1.49 及以下)没有字段描述。在这种情况下,将返回
false
。请求示例:
{ "action": "modelFieldSetDescription", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "description": "example field description" } }
结果示例:
{ "result": true, "error": null }
笔记操作
addNote
-
使用给定的牌组和模型创建一个笔记,包含提供的字段值和标签。成功时返回创建的笔记的标识符, 失败时返回
null
。Anki-Connect 可以下载音频、视频和图片文件,并将它们嵌入到新创建的笔记中。相应的
audio
、video
和picture
笔记成员是 可选的,可以省略。如果选择包含它们中的任何一个,它们应该包含一个对象或一个对象数组, 带有必填的filename
字段和data
、path
或url
之一。有关这些字段的解释,请参阅storeMediaFile
的文档。 可以选择提供skipHash
字段,以跳过包含与提供的值匹配的 MD5 哈希的文件。 这对于避免保存错误页面和存根文件很有用。fields
成员是一个字段列表,这些字段应该在卡片显示在 Anki 中时播放音频或视频,或显示图片。options
组中的allowDuplicate
成员可以设置为 true 以启用添加重复卡片。 通常不能添加重复卡片,会触发异常。options
中的duplicateScope
成员可用于指定检查重复项的范围。 值为"deck"
将只检查目标牌组中的重复项;任何其他值将检查整个集合。duplicateScopeOptions
对象可用于指定一些附加设置:duplicateScopeOptions.deckName
将指定用于检查重复项的牌组。如果未定义或为null
,将使用目标牌组。duplicateScopeOptions.checkChildren
将更改是否在子牌组中检查重复卡片。默认值为false
。duplicateScopeOptions.checkAllModels
指定是否在所有笔记类型中执行重复检查。默认值为false
。
请求示例:
{ "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" ] }] } } }
结果示例:
{ "result": 1496198395707, "error": null }
addNotes
-
使用给定的牌组和模型创建多个笔记,包含提供的字段值和标签。返回一个数组, 包含创建的笔记的标识符。如有任何错误,将收集并返回所有错误。
-
有关
notes
数组中对象的解释,请参阅addNote
的文档。请求示例:
{ "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" } } ] } }
结果示例:
{ "result":null, "error":"['model was not found: non_existent_model']" }
canAddNotes
-
接受一个对象数组,这些对象定义候选笔记的参数(参见
addNote
),并返回一个布尔值数组, 指示相应索引处的参数是否可用于创建新笔记。请求示例:
{ "action": "canAddNotes", "version": 6, "params": { "notes": [ { "deckName": "Default", "modelName": "Basic", "fields": { "Front": "front content", "Back": "back content" }, "tags": [ "yomichan" ] } ] } }
结果示例:
{ "result": [true], "error": null }
canAddNotesWithErrorDetail
-
接受一个对象数组,这些对象定义候选笔记的参数(参见
addNote
),并返回一个对象数组, 包含canAdd
和error
字段。canAdd
指示相应索引处的参数是否可用于创建新笔记。error
包含无法添加笔记的原因说明。
请求示例:
{ "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" ] } ] } }
结果示例:
{ "result": [ { "canAdd": false, "error": "cannot create note because it is a duplicate" }, { "canAdd": true } ], "error": null }
updateNoteFields
-
修改现有笔记的字段。您还可以包含音频、视频或图片文件,这些文件将添加到笔记中,并带有 可选的
audio
、video
或picture
属性。有关audio
、video
或picture
数组中对象的解释,请参阅addNote
的文档。警告: 您不能在 Anki 浏览器中查看您正在更新的笔记,否则 字段将不会更新。有关更多详细信息,请参阅此问题。
请求示例:
{ "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" ] }] } } }
结果示例:
{ "result": null, "error": null }
updateNote
-
修改现有笔记的字段和/或标签。 换句话说,结合了
updateNoteFields
和updateNoteTags
的功能。 请参阅它们的文档以了解所有属性。可以省略
fields
或tags
属性,而不影响另一个。 因此有效的updateNoteFields
请求也适用于updateNote
。 笔记必须具有fields
属性才能更新可选的音频、视频或图片对象。如果既没有提供
fields
也没有提供tags
,则该方法将失败。 首先更新字段,如果更新标签失败,则不会回滚字段更新。 如果更新字段失败,则不会更新标签。警告 您不能在 Anki 浏览器中查看您正在更新的笔记,否则 字段将不会更新。有关更多详细信息,请参阅此问题。
请求示例:
{ "action": "updateNote", "version": 6, "params": { "note": { "id": 1514547547030, "fields": { "Front": "new front content", "Back": "new back content" }, "tags": ["new", "tags"] } } }
结果示例:
{ "result": null, "error": null }
updateNoteModel
-
更新现有笔记的模型、字段和标签。 这允许您更改笔记的模型,用新内容更新其字段,并设置新标签。
请求示例:
{ "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"] } } }
结果示例:
{ "result": null, "error": null }
updateNoteTags
-
通过笔记 ID 设置笔记的标签。旧标签将被移除。
请求示例:
{ "action": "updateNoteTags", "version": 6, "params": { "note": 1483959289817, "tags": ["european-languages"] } }
结果示例:
{ "result": null, "error": null }
getNoteTags
-
通过笔记 ID 获取笔记的标签。
请求示例:
{ "action": "getNoteTags", "version": 6, "params": { "note": 1483959289817 } }
结果示例:
{ "result": ["european-languages"], "error": null }
addTags
-
通过笔记 ID 向笔记添加标签。
请求示例:
{ "action": "addTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tags": "european-languages" } }
结果示例:
{ "result": null, "error": null }
removeTags
-
通过笔记 ID 从笔记中移除标签。
请求示例:
{ "action": "removeTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tags": "european-languages" } }
结果示例:
{ "result": null, "error": null }
getTags
-
获取当前用户的标签完整列表。
请求示例:
{ "action": "getTags", "version": 6 }
结果示例:
{ "result": ["european-languages", "idioms"], "error": null }
clearUnusedTags
-
清除当前用户笔记中所有未使用的标签。
请求示例:
{ "action": "clearUnusedTags", "version": 6 }
结果示例:
{ "result": null, "error": null }
replaceTags
-
通过笔记 ID 替换笔记中的标签。
请求示例:
{ "action": "replaceTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tag_to_replace": "european-languages", "replace_with_tag": "french-languages" } }
结果示例:
{ "result": null, "error": null }
replaceTagsInAllNotes
-
替换当前用户所有笔记中的标签。
请求示例:
{ "action": "replaceTagsInAllNotes", "version": 6, "params": { "tag_to_replace": "european-languages", "replace_with_tag": "french-languages" } }
结果示例:
{ "result": null, "error": null }
findNotes
-
返回给定查询的笔记 ID 数组。查询语法在此处有文档。
请求示例:
{ "action": "findNotes", "version": 6, "params": { "query": "deck:current" } }
结果示例:
{ "result": [1483959289817, 1483959291695], "error": null }
notesInfo
-
返回一个对象列表,每个笔记 ID 包含笔记字段、标签、笔记类型、修改时间、属于该笔记的卡片以及创建笔记的个人资料。
请求示例(笔记 id):
{ "action": "notesInfo", "version": 6, "params": { "notes": [1502298033753] } }
请求示例(查询):
{ "action": "notesInfo", "version": 6, "params": { "query": "deck:current" } }
结果示例:
{ "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 }
s
notesModTime
-
返回一个对象列表,每个笔记 ID 包含修改时间。
请求示例:
apiReflect
-
获取有关可用 AnkiConnect API 的信息。请求支持以下参数:
scopes
- 要获取反射信息的作用域数组。 目前唯一支持的值是"actions"
。actions
- 可以是null
或者 API 方法名称的数组。 如果值为null
,结果将列出所有可用的 API 动作。 如果值是字符串数组,结果将只包含该数组中存在的动作。
结果将包含使用了哪些作用域及每个作用域的值。 例如,
"actions"
作用域将包含一个"actions"
属性,其中包含支持的动作名称列表。请求示例:
{ "action": "apiReflect", "version": 6, "params": { "scopes": ["actions", "invalidType"], "actions": ["apiReflect", "invalidMethod"] } }
结果示例:
{ "result": { "scopes": ["actions"], "actions": ["apiReflect"] }, "error": null }
sync
-
将本地 Anki 集合与 AnkiWeb 同步。
请求示例:
{ "action": "sync", "version": 6 }
结果示例:
{ "result": null, "error": null }
getProfiles
-
获取个人资料列表。
请求示例:
{ "action": "getProfiles", "version": 6 }
结果示例:
{ "result": ["User 1"], "error": null }
getActiveProfile
-
获取当前活动个人资料。
请求示例:
{ "action": "getActiveProfile", "version": 6 }
结果示例:
{ "result": "User 1", "error": null }
loadProfile
-
选择请求中指定的个人资料。
请求示例:
{ "action": "loadProfile", "version": 6, "params": { "name": "user1" } }
结果示例:
{ "result": true, "error": null }
multi
-
在一个请求中执行多个操作,返回一个数组,其中包含每个操作的响应(按给定顺序)。
请求示例:
{ "action": "multi", "version": 6, "params": { "actions": [ { "action": "deckNames" }, { "action": "deckNames", "version": 6 }, { "action": "invalidAction", "params": {"useless": "param"} }, { "action": "invalidAction", "params": {"useless": "param"}, "version": 6 } ] } }
结果示例:
{ "result": [ ["Default"], {"result": ["Default"], "error": null}, {"result": null, "error": "unsupported action"}, {"result": null, "error": "unsupported action"} ], "error": null }
exportPackage
-
将指定的牌组以
.apkg
格式导出。如果成功则返回true
,否则返回false
。可以指定可选属性includeSched
(默认为false
)以包含卡片的调度数据。请求示例:
{ "action": "exportPackage", "version": 6, "params": { "deck": "Default", "path": "/data/Deck.apkg", "includeSched": true } }
结果示例:
{ "result": true, "error": null }
importPackage
-
将
.apkg
格式的文件导入集合中。如果成功则返回true
,否则返回false
。 注意,文件路径是相对于 Anki 的 collection.media 文件夹,而不是相对于客户端。请求示例:
{ "action": "importPackage", "version": 6, "params": { "path": "/data/Deck.apkg" } }
结果示例:
{ "result": true, "error": null }
reloadCollection
-
告诉 Anki 从数据库重新加载所有数据。
请求示例:
{ "action": "reloadCollection", "version": 6 }
结果示例:
{ "result": null, "error": null }
模型(笔记类型)操作
modelNames
-
获取当前用户的完整模型名称列表。
请求示例:
{ "action": "modelNames", "version": 6 }
结果示例:
{ "result": ["Basic", "Basic (and reversed card)"], "error": null }
modelNamesAndIds
-
获取当前用户的完整模型名称及其对应的 ID 列表。
请求示例:
{ "action": "modelNamesAndIds", "version": 6 }
结果示例:
{ "result": { "Basic": 1483883011648, "Basic (and reversed card)": 1483883011644, "Basic (optional reversed card)": 1483883011631, "Cloze": 1483883011630 }, "error": null }
findModelsById
-
根据提供的模型 ID 从当前用户获取模型列表。
请求示例:
{ "action": "findModelsById", "version": 6, "params": { "modelIds": [1704387367119, 1704387398570] } }
结果示例:
{ "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}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "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}}\n\n<hr id=answer>\n\n{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 1689886528158874152 }, { "name": "Card 2", "ord": 1, "qfmt": "{{Back}}", "afmt": "{{FrontSide}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ], [ 1, "any", [ 1 ] ] ], "originalStockKind": 1 } ], "error": null }
findModelsByName
-
根据提供的模型名称从当前用户获取模型列表。
请求示例:
{ "action": "findModelsByName", "version": 6, "params": { "modelNames": ["Basic", "Basic (and reversed card)"] } }
结果示例:
{ "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}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "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}}\n\n<hr id=answer>\n\n{{Back}}", "bqfmt": "", "bafmt": "", "did": null, "bfont": "", "bsize": 0, "id": 1689886528158874152 }, { "name": "Card 2", "ord": 1, "qfmt": "{{Back}}", "afmt": "{{FrontSide}}\n\n<hr id=answer>\n\n{{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 {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "latexPost": "\\end{document}", "latexsvg": false, "req": [ [ 0, "any", [ 0 ] ], [ 1, "any", [ 1 ] ] ], "originalStockKind": 1 } ], "error": null }
modelFieldNames
-
获取提供的模型名称的完整字段名称列表。
请求示例:
{ "action": "modelFieldNames", "version": 6, "params": { "modelName": "Basic" } }
结果示例:
{ "result": ["Front", "Back"], "error": null }
modelFieldDescriptions
-
获取提供的模型名称的完整字段描述列表(当字段为空时在 GUI 编辑器中显示的文本)。
请求示例:
{ "action": "modelFieldDescriptions", "version": 6, "params": { "modelName": "Basic" } }
结果示例:
{ "result": ["", ""], "error": null }
modelFieldFonts
-
获取完整的字体列表及其字体大小。
请求示例:
{ "action": "modelFieldFonts", "version": 6, "params": { "modelName": "Basic" } }
结果示例:
{ "result": { "Front": { "font": "Arial", "size": 20 }, "Back": { "font": "Arial", "size": 20 } }, "error": null }
modelFieldsOnTemplates
-
返回一个对象,指示给定模型名称的每个卡片模板的问题侧和答案侧的字段。 问题侧在每个数组中首先给出。
请求示例:
{ "action": "modelFieldsOnTemplates", "version": 6, "params": { "modelName": "Basic (and reversed card)" } }
结果示例:
{ "result": { "Card 1": [["Front"], ["Back"]], "Card 2": [["Back"], ["Front"]] }, "error": null }
createModel
-
创建一个新模型以在 Anki 中使用。用户必须提供
modelName
、inOrderFields
和cardTemplates
来 在模型中使用。有可选字段css
和isCloze
。如果未指定,css
将使用默认的 Anki CSS,isCloze
将等于false
。如果isCloze
为true
,则模型将创建为填空题型。可以为
cardTemplates
的每个条目提供可选的Name
字段。默认情况下, 卡片名称将是Card 1
,Card 2
等。请求示例:
{ "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}}" } ] } }
结果示例:
{ "result":{ "sortf":0, "did":1, "latexPre":"\\documentclass[12pt]{article}\n\\special{papersize=3in,5in}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amssymb,amsmath}\n\\pagestyle{empty}\n\\setlength{\\parindent}{0in}\n\\begin{document}\n", "latexPost":"\\end{document}", "mod":1551462107, "usn":-1, "vers":[ ], "type":0, "css":".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "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
-
返回一个对象,指示与提供的模型名称相连接的每个卡片的模板内容。
请求示例:
{ "action": "modelTemplates", "version": 6, "params": { "modelName": "Basic (and reversed card)" } }
结果示例:
{ "result": { "Card 1": { "Front": "{{Front}}", "Back": "{{FrontSide}}\n\n<hr id=answer>\n\n{{Back}}" }, "Card 2": { "Front": "{{Back}}", "Back": "{{FrontSide}}\n\n<hr id=answer>\n\n{{Front}}" } }, "error": null }
modelStyling
-
获取按名称提供的模型的 CSS 样式。
请求示例:
{ "action": "modelStyling", "version": 6, "params": { "modelName": "Basic (and reversed card)" } }
结果示例:
{ "result": { "css": ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n" }, "error": null }
updateModelTemplates
-
修改现有模型的模板(通过名称指定)。只有指定的卡片和指定的侧面会被修改。 如果请求中不包括现有卡片或侧面,它将保持不变。
请求示例:
{ "action": "updateModelTemplates", "version": 6, "params": { "model": { "name": "Custom", "templates": { "Card 1": { "Front": "{{Question}}?", "Back": "{{Answer}}!" } } } } }
结果示例:
{ "result": null, "error": null }
updateModelStyling
-
修改现有模型的 CSS 样式(通过名称指定)。
请求示例:
{ "action": "updateModelStyling", "version": 6, "params": { "model": { "name": "Custom", "css": "p { color: blue; }" } } }
结果示例:
{ "result": null, "error": null }
findAndReplaceInModels
-
在现有模型中查找并替换字符串(通过模型名称)。通过设置为 true/false 自定义在前面、后面或 CSS 中替换。
请求示例:
{ "action": "findAndReplaceInModels", "version": 6, "params": { "model": { "modelName": "", "findText": "text_to_replace", "replaceText": "replace_with_text", "front": true, "back": true, "css": true } } }
结果示例:
{ "result": 1, "error": null }
modelTemplateRename
-
重命名现有模型中的模板。
请求示例:
{ "action": "modelTemplateRename", "version": 6, "params": { "modelName": "Basic", "oldTemplateName": "Card 1", "newTemplateName": "Card 1 renamed" } }
结果示例:
{ "result": null, "error": null }
modelTemplateReposition
-
重新定位现有模型中的模板。
index
的值从 0 开始。例如,索引0
将模板放在第一个位置,索引2
将模板放在第三个位置。请求示例:
{ "action": "modelTemplateReposition", "version": 6, "params": { "modelName": "Basic", "templateName": "Card 1", "index": 1 } }
结果示例:
{ "result": null, "error": null }
modelTemplateAdd
-
通过名称向现有模型添加模板。如果要更新现有模板,请使用
updateModelTemplates
。请求示例:
{ "action": "modelTemplateAdd", "version": 6, "params": { "modelName": "Basic", "template": { "Name": "Card 3", "Front": "Front html {{Field1}}", "Back": "Back html {{Field2}}" } } }
结果示例:
{ "result": null, "error": null }
modelTemplateRemove
-
从现有模型中移除模板。
请求示例:
{ "action": "modelTemplateRemove", "version": 6, "params": { "modelName": "Basic", "templateName": "Card 1" } }
结果示例:
{ "result": null, "error": null }
modelFieldRename
-
重命名给定模型的字段名称。
请求示例:
{ "action": "modelFieldRename", "version": 6, "params": { "modelName": "Basic", "oldFieldName": "Front", "newFieldName": "FrontRenamed" } }
结果示例:
{ "result": null, "error": null }
modelFieldReposition
-
重新定位给定模型的字段列表中的字段。
index
的值从 0 开始。例如,索引0
将字段放在第一个位置,索引2
将字段放在第三个位置。请求示例:
{ "action": "modelFieldReposition", "version": 6, "params": { "modelName": "Basic", "fieldName": "Back", "index": 0 } }
结果示例:
{ "result": null, "error": null }
modelFieldAdd
-
在给定模型中创建新字段。
可以选择提供
index
值,其工作方式与modelFieldReposition
中的索引完全相同。默认情况下,字段将添加到字段列表的末尾。请求示例:
{ "action": "modelFieldAdd", "version": 6, "params": { "modelName": "Basic", "fieldName": "NewField", "index": 0 } }
结果示例:
{ "result": null, "error": null }
modelFieldRemove
-
删除给定模型中的字段。
请求示例:
{ "action": "modelFieldRemove", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front" } }
结果示例:
{ "result": null, "error": null }
modelFieldSetFont
-
设置给定模型中字段的字体。
请求示例:
{ "action": "modelFieldSetFont", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "font": "Courier" } }
结果示例:
{ "result": null, "error": null }
modelFieldSetFontSize
-
设置给定模型中字段的字体大小。
请求示例:
{ "action": "modelFieldSetFontSize", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "fontSize": 10 } }
结果示例:
{ "result": null, "error": null }
modelFieldSetDescription
-
设置给定模型中字段的描述(当字段为空时在 GUI 编辑器中看到的文本)。
旧版本的 Anki(2.1.49 及以下)没有字段描述。在这种情况下,将返回
false
。请求示例:
{ "action": "modelFieldSetDescription", "version": 6, "params": { "modelName": "Basic", "fieldName": "Front", "description": "example field description" } }
结果示例:
{ "result": true, "error": null }
笔记操作
addNote
-
使用给定的牌组和模型创建一个笔记,包含提供的字段值和标签。成功时返回创建的笔记的标识符, 失败时返回
null
。Anki-Connect 可以下载音频、视频和图片文件,并将它们嵌入到新创建的笔记中。相应的
audio
、video
和picture
笔记成员是 可选的,可以省略。如果选择包含它们中的任何一个,它们应该包含一个对象或一个对象数组, 带有必填的filename
字段和data
、path
或url
之一。有关这些字段的解释,请参阅storeMediaFile
的文档。 可以选择提供skipHash
字段,以跳过包含与提供的值匹配的 MD5 哈希的文件。 这对于避免保存错误页面和存根文件很有用。fields
成员是一个字段列表,这些字段应该在卡片显示在 Anki 中时播放音频或视频,或显示图片。options
组中的allowDuplicate
成员可以设置为 true 以启用添加重复卡片。 通常不能添加重复卡片,会触发异常。options
中的duplicateScope
成员可用于指定检查重复项的范围。 值为"deck"
将只检查目标牌组中的重复项;任何其他值将检查整个集合。duplicateScopeOptions
对象可用于指定一些附加设置:duplicateScopeOptions.deckName
将指定用于检查重复项的牌组。如果未定义或为null
,将使用目标牌组。duplicateScopeOptions.checkChildren
将更改是否在子牌组中检查重复卡片。默认值为false
。duplicateScopeOptions.checkAllModels
指定是否在所有笔记类型中执行重复检查。默认值为false
。
请求示例:
{ "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" ] }] } } }
结果示例:
{ "result": 1496198395707, "error": null }
addNotes
-
使用给定的牌组和模型创建多个笔记,包含提供的字段值和标签。返回一个数组, 包含创建的笔记的标识符。如有任何错误,将收集并返回所有错误。
-
有关
notes
数组中对象的解释,请参阅addNote
的文档。请求示例:
{ "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" } } ] } }
结果示例:
{ "result":null, "error":"['model was not found: non_existent_model']" }
canAddNotes
-
接受一个对象数组,这些对象定义候选笔记的参数(参见
addNote
),并返回一个布尔值数组, 指示相应索引处的参数是否可用于创建新笔记。请求示例:
{ "action": "canAddNotes", "version": 6, "params": { "notes": [ { "deckName": "Default", "modelName": "Basic", "fields": { "Front": "front content", "Back": "back content" }, "tags": [ "yomichan" ] } ] } }
结果示例:
{ "result": [true], "error": null }
canAddNotesWithErrorDetail
-
接受一个对象数组,这些对象定义候选笔记的参数(参见
addNote
),并返回一个对象数组, 包含canAdd
和error
字段。canAdd
指示相应索引处的参数是否可用于创建新笔记。error
包含无法添加笔记的原因说明。
请求示例:
{ "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" ] } ] } }
结果示例:
{ "result": [ { "canAdd": false, "error": "cannot create note because it is a duplicate" }, { "canAdd": true } ], "error": null }
updateNoteFields
-
修改现有笔记的字段。您还可以包含音频、视频或图片文件,这些文件将添加到笔记中,并带有 可选的
audio
、video
或picture
属性。有关audio
、video
或picture
数组中对象的解释,请参阅addNote
的文档。警告: 您不能在 Anki 浏览器中查看您正在更新的笔记,否则 字段将不会更新。有关更多详细信息,请参阅此问题。
请求示例:
{ "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" ] }] } } }
结果示例:
{ "result": null, "error": null }
updateNote
-
修改现有笔记的字段和/或标签。 换句话说,结合了
updateNoteFields
和updateNoteTags
的功能。 请参阅它们的文档以了解所有属性。可以省略
fields
或tags
属性,而不影响另一个。 因此有效的updateNoteFields
请求也适用于updateNote
。 笔记必须具有fields
属性才能更新可选的音频、视频或图片对象。如果既没有提供
fields
也没有提供tags
,则该方法将失败。 首先更新字段,如果更新标签失败,则不会回滚字段更新。 如果更新字段失败,则不会更新标签。警告 您不能在 Anki 浏览器中查看您正在更新的笔记,否则 字段将不会更新。有关更多详细信息,请参阅此问题。
请求示例:
{ "action": "updateNote", "version": 6, "params": { "note": { "id": 1514547547030, "fields": { "Front": "new front content", "Back": "new back content" }, "tags": ["new", "tags"] } } }
结果示例:
{ "result": null, "error": null }
updateNoteModel
-
更新现有笔记的模型、字段和标签。 这允许您更改笔记的模型,用新内容更新其字段,并设置新标签。
请求示例:
{ "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"] } } }
结果示例:
{ "result": null, "error": null }
updateNoteTags
-
通过笔记 ID 设置笔记的标签。旧标签将被移除。
请求示例:
{ "action": "updateNoteTags", "version": 6, "params": { "note": 1483959289817, "tags": ["european-languages"] } }
结果示例:
{ "result": null, "error": null }
getNoteTags
-
通过笔记 ID 获取笔记的标签。
请求示例:
{ "action": "getNoteTags", "version": 6, "params": { "note": 1483959289817 } }
结果示例:
{ "result": ["european-languages"], "error": null }
addTags
-
通过笔记 ID 向笔记添加标签。
请求示例:
{ "action": "addTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tags": "european-languages" } }
结果示例:
{ "result": null, "error": null }
removeTags
-
通过笔记 ID 从笔记中移除标签。
请求示例:
{ "action": "removeTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tags": "european-languages" } }
结果示例:
{ "result": null, "error": null }
getTags
-
获取当前用户的标签完整列表。
请求示例:
{ "action": "getTags", "version": 6 }
结果示例:
{ "result": ["european-languages", "idioms"], "error": null }
clearUnusedTags
-
清除当前用户笔记中所有未使用的标签。
请求示例:
{ "action": "clearUnusedTags", "version": 6 }
结果示例:
{ "result": null, "error": null }
replaceTags
-
通过笔记 ID 替换笔记中的标签。
请求示例:
{ "action": "replaceTags", "version": 6, "params": { "notes": [1483959289817, 1483959291695], "tag_to_replace": "european-languages", "replace_with_tag": "french-languages" } }
结果示例:
{ "result": null, "error": null }
replaceTagsInAllNotes
-
替换当前用户所有笔记中的标签。
请求示例:
{ "action": "replaceTagsInAllNotes", "version": 6, "params": { "tag_to_replace": "european-languages", "replace_with_tag": "french-languages" } }
结果示例:
{ "result": null, "error": null }
findNotes
-
返回给定查询的笔记 ID 数组。查询语法在此处有文档。
请求示例:
{ "action": "findNotes", "version": 6, "params": { "query": "deck:current" } }
结果示例:
{ "result": [1483959289817, 1483959291695], "error": null }
notesInfo
-
返回一个对象列表,每个笔记 ID 包含笔记字段、标签、笔记类型、修改时间、属于该笔记的卡片以及创建笔记的个人资料。
请求示例(笔记 id):
{ "action": "notesInfo", "version": 6, "params": { "notes": [1502298033753] } }
请求示例(查询):
{ "action": "notesInfo", "version": 6, "params": { "query": "deck:current" } }
结果示例:
{ "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 包含修改时间。
请求示例: