現在ドキュメントは制作段階にあるため、多くの情報が不完全なものになっています

報告は Discord までお願いします

チュートリアル

このチュートリアルでは Svelte 5 と OMUAPPS を組み合わせて、配信向けのアプリを作ります

おむアプリとして構築する利点

おむアプリは実行者のPC内で実行されているAPIサーバーで完結します

外部のサーバーに送信しない限り実行者のPC内で完結するので、サーバー管理者がデータを管理していないことからプライバシーに強く、そして、どんなに重い処理をしていても、サーバーを契約して借りる必要がないため安定してアプリを提供できます

環境を構築

このチュートリアルではbun をパッケージマネージャーとして使用します

SvelteKit を構築し、アプリを作るのに必要な依存関係をインストールしましょう

1
bunx sv create example

基本的には以下のように選択します

1
┌  Welcome to the Svelte CLI! (v0.9.14)
2
3
◇  Which template would you like?
4
│  SvelteKit minimal
5
6
◇  Add type checking with TypeScript?
7
│  Yes, using TypeScript syntax // OMUAPPSのAPIはTypeScriptを使うことを前提に設計されているため、使うことを推奨します
8
9
◆  Project created
10
11
◇  What would you like to add to your project? (use arrow keys / space bar)
12
│  devtools-json // 好みで入れます
13
14
◆  Successfully setup add-ons
15
16
◇  Which package manager do you want to install dependencies with?
17
│  bun // このチュートリアルではbunを使って構築します

プロジェクトディレクトリに移動します

1
cd example

このチュートリアルで必要になる依存関係をインストールしましょう

1
npm install @omujs/omu @omujs/obs

それぞれ

  • @omujs/omu
    APIクライアント本体
  • @omujs/obs
    OBSを操作するためのインターフェース

の役割になっています

アプリを作る

アプリを導入できる状態にするには、これら4つのページを作成する必要があります

1. アプリ情報

名前や説明、管理画面のURLなどを設定します。 これは認証のために使われるため正確に設定する必要があります

2. アプリ情報配信ページ

サイトがどのアプリを管理しているかを確認するために必要です

3. アプリ操作ページ

管理画面で開かれるアプリのページです

4. アプリ表示ページ

OBS側で開かれるアプリのページです

アプリの出処を確認するところからOBS上の表示まで4つのページ必要ですが、一つずつ作成していきましょう

アプリ情報

その前にIdentifier (識別子) について

識別子はAPIオブジェクトがどのアプリによって所有され、どのような名前かによって一意に識別するために使われる

namespace:path
の構造をした文字列です

  • namespace
    部は逆順ドメイン(
    https://omuapps.github.io/
    の場合io.github.omuappsになります)。
  • path
    部は / 区切りで、英数字と - _ のみ使うことができます。

構造が保証された状態で安全に処理するためにはIdentifierクラスを使うことができます

new Identifier(namespace, ...path)

  • namespace: 逆順ドメイン
  • path: 識別子のパス

例:io.github.omuapps:path/to/id

注意⚠️ URL以外では識別子はすべてドメインが逆順な事にご注意ください

src/routes/tutorial/index.ts
を作成しその中に情報を書き込みます

必要な物をインポートし定数を設定します

1
// src/routes/tutorial/index.ts
2

3
import { dev } from "$app/environment";
4
import { App } from "@omujs/omu";
5

6
export const ORIGIN = dev ? 'http://localhost:5173' : 'https://omuapps.github.io' // 公開先のOrigin (開発時はローカルサーバーのOriginを指定する)
7
export const NAMESPACE = 'io.github.omuapps' // 公開先の逆順ドメイン

アプリ情報は

App
クラスから設定します

new App(id, options)

  • id
    : 識別子となるIDです。
    https://omuapps.github.io/
    に公開する場合、逆順ドメイン名で
    io.github.omuapps/name
    と入力
  • options
    : 名前や説明などアプリの情報を設定

管理画面用とアセット用の2つを設定します

1
// 管理画面用のアプリ情報
2
export const TUTORIAL_APP = new App(`${NAMESPACE}:tutorial`, {
3
    url: `${ORIGIN}/tutorial`, // アプリの開かれるページのURL
4
    metadata: {
5
        locale: "ja", // アプリの推奨言語
6
        name: "チュートリアルアプリ", // アプリの名前
7
        description: "初めてのアプリ", // 一行の説明をつけることを推奨
8
        icon: 'ti-typography' // アイコンのURL、もしくは先端にti-をつけることでTabler Iconsのアイコンを指定することができます
9
    },
10
});
11

12
// 配信画面用のアプリ情報
13
export const TUTORIAL_ASSET_APP = new App(`${NAMESPACE}:tutorial/app`, {
14
    url: `${ORIGIN}/tutorial/asset`, // アセットの開かれるページのURL
15
    parentId: TUTORIAL_APP, // 親アプリを設定
16
    metadata: {
17
        locale: "ja",
18
        name: "チュートリアルアセット",
19
    },
20
});

アプリ情報配信ページ

/_omuapps.json
にアクセスすることでアプリ情報を取得できるようにします

アプリ情報を含んだJSONを配信することで完了しますが、ここではSvelteKitのルーティングを使って自動で配信する仕組みも作ってみましょう

src/routes/_omuapps.json/+server.ts

1
// src/routes/_omuapps.json/+server.ts
2

3
import { AppIndexRegistry } from '@omujs/omu';
4
import { json } from '@sveltejs/kit';
5
import { NAMESPACE, TUTORIAL_APP } from '../tutorial';
6
import type { RequestHandler } from './$types';
7

8
export const prerender = true;
9

10
export const GET: RequestHandler = () => {
11
    return json(
12
        AppIndexRegistry.build({
13
            id: `${NAMESPACE}:apps`,
14
            meta: {
15
                name: 'チュートリアル', // 名前
16
                note: 'チュートリアル用提供元', // 1行の説明
17
            },
18
            apps: [TUTORIAL_APP], // 配信するアプリの配列
19
        }).toJSON()
20
    );
21
};

ここで一度アプリを導入してみましょう

1. 開発者モード

管理画面の「設定」 →「一般」→ 最下部の「開発者モード」を有効にする

2. ホストマッピング

「設定」→「開発者」→「アプリ開発用ホストマッピング」で、変換元にローカルサーバーの

host:port
(例:
localhost:5173
)を入力、変換先に公開先(例:
omuapps.github.io
)を入力して追加

3. 提供元を追加

以下のURLを開いて提供元を追加する

1
http://localhost:26423/index/install?index_url=<_omuapps.jsonのURL>

(例:

http://localhost:26423/index/install?index_url=http://localhost:5173/_omuapps.json
)

4. アプリを追加

「アプリを追加」タブからアプリを追加して、アプリを開きます。404 エラーが表示されれば、アプリの URL 設定までは正しく登録されています(次に中身を実装します)

アプリの中身を書く

操作(管理画面)を作る前に、

src/routes/tutorial/index.ts
にアプリのデータ型とそれを管理するクラスを追加します。 ここではレジストリ API を使い、簡単にデータを保持・共有する事ができます

1
// src/routes/tutorial/index.ts
2
// ...
3

4
import type { Writable } from "svelte/store";
5
import { Omu } from '@omujs/omu';
6

7
type TutorialData = {
8
    text: string
9
};
10

11
export class TutorialApp {
12
    public tutorialData: Writable<TutorialData>;
13

14
    constructor(omu: Omu) {
15
        this.tutorialData = omu.registries.json<TutorialData>('tutorial_data', {
16
            default: {
17
                text: 'Default text'
18
            }
19
        }).compatSvelte();
20
    }
21
}

続いて、

src/routes/tutorial/+page.svelte
に操作ページを作ります

1
<script lang="ts">
2
    import { browser } from "$app/environment";
3
    import { OBSPermissions, OBSPlugin } from "@omujs/obs";
4
    import { Omu, OmuPermissions } from "@omujs/omu";
5
    import { TUTORIAL_APP, TUTORIAL_ASSET_APP, TutorialApp } from ".";
6

7
    // APIを触るのに必要なOmuオブジェクトを生成します
8
    const omu = new Omu(TUTORIAL_APP);
9

10
    // Omuオブジェクトからその他のAPIを使用する事ができます
11
    const obs = OBSPlugin.create(omu);
12

13
    // アプリを初期化して必要な変数を取り出します
14
    const { tutorialData } = new TutorialApp(omu);
15

16
    // 必要な権限を要求します
17
    omu.permissions.require(
18
        OmuPermissions.GENERATE_TOKEN_PERMISSION_ID,
19
        OBSPermissions.OBS_SOURCE_CREATE_PERMISSION_ID,
20
    );
21

22
    // ブラウザのみでAPIに接続します
23
    if (browser) {
24
        omu.start();
25
    }
26

27
    // OBSにソースを追加する関数
28
    async function handleInstall() {
29
        // アセット用のtokenを生成
30
        const session = await omu.sessions.generateToken({
31
            app: TUTORIAL_ASSET_APP,
32
        });
33
        const url = new URL(TUTORIAL_ASSET_APP.url!);
34
        url.searchParams.set(
35
            BrowserSession.PARAM_NAME,
36
            JSON.stringify(session),
37
        );
38
        // OBSにソースを追加
39
        await obs.browserAdd({
40
            name: "チュートリアル表示", // ソース名
41
            url: url.toString(),
42
        });
43
    }
44
</script>
45

46
<h2>文字</h2>
47
<textarea cols="50" rows="5" bind:value={$tutorialData.text}></textarea>
48

49
<button onclick={handleInstall}> OBSに追加 </button>

最後に

src/routes/tutorial/asset/+page.svelte
に表示側ページを作っていきましょう

1
<script lang="ts">
2
    import { Omu, OmuPermissions } from "@omujs/omu";
3
    import { TUTORIAL_ASSET_APP, TutorialApp } from "..";
4
    import { browser } from "$app/environment";
5

6
    const omu = new Omu(TUTORIAL_ASSET_APP);
7
    const { tutorialData } = new TutorialApp(omu);
8

9
    if (browser) {
10
        omu.permissions.require(
11
            OmuPermissions.REGISTRY_PERMISSION_ID,
12
        )
13
        omu.start()
14
    }
15
</script>
16

17
<h1>
18
    {$tutorialData.text}
19
</h1>
20

21
<style>
22
    h1 {
23
        background: #000;
24
        color: #fff;
25
    }
26
</style>

完成

これで管理画面と OBS 間でデータを同期し、同じ文字列を表示する簡単なアプリが完成です

OMUAPPSのアプリはこのチュートリアルで扱ったレジストリを含めて様々なAPIを使用しています。その他のAPIについてはAPI一覧 を参照してください

使用するパッケージマネージャー