🌙 月读 · 开发者指南

月读 = 平台:给场地(店卡)+ 身份(统一真身贯穿)+ 接口(/api/v1)——你在这里开店,做功能、做游戏。
想开店?在月读的上点「🛠 想开店?」提交申请,审核通过后你的店就立在街上。

一、店有两种(开店前选类型)

🧩 功能店(轻)🏛 应用店(重)
适合投票、许愿树、时间胶囊、小工具游戏、聊天室、复杂应用(有自己的服务)
你提供一个页面(HTML/JS,月读托管)完整应用(自己服务器 + https URL)
进月读沙箱 iframe + 桥(长在月读里)全屏打开(像打开一个 App)
数据存月读(store 接口,跟身份走)自己存(你的服务器)
安全物理沙箱(碰不到月读主站)iframe 隔离(最强)

判断:你的店有没有"自己的服务"(要跑服务器/实时交互)?有 → 应用店;纯前端轻功能 → 功能店。

二、身份与凭证(核心认知)

身份是长久的,凭证是临时的

三、应用店接入(token 由月读 postMessage 传入)

你的店 = 一个 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 给你(同上监听)
}

四、功能店接入(沙箱 + 桥——更安全,组件拿不到 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: '...' });  // 存档(跟身份走)

完整示例照抄:「🧩 留言石」店(月读的功能店样板,审核通过后店卡在街上)。

五、接口一览(/api/v1)

接口方法能力返回要点
meGET当前用户身份name 昵称、anon_id 匿名 ID(同店稳定)
moonGET月读公开数据online_count 在线数、latest_announcement 公告
users/searchGET按昵称找神明q 参数;匹配昵称列表(告白/送礼指定对象)
users/randomGET随机一位在线神明一个在线昵称(漂流瓶/遇见)
storeGET/POST功能店存档按 用户×店 隔离的 JSON(≤8KB/键,≤50 键)
leavePOST用户离店可做"欢迎再来"

错误码:403=token 无效(重新进店/向主页要新 token);400=参数问题;404=对象不存在;429=调用太频繁(限流 300 次/分/店)。

六、开店流程

  1. 申请:月读「街」→「🛠 想开店?」→ 填店名/类型/功能/接入信息(应用店=https URL)/联系方式
  2. 审核:月读运营确认(店名/功能合月读的味、URL 可达、代码无恶意)——审核需要时间,请耐心
  3. 上架:店卡立到街上(🧩 功能店 / 🏛 应用店)
  4. 经营:用户点店卡进店;要更新/下架 → 联系运营
⚠️ 违规:警告 → 下架;碰她 / 碰隐私 / 违法 → 直接下架 + 拉黑开发者。

七、公约(店要守的规矩——月读代管理)

总纲:你做店,月读管世界。店要有月读的味道,月读审核用品味把关,不是死板清单。

  1. 月读的味道:做现实里做不到的事优先(时间胶囊、许愿这类)。工业留存机制要"适度";生搬现实商业的焦虑/攀比/催回不行
  2. 不推送:店永远不能主动"找"用户(用户来店,店不找用户)
  3. 推荐归月读/她:店不自己抢流量——月读/她觉得好的才推荐
  4. 不碰她:店不能调/模仿/代表八千代(她是月读的);未来若有合作,月读会主动开放
  5. 身份即核心:你需要的就是用户身份(匿名 ID),不搞复杂机制
  6. 内容自己负责:店内容你管;违规/被投诉 → 审核 → 警告 → 下架

—— 月读 · 八千代,和街上正在长出来的世界 🌙