Lingara Lingara 문서 학습 가이드 API 라이브러리 앱 만들기 웹 앱
언어: 한국어

Lingara 개발자 문서

이 페이지는 영어에서 번역되었습니다. 두 내용이 다를 경우 영어 페이지가 정확합니다. 영어 페이지 읽기

연결은 단계로 이루어지며, 어떤 단계든 스크립트를 가질 수 있습니다. 단계의 스크립트는 함수의 본문입니다. 스크립트는 두 가지 값을 받습니다. 이 페이지의 API인 lingara, 그리고 단계 자체의 입력 항목에 그 클라이언트와 그 앞에 연결된 단계를 더한 input입니다. input의 타입은 단계의 종류에 따라 달라지므로, 웹훅 단계의 스크립트는 웹훅 단계의 입력 항목을 읽습니다. 스크립트는 아래 헬퍼 중 하나로 만든 객체를 정확히 하나 반환합니다.

스크립트는 시크릿을 절대 보지 못합니다. 단계에 클라이언트가 필요하면 input.client 같은 핸들을 받고, 헬퍼는 그 핸들을 기록합니다. 실제 값은 연결을 적용할 때 Lingara가 채웁니다.

스크립트가 해서는 안 되는 일

스크립트는 여러분의 브라우저에서, 네트워크도 저장소도 없는 워커 안에서 실행됩니다. 다음 제한이 적용됩니다.

  • 1초 안에 끝나야 합니다.
  • 반환하는 문자열은 최대 2048자입니다.
  • 반환하는 목록은 최대 64개 항목입니다.
  • 전체 결과는 최대 16 KiB입니다.

제한을 어기거나, 예외를 던지거나, 헬퍼 하나의 결과가 아닌 것을 반환하는 스크립트는 그 단계를 실패하게 하며, “확인하기”가 어느 단계가 왜 실패했는지 보여 줍니다.

버전 약속

이 페이지의 모든 것은 lingara.v1입니다. v1 안에서 API는 늘어나기만 합니다. 새 헬퍼, 새 선택적 옵션, 새 단계 종류가 나타날 수는 있지만, 지금 사용할 수 있는 것이 삭제되거나 이름이 바뀌거나 범위가 좁아지는 일은 없습니다. 스크립트를 깨뜨릴 변경은 이 버전 옆에 새 버전으로 나오며, v1은 그대로 유지됩니다.

선언

아래의 각 선언은 스크립트 편집기의 자동 완성이 참조하는 것과 같은 파일에서 생성됩니다.

NodeHandle

"n1"처럼 다른 단계의 ID입니다. 의존하는 단계는 자신의 클라이언트를 핸들로 지정합니다.

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 앱에서 앱의 카드가 나타날 수 있는 위치입니다.

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) — 이 웹훅이 속한 클라이언트 단계: 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

웹훅 단계가 만드는 것: 웹훅 엔드포인트.

export interface WebhookSpec {
    readonly kind: 'webhook';
    readonly client: NodeHandle;
    readonly url: string;
    readonly events: readonly string[];
}
  • kind ('webhook') — 항상 "webhook".
  • client (NodeHandle) — 웹훅이 속한 클라이언트 단계.
  • 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

웹훅 단계의 입력: 단계의 입력 항목과 연결된 클라이언트.

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

스크립트가 호출하는 헬퍼입니다. 각 헬퍼는 고정된(frozen) 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 — 클라이언트 단계의 웹훅 엔드포인트.
  • 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;

함께 보기