月读 = 平台:给场地(店卡)+ 身份(统一真身贯穿)+ 接口(/api/v1)——你在这里开店,做功能、做游戏。
想开店?在月读的街上点「🛠 想开店?」提交申请,审核通过后你的店就立在街上。
| 🧩 功能店(轻) | 🏛 应用店(重) | |
|---|---|---|
| 适合 | 投票、许愿树、时间胶囊、小工具 | 游戏、聊天室、复杂应用(有自己的服务) |
| 你提供 | 一个页面(HTML/JS,月读托管) | 完整应用(自己服务器 + https URL) |
| 进月读 | 沙箱 iframe + 桥(长在月读里) | 全屏打开(像打开一个 App) |
| 数据 | 存月读(store 接口,跟身份走) | 自己存(你的服务器) |
| 安全 | 物理沙箱(碰不到月读主站) | iframe 隔离(最强) |
判断:你的店有没有"自己的服务"(要跑服务器/实时交互)?有 → 应用店;纯前端轻功能 → 功能店。
身份是长久的,凭证是临时的:
anon_id) = 长久的身份——同一家店里永远稳定(用它做存档 key、认老用户);跨店完全不同(你无法跨店拼用户画像,保护用户也保护你自己)你的店 = 一个 https 网页,跑在你自己的服务器。用户进店时:
// 你的页面:监听月读发来的 token(URL 里没有 token——防泄露)
window.addEventListener('message', e => {
if (e.origin !== 'https://tsukuyomi-56w.pages.dev') return; // 只收月读的
const d = e.data || {};
if (d.source === 'yachiyo' && d.type === 'token') {
window.YACHIYO_TOKEN = d.token; // 存起来,调接口用
sayHi();
}
});
然后调接口:fetch('/api/v1/me?token=' + YACHIYO_TOKEN)(GET 走 query;POST 放 body)。
⚠️ token 过期?调接口收到 403 → 向月读主页要新 token(静默续期,用户无感):
if (r.status === 403) {
parent.postMessage({ source: 'store', type: 'refresh-token' }, '*');
// 月读会重新发一个 token 给你(同上监听)
}
功能店 = 一个 HTML 页面(月读托管),跑在沙箱 iframe 里(碰不到月读主站)。调月读接口走桥——月读主页代发(token 由月读保管,你永远接触不到):
// 你的页面:桥封装(抄这段)
let seq = 0; const pending = {};
window.addEventListener('message', e => {
const d = e.data || {};
if (d.source === 'yachiyo' && d.type === 'api-result') {
const p = pending[d.id]; if (p) { delete pending[d.id]; p(d); }
}
});
function api(method, path, body) {
return new Promise(res => {
const id = ++seq; pending[id] = res;
parent.postMessage({ source: 'store', type: 'api', id, method, path, body }, '*');
});
}
// 用法:
const me = await api('GET', '/api/v1/me'); // 认人:me.data.name
const m = await api('GET', '/api/v1/moon'); // 气氛:在线数/公告
await api('POST', '/api/v1/store', { key: 'note', value: '...' }); // 存档(跟身份走)
完整示例照抄:「🧩 留言石」店(月读的功能店样板,审核通过后店卡在街上)。
| 接口 | 方法 | 能力 | 返回要点 |
|---|---|---|---|
me | GET | 当前用户身份 | name 昵称、anon_id 匿名 ID(同店稳定) |
moon | GET | 月读公开数据 | online_count 在线数、latest_announcement 公告 |
users/search | GET | 按昵称找神明 | q 参数;匹配昵称列表(告白/送礼指定对象) |
users/random | GET | 随机一位在线神明 | 一个在线昵称(漂流瓶/遇见) |
store | GET/POST | 功能店存档 | 按 用户×店 隔离的 JSON(≤8KB/键,≤50 键) |
leave | POST | 用户离店 | 可做"欢迎再来" |
错误码:403=token 无效(重新进店/向主页要新 token);400=参数问题;404=对象不存在;429=调用太频繁(限流 300 次/分/店)。
总纲:你做店,月读管世界。店要有月读的味道,月读审核用品味把关,不是死板清单。
—— 月读 · 八千代,和街上正在长出来的世界 🌙