Lingara 開發者文件
本頁譯自英文。如兩者有出入,以英文頁面為準。 閱讀英文頁面
連結由步驟組成,任何步驟都可以附帶腳本。步驟的腳本是一個函式的主體。它接收兩個值:lingara,也就是本頁介紹的 API;以及 input,也就是該步驟自己的欄位,連同它的用戶端和在它之前連接的步驟。input 的型別取決於步驟的種類,因此 Webhook 步驟的腳本讀取的是 Webhook 步驟的欄位。腳本只會傳回剛好一個物件,由下面的其中一個輔助函式建立。
腳本永遠看不到密鑰。當步驟需要它的用戶端時,它會取得一個控制代碼,例如 input.client,輔助函式會記錄這個控制代碼。你套用連結時,Lingara 會填入真正的值。
腳本不得做的事
腳本在你自己的瀏覽器中執行,位於一個沒有網路、沒有儲存空間的 worker 中。它受以下限制:
- 它在 1 秒內完成。
- 它傳回的字串最多 2048 個字元。
- 它傳回的清單最多 64 個項目。
- 它的整個結果最多 16 KiB。
違反限制、擲出例外,或傳回的不是某個輔助函式結果的腳本,會讓它的步驟失敗,「開始檢查」會顯示是哪個步驟以及原因。
版本承諾
本頁的一切都屬於 lingara.v1。在 v1 之內,API 只會擴充:可能會出現新的輔助函式、新的選用選項或新的步驟種類,但你今天能使用的任何東西都不會被移除、重新命名或縮減。會破壞腳本的變更會成為與這個版本並存的新版本,而 v1 會維持原樣。
宣告
下面的每個宣告都產生自腳本編輯器進行自動完成時所依據的同一個檔案。
NodeHandle
另一個步驟的 id,例如 "n1"。相依步驟會以控制代碼指定它的用戶端。
export type NodeHandle = string;
Scope
API 用戶端可以擁有的一項權限。由伺服器判斷你的帳戶可以使用哪些。
export type Scope = 'vocab:generate' | 'lesson_plans:read' | 'lesson_plans:write' | 'tutor:converse' | 'usage:read' | 'events:read' | 'events:write' | 'embed:mint' | 'embed:play';
AppSlot
Lingara App 中可以顯示應用程式卡片的位置。
export type AppSlot = 'plans.empty_detail' | 'home.side';
ContextSlice
應用程式可以要求接收的學習者情境的一部分。
export type ContextSlice = 'languages' | 'plan_summary' | 'review_due' | 'tutor_topic';
ClientOptions
lingara.client 的選項。
export interface ClientOptions {
name: string;
scopes: readonly Scope[];
redirectUris?: readonly string[];
}
name(string) — 用戶端的名稱,與開發者工具中顯示的相同。scopes(readonly Scope[]) — 用戶端要求的權限。redirectUris?(readonly string[]) — 授權碼流程可以把學習者送回的位置。伺服器對伺服器的用戶端可省略。
WebhookOptions
lingara.webhook 的選項。
export interface WebhookOptions {
client: NodeHandle;
url: string;
events: readonly string[];
}
client(NodeHandle) — 這個 Webhook 所屬的用戶端步驟:input.client。url(string) — Lingara 傳遞事件的 HTTPS 位址。events(readonly string[]) — 要傳遞的事件類型,例如"lesson_plan.ready"。
ManifestOptions
lingara.manifest 的選項,使用 camelCase;輔助函式會寫出資訊清單的傳輸格式。
export interface ManifestOptions {
name: string | Readonly<Record<string, string>>;
description: string | Readonly<Record<string, string>>;
renderUrl: string;
slots: readonly AppSlot[];
context?: readonly ContextSlice[];
scopes?: readonly Scope[];
tutorNote?: boolean;
defaultLocale?: string;
}
name(string | Readonly<Record<string, string>>) — 應用程式的名稱:一個字串,或每個語言代碼一個字串。description(string | Readonly<Record<string, string>>) — 關於應用程式的一句話:一個字串,或每個語言代碼一個字串。renderUrl(string) — Lingara 要求應用程式卡片的 HTTPS 位址。slots(readonly AppSlot[]) — 應用程式卡片可以出現的位置。context?(readonly ContextSlice[]) — 應用程式接收的情境片段。預設為無。scopes?(readonly Scope[]) — 應用程式向學習者要求的權限。預設為無。tutorNote?(boolean) — 應用程式是否可以為導師留下備註。預設為false。defaultLocale?(string) — 純字串名稱或描述所儲存的語言代碼。預設為"en"。
AppOptions
lingara.app 的選項。
export interface AppOptions {
client: NodeHandle;
manifest: Manifest;
}
client(NodeHandle) — 這個應用程式所屬的用戶端步驟:input.client。manifest(Manifest) — 應用程式的資訊清單,以lingara.manifest建立。
ClientSpec
用戶端步驟建立的內容:一個 API 用戶端。
export interface ClientSpec {
readonly kind: 'client';
readonly name: string;
readonly scopes: readonly Scope[];
readonly redirectUris?: readonly string[];
}
kind('client') — 一律為"client"。name(string) — 用戶端的名稱。scopes(readonly Scope[]) — 用戶端要求的權限。redirectUris?(readonly string[]) — 用戶端的重新導向 URI(如果有的話)。
SecretSpec
密鑰步驟建立的內容:為它的用戶端產生的新密鑰。
export interface SecretSpec {
readonly kind: 'secret';
readonly client: NodeHandle;
}
kind('secret') — 一律為"secret"。client(NodeHandle) — 密鑰所屬的用戶端步驟。
WebhookSpec
Webhook 步驟建立的內容:一個 Webhook 端點。
export interface WebhookSpec {
readonly kind: 'webhook';
readonly client: NodeHandle;
readonly url: string;
readonly events: readonly string[];
}
kind('webhook') — 一律為"webhook"。client(NodeHandle) — Webhook 所屬的用戶端步驟。url(string) — 事件傳遞到的位址。events(readonly string[]) — 傳遞的事件類型。
AppSpec
應用程式步驟建立的內容:一個在 Lingara 中繪製卡片的應用程式。
export interface AppSpec {
readonly kind: 'app';
readonly client: NodeHandle;
readonly manifest: Manifest;
}
kind('app') — 一律為"app"。client(NodeHandle) — 應用程式所屬的用戶端步驟。manifest(Manifest) — 應用程式的資訊清單。
Manifest
傳輸格式的應用程式資訊清單,與伺服器儲存的形式相同。
export interface Manifest {
readonly manifest_version: 1;
readonly default_locale: string;
readonly name: Readonly<Record<string, string>>;
readonly description: Readonly<Record<string, string>>;
readonly render_url: string;
readonly slots: readonly AppSlot[];
readonly context: readonly ContextSlice[];
readonly scopes: readonly Scope[];
readonly tutor_note: boolean;
}
manifest_version(1) — 一律為1。default_locale(string) — 學習者自己的語言沒有項目時顯示的語言。name(Readonly<Record<string, string>>) — 應用程式的名稱,依語言代碼區分。description(Readonly<Record<string, string>>) — 關於應用程式的一句話,依語言代碼區分。render_url(string) — Lingara 要求應用程式卡片的 HTTPS 位址。slots(readonly AppSlot[]) — 應用程式卡片可以出現的位置。context(readonly ContextSlice[]) — 應用程式接收的情境片段。scopes(readonly Scope[]) — 應用程式向學習者要求的權限。tutor_note(boolean) — 應用程式是否可以為導師留下備註。
Spec
輔助函式傳回的任何 spec。腳本只會傳回剛好一個。
export type Spec = ClientSpec | SecretSpec | WebhookSpec | AppSpec;
Upstream
每個直接上游步驟的輸出,依控制代碼索引。
export type Upstream = Readonly<Record<NodeHandle, Spec & {
readonly handle: NodeHandle;
}>>;
ClientInput
用戶端步驟的輸入:它的欄位,也就是 lingara.client 的選項。
export interface ClientInput {
readonly name: string;
readonly scopes: readonly Scope[];
readonly redirectUris?: readonly string[];
readonly upstream: Upstream;
}
name(string) — 用戶端的名稱。scopes(readonly Scope[]) — 用戶端要求的權限。redirectUris?(readonly string[]) — 用戶端的重新導向 URI(如果該步驟有的話)。upstream(Upstream) — 每個直接上游步驟的輸出。
SecretInput
密鑰步驟的輸入。client 是與這個步驟連接的那一個用戶端步驟。
export interface SecretInput {
readonly client: NodeHandle;
readonly upstream: Upstream;
}
client(NodeHandle) — 與這個步驟連接的用戶端步驟。upstream(Upstream) — 每個直接上游步驟的輸出。
WebhookInput
Webhook 步驟的輸入:它的欄位,加上連接的用戶端。
export interface WebhookInput {
readonly client: NodeHandle;
readonly url: string;
readonly events: readonly string[];
readonly upstream: Upstream;
}
client(NodeHandle) — 與這個步驟連接的用戶端步驟。url(string) — 該步驟的欄位所指定的位址。events(readonly string[]) — 該步驟的欄位所指定的事件類型。upstream(Upstream) — 每個直接上游步驟的輸出。
AppInput
應用程式步驟的輸入:它的資訊清單欄位,加上連接的用戶端。
export interface AppInput {
readonly client: NodeHandle;
readonly manifest: ManifestOptions;
readonly upstream: Upstream;
}
client(NodeHandle) — 與這個步驟連接的用戶端步驟。manifest(ManifestOptions) — 該步驟的欄位所描述的資訊清單。upstream(Upstream) — 每個直接上游步驟的輸出。
InputFor
指定種類的步驟腳本所接收的輸入。
export type InputFor<K extends Spec['kind']> = K extends 'client' ? ClientInput : K extends 'secret' ? SecretInput : K extends 'webhook' ? WebhookInput : AppInput;
LingaraV1
腳本呼叫的輔助函式。每個都會傳回一個凍結的 spec,型別錯誤的選項會擲出一個指出該選項的 TypeError。
export interface LingaraV1 {
readonly version: 'v1';
client(options: ClientOptions): ClientSpec;
secret(client: NodeHandle): SecretSpec;
webhook(options: WebhookOptions): WebhookSpec;
app(options: AppOptions): AppSpec;
manifest(options: ManifestOptions): Manifest;
}
version('v1') — 一律為"v1"。client(options: ClientOptions): ClientSpec— 一個 API 用戶端。secret(client: NodeHandle): SecretSpec— 為用戶端步驟產生的新密鑰。webhook(options: WebhookOptions): WebhookSpec— 用戶端步驟上的 Webhook 端點。app(options: AppOptions): AppSpec— 用戶端步驟上的應用程式。manifest(options: ManifestOptions): Manifest— 傳輸格式的資訊清單,並填入 v1 保留為選用的那些選項。
return lingara.client({ name: input.name, scopes: input.scopes })
return lingara.secret(input.client)
return lingara.webhook({ client: input.client, url: input.url, events: input.events })
return lingara.app({ client: input.client, manifest: lingara.manifest(input.manifest) })
NodeScript
步驟的腳本就是這個函式的主體:return lingara.webhook({ client: input.client, url: input.url, events: input.events })。
export type NodeScript<K extends Spec['kind']> = (lingara: LingaraV1, input: InputFor<K>) => Spec;