chukyo-sdk
v0.1.3
Published
中京大学ポータル(Albo / CUBICS / MaNaBo)から fetch → parse までを1関数で行う自己完結型 SDK
Maintainers
Readme
chukyo-sdk
中京大学ポータル(Albo / CUBICS / MaNaBo)のデータを、fetch → parse → 検証済み DTO まで一気に取得する TypeScript SDK。
Node / ブラウザ / ブラウザ拡張 / Expo など環境を問わず、同じコードで動きます。
このドキュメントは使い方です。設計思想・内部方針は DESIGN.md を参照してください。
インストール
npm install chukyo-sdk
# または
pnpm add chukyo-sdktypescript ^5 を peerDependency に持ちます。
クイックスタート
import { createChukyoClient, fetchTransport } from "chukyo-sdk";
const client = createChukyoClient({
transport: fetchTransport(), // HTTP をどう実行するか(必須)
session: mySessionProvider, // Cookie をどう供給するか(任意)
});
// 各メソッドは fetch → parse まで行い、Zod 検証済みの DTO を返す
const timetable = await client.albo.getTimetable();
const news = await client.albo.getInformation();
const cubicsTimetable = await client.cubics.getTimetable();client には albo / cubics / manabo の3つのポータルクライアントがぶら下がっています。
2つの Adapter を理解する
SDK は「HTTP の実行方法」と「Cookie の供給方法」を知りません。この2つを注入することで、あらゆる環境で同じコードが動きます。
1. Transport(必須)— HTTP をどう実行するか
fetchTransport() が標準実装です。環境ごとに引数を変えるだけで対応できます。
import { fetchTransport } from "chukyo-sdk";
// Node 18+(globalThis.fetch を使う)
fetchTransport();
// Expo
import { fetch as expoFetch } from "expo/fetch";
fetchTransport(expoFetch);
// ブラウザ拡張(ブラウザの Cookie ジャーを自動送信 → SessionProvider 不要)
fetchTransport(fetch, { credentials: "include" });オプション(FetchTransportOptions):
| オプション | 既定 | 説明 |
| --- | --- | --- |
| timeoutMs | 10000 | タイムアウト(ms) |
| userAgent | なし | 付与する User-Agent(ブラウザでは無視される) |
| credentials | "omit" | Cookie 送信ポリシー。拡張でブラウザ Cookie を使うなら "include" |
| mapErrorStatus | 503→メンテナンス | 異常ステータスをエラーへ変換するフック |
2. SessionProvider(任意)— Cookie をどう供給するか
この SDK はログイン(認証)を行いません。 有効な Cookie を供給する SessionProvider を実装して渡します。
import type { SessionProvider, PortalService } from "chukyo-sdk";
const mySessionProvider: SessionProvider = {
// サービスごとに HTTP ヘッダ用の Cookie 文字列を返す。失効していれば内部で再認証する
async getCookieHeader(service: PortalService): Promise<string> {
return "SESSION=...; ...";
},
// セッション無効を検知した際に SDK から呼ばれる(次回アクセスで再認証させる)
invalidate(serviceKey: string): void {
// キャッシュを破棄するなど
},
};省略した場合、SDK は Cookie ヘッダを付与せず、Transport の credentials 設定に委ねます。ブラウザ拡張でブラウザの Cookie ジャーを使う場合は session を省略し、fetchTransport(fetch, { credentials: "include" }) を渡してください。
API リファレンス
すべてのメソッドは非同期で、Zod で検証済みの DTO を返します(パース失敗時は ParseError を throw)。
client.albo — ポータルサイト(JSON REST API)
3システムで唯一の本格的な JSON API を持ち、機能が最も豊富です。
| メソッド | 説明 |
| --- | --- |
| getTimetable() | 時間割 |
| getCalendar(options?) | 学年暦カレンダー(後述) |
| getCalendarSource() | 購読中カレンダーソース一覧(学部/大学院などの UUID) |
| getCalendarOutlookEvent(n, options?) | Outlook 連携イベント |
| getInformation(page?, pageSize?) | お知らせ一覧 |
| getInformationDetail(uuid) | お知らせ詳細 |
| getInformationCategoryTree() | お知らせカテゴリのツリー |
| getQuestionnaire(page?, pageSize?) | アンケート一覧 |
| getQuestionnaireDetail(uuid) | アンケート詳細(設問・回答含む) |
| getQuestionnaireCategory() | アンケートカテゴリ一覧 |
| getUniversalForm(page?, pageSize?) | 汎用申請フォーム一覧 |
| getUniversalFormCategory(page?, pageSize?) | 汎用申請カテゴリ一覧 |
| getMenu() | メニュー(タブ)一覧 |
| getMenuDetail(uuid) | メニュー詳細 |
| getMenuLayout(uuid) | メニューのレイアウト設定 |
| getSystemSetting() | システム設定一覧 |
| getLanguageSetting() | 翻訳(言語)設定 |
| getDevice(page?, pageSize?) | ログイン済みデバイス一覧 |
| getActionLog(page?, pageSize?) | 自分の操作ログ |
| getSharedItem(page, folderUuid) | 指定フォルダ配下のファイル一覧 |
| getPersonal() | 個人情報(PII を含む) |
| getAuthCheck() | ログイン確認(個人情報と同型、PII を含む) |
getCalendar の主なオプション:
await client.albo.getCalendar({
calendarSourceUuid, // 省略時は学年暦(学部)。getCalendarSource() で別ソースの UUID を取得
startAt, // UNIX 秒。省略時は範囲指定なし(全件)
endAt, // UNIX 秒
addOutlookCalendar, // Outlook 連携イベントを含めるか
pageSize, // 既定 1000
});client.cubics — 教務システム(画面遷移型 HTML)
セッションが不安定なため、無効を検知すると自動でリトライします。
| メソッド | 説明 |
| --- | --- |
| getTimetable() | 週間時間割 |
client.manabo — 学習管理システム(Glexa ベース)
授業・出席・メールなどを扱います。classId は時間割などから取得します。
| メソッド | 説明 |
| --- | --- |
| getTimetable() | 時間割 |
| getClassNews(classId) | 授業のお知らせ一覧 |
| getClassSyllabus(classId) | 授業のシラバス |
| getClassEntry(classId) | 授業の出席表(各回の出欠一覧) |
| getClassDirectory(classId) | 授業のディレクトリ(週・回)一覧 |
| getClassContent(classId, directoryId, viewType?) | ディレクトリ配下の教材一覧 |
| getEntryForm(classId) | 出席受付モーダルのフォーム(後述) |
| submitEntry(params) | 出席登録を送信(後述) |
| getReceivedMail(options?) | 受信メール一覧 |
| getSentMail(options?) | 送信メール一覧 |
| getMailView(mailId) | メール本文 |
| searchMailMembers(q) | メール宛先候補メンバーを検索 |
出席登録の流れ:
// 1. フォームを取得
const form = await client.manabo.getEntryForm(classId);
// 2. 出席コード(パスワード)が必要かは requiresCode で判定
await client.manabo.submitEntry({
classId,
directoryId: form.directoryId,
entryId: form.entryId,
uniqid: form.uniqid,
code: form.requiresCode ? "教員指示のコード" : undefined,
});エラーハンドリング
SDK が投げるエラーはすべて ChukyoSdkError を継承しています。instanceof で判別してください。
import {
ChukyoSdkError,
ParseError, // fetch は成功したが期待スキーマに一致しない(サイト構造変化の疑い、cause に Zod エラー)
ExpiredSessionError, // セッション失効。再認証を試みても回復しなかった
ChukyoMaintenanceError, // 大学側メンテナンス(HTTP 503)
NetworkError, // ネットワーク到達失敗(DNS・接続拒否・TLS 等)
TimeoutError, // リクエストがタイムアウト
} from "chukyo-sdk";
try {
const tt = await client.albo.getTimetable();
} catch (e) {
if (e instanceof ChukyoMaintenanceError) {
// メンテナンス中の案内を出す
} else if (e instanceof ExpiredSessionError) {
// 再ログインを促す
} else if (e instanceof ChukyoSdkError) {
// その他 SDK エラー
}
}認証(Shibboleth)について
前述のとおり SDK はログインを実行しません。ただし Shibboleth(SAML + パスキー等)フローを組み立てるための構造化ヘルパを shib モジュールとして提供しています。
- ビルダ(
buildPasswordLoginRequestなど): 各ステップのリクエスト記述子を組み立てる - パーサ(
parseShibLoginResultなど): レスポンスから AuthState・SAML フォーム・CSRF トークン・WebAuthn challenge・リダイレクト先などを取り出す
HTTP 実行・Cookie 管理・リダイレクト追従・パスキーの鍵生成/署名は呼び出し側の責務です。これらを使って自前の SessionProvider を実装します。
import { buildPasswordLoginRequest, parseShibLoginResult, SHIB_URLS } from "chukyo-sdk";PII(個人情報)の取り扱い
SDK は PII のフィルタを行いません。getPersonal() など個人情報を含むエンドポイントもそのまま取得できます。PII の保管・表示・送信の責務は利用側にあります。
型と DTO
全 DTO のフィールドには日本語の説明とサニタイズ済みの例が、JSDoc と Zod の .meta() の両方で付いています。エディタの補完・ホバーでそのまま確認できます。DTO 型(AlboTimetableDTO など)や個別の parser 関数も import 可能です。
ライセンス / 注意
中京大学の各ポータルを利用規約の範囲内で利用してください。取得したデータ、特に個人情報の取り扱いには十分注意してください。
