Ugrás a fő tartalomhoz

API példák

Ezen az oldalon másolhatja a megfelelő kérésformát az egyes bővítményfolyamatokhoz.

  • Az iframe bridge példák postMessage műveleteket használnak, mint például a session.get, state.get és files.get.
  • A privilegizált példák a saját kiterjesztési háttérrendszeredet használják a Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY és a x-chastify-main-token paraméterekkel.
  • Soha ne küldj fejlesztői API-kulcsot iframe-be vagy böngészőkódba.
információ

Az iframe híd felhasználói felület bootstrap és alacsony kockázatú munkamenet-műveletekhez használható. Használja kontextus olvasására, a bővítmény tulajdonában lévő állapot tárolására és fájl URL-címek feloldására.

figyelem

A böngésző iframe kódját felhasználó vezérli. Ne használjon iframe bridge kéréseket idő alkalmazására/eltávolítására, feladatok végrehajtására, feloldási blokkolók feloldására, futásidejű fájlok feltöltésére/törlésére, értesítések küldésére, naplók írására vagy eszközök vezérlésére.

Kérés és válasz formátuma

A biztonságos iframe hídműveletek ebben a hídkérelem-borítékban kerülnek elküldésre:

{
"type": "chastify:ext:req", // required
"v": 1, // protocol version
"id": "req-123", // your unique request id
"nonce": "from-iframe-hash",
"action": "session.get",
"payload": {}
}

És megkapod:

{
"type": "chastify:ext:resp",
"v": 1,
"id": "req-123", // same id you sent
"ok": true,
"data": {}
}

Ha a ok értéke false, akkor jelölje be a error.code és a error.message kódot.

A csak háttérben futó példák a szerveredről érkező normál HTTPS kéréseket használják. Nem iframe hídon keresztül küldik őket.

Munkamenet és kontextus

session.get

Ezt használd elsőként szinte minden bővítményfolyamatban.

Mit csinál:

  • Ellenőrzi, hogy a hídkapcsolat működik-e.
  • Visszaadja a munkamenet kontextusát (zárolási állapot, szerepkör, bővítmény konfigurációja, képességek).
  • Visszaadja az eszköz képességeire vonatkozó információkat, amelyeket a felhasználói felület használhat, mielőtt a háttérrendszert a device.command meghívására kérné.

Mire használják:

  • A felhasználói felület újraindítása.
  • Funkciók engedélyezése/letiltása szerepkör és jogosultságok alapján.
  • A támogatott eszközparancsok ellenőrzése az eszközvezérlők megjelenítése előtt.

Példa a művelet hasznos adatára:

{
"action": "session.get",
"payload": {}
}

Példa session.get válaszrészletre (futásidejű zárolási adatok):

{
"ok": true,
"data": {
"lockData": {
"frozen": false,
"unlockable": false,
"trusted": true,
"taskAssigned": true,
"timeLockedSeconds": 1420,
"timeRemainingSeconds": 27800,
"maxTimeRemainingSeconds": 86400,
"taskPoints": 12,
"taskPointsRequired": 20,
"lockTitle": "Weekend Challenge",
"wearerUsername": "alice",
"keyholderUsername": "kh_bob",
"wearerLastSeenTimestamp": 1739640505123,
"keyholderLastSeenTimestamp": null
}
}
}

Adatvédelmi megjegyzések:

  • A wearerLastSeenTimestamp / keyholderLastSeenTimestamp értékek csak akkor adódnak vissza, ha a felhasználó rendelkezik showOnlineStatus !== false kóddal.
  • Ha az online állapot láthatósága le van tiltva, ezek a mezők null formátumúak.

Háttérbeli bővítményfolyamatok

Ezek a példák a biztonságos gyártási mintát mutatják:

  1. Az iframe a hash hasznos adatból olvassa be a mainToken és sessionId értékeket.
  2. Az iframe elküldi őket a backend rendszerednek.
  3. A backend rendszered ellenőrzi a saját játékod/feladatod/üzleted állapotát.
  4. A háttérrendszered egy alkalmazás-hatókörű fejlesztői API-kulccsal és a x-chastify-main-token-val hívja meg a ZXQTER0ZXQ függvényt.

Ne használd a sessionId kulcsot önmagában hitelesítéshez. A mainToken kulcsot kezeld böngésző által látható indítási kontextusként, a fejlesztői API kulcsodat pedig csak a háttérben használható titkos kulcsként.

vigyázat

A backendnek érvényesítenie kell a saját játék/feladat állapotát a Chastify meghívása előtt. A mainToken és sessionId átadása az iframe-ből csak a megnyitott bővítmény munkamenetet azonosítja; nem bizonyítja, hogy a felhasználó befejezett egy kihívást.

Munkamenet-kontextus biztonságos lekérése

Az iframe használhatja a session.get biztonságos hidat a felhasználói felület indításához. Ha a backendnek ugyanarra a kontextusra van szüksége egy privilegizált művelet alkalmazása előtt, akkor mindkét hitelesítő adattal kérje le azt a backendről.

Iframe:

const hash = JSON.parse(decodeURIComponent(window.location.hash.slice(1)));

await fetch("/api/my-extension/session-context", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
mainToken: hash.mainToken,
sessionId: hash.sessionId
})
});

A háttérrendszered:

app.post("/api/my-extension/session-context", async (req, res) => {
const { mainToken, sessionId } = req.body;

const response = await fetch(
`https://chastify.net/api/extensions/sessions/${encodeURIComponent(sessionId)}`,
{
headers: {
Authorization: `Bearer ${process.env.CHASTIFY_APP_DEVELOPER_KEY}`,
"x-chastify-main-token": mainToken
}
}
);

if (!response.ok) {
return res.status(response.status).json(await response.json());
}

const context = await response.json();

res.json({
role: context.role,
config: context.extensionConfig,
lockData: context.lockData
});
});

Idő alkalmazása egy bővítmény háttérrendszeréből

A böngésző kérheti a háttérrendszertől, hogy jutalmat vagy büntetést alkalmazzon, de a böngészőnek nem szabad eldöntenie, hogy a művelet érvényes-e. Először ellenőrizze a műveletet a szerveroldalon.

app.post("/api/my-extension/apply-reward", async (req, res) => {
const { mainToken, sessionId, runId } = req.body;

const run = await db.gameRuns.findUnique({ where: { id: runId } });
if (!run || run.sessionId !== sessionId || !run.serverVerifiedWin) {
return res.status(403).json({ error: "game_not_verified" });
}

const response = await fetch(
`https://chastify.net/api/extensions/sessions/${encodeURIComponent(sessionId)}/action`,
{
method: "POST",
headers: {
"content-type": "application/json",
Authorization: `Bearer ${process.env.CHASTIFY_APP_DEVELOPER_KEY}`,
"x-chastify-main-token": mainToken
},
body: JSON.stringify({
name: "remove_time",
params: 300
})
}
);

if (!response.ok) {
return res.status(response.status).json(await response.json());
}

res.json(await response.json());
});

Használd a add_time kódot büntetésekhez, a remove_time kódot pedig jutalmakhoz.

Szerver által ellenőrzött játékbefejezés

Az olyan játékoknál, mint a Simon Says, ne bízz meg a kliens által jelentett győzelmekben. Hozd létre a futtatást szerveroldalon, tárold el a várt szekvenciát vagy annak egy hash-ét, és ellenőrizd a beküldött bemenetet a Chastify meghívása előtt.

Egy böngésző által látható memóriajáték nem tudja bizonyítani, hogy egy ember becsületesen játszott, mivel a böngészőnek meg kell kapnia a szekvenciát a játék megjelenítéséhez. A szerverellenőrzés továbbra is megakadályozza a hamisított Chastify mutációkat, és lehetővé teszi a háttérrendszer számára, hogy a jutalmak vagy büntetések alkalmazása előtt érvényesítse a futási azonosítókat, a lejáratot, a nehézséget, a ritmust, a pontozást és az újrajátszás elleni védelmet.

app.post("/api/simon/runs", async (req, res) => {
const { mainToken, sessionId } = req.body;
await verifySessionLaunch({ mainToken, sessionId });

const sequence = createSimonSequence();

const run = await db.simonRuns.create({
data: {
sessionId,
sequenceHash: hashSequence(sequence),
expiresAt: new Date(Date.now() + 5 * 60_000)
}
});

res.json({
runId: run.id,
sequence
});
});

app.post("/api/simon/runs/:runId/complete", async (req, res) => {
const { mainToken, sessionId, input } = req.body;
await verifySessionLaunch({ mainToken, sessionId });

const run = await db.simonRuns.findUnique({ where: { id: req.params.runId } });

if (!run || run.sessionId !== sessionId || run.expiresAt < new Date()) {
return res.status(403).json({ error: "run_invalid" });
}

const won = hashSequence(input) === run.sequenceHash;
await db.simonRuns.update({
where: { id: run.id },
data: { completedAt: new Date(), serverVerifiedWin: won }
});

if (won) {
await fetch(`https://chastify.net/api/extensions/sessions/${encodeURIComponent(sessionId)}/requirements/progress`, {
method: "POST",
headers: {
"content-type": "application/json",
Authorization: `Bearer ${process.env.CHASTIFY_APP_DEVELOPER_KEY}`,
"x-chastify-main-token": mainToken
},
body: JSON.stringify({
key: "simon_says_wins",
amount: 1
})
});
}

res.json({ won });
});

A pontos futási tárolási séma a tiéd. A verifySessionLaunch függvénynek meg kell hívnia a Chastify függvényt az alkalmazás hatókörébe tartozó fejlesztői API-kulccsal és a x-chastify-main-token függvényt, mielőtt megbízna a sessionId függvényben. A fontos szabály, hogy a Chastify mutációk csak azután történnek, hogy a háttérrendszered ellenőrzi az indítást és az eredményt.

Ütemezett követelmények

A backend kezeli az ütemterveket, a ritmusellenőrzéseket és a bizonyításérvényesítést. A Chastify függvényt csak megbízható előrehaladás rögzítéséhez vagy a feloldási blokkolók frissítéséhez használja, miután a backend úgy dönt, hogy a követelmény teljesült.

async function recordDailyRequirementProgress({ sessionId, mainToken, userId }) {
const completed = await db.dailyCheckins.exists({
where: {
userId,
day: new Date().toISOString().slice(0, 10),
verified: true
}
});

if (!completed) return;

await fetch(`https://chastify.net/api/extensions/sessions/${encodeURIComponent(sessionId)}/requirements/progress`, {
method: "POST",
headers: {
"content-type": "application/json",
Authorization: `Bearer ${process.env.CHASTIFY_APP_DEVELOPER_KEY}`,
"x-chastify-main-token": mainToken
},
body: JSON.stringify({
key: "daily_checkin",
amount: 1
})
});
}

A jelenlegi telepített bővítmény munkamenet API-k érvényes iframe indítási tokent igényelnek a x-chastify-main-token kódban; az indítási tokenek jelenleg 10 óra elteltével lejárnak. Az ütemezett feladatok esetében, amelyek a token lejárta után futnak, tárolja el saját függőben lévő bizonyítékát, és küldje be a folyamatot a következő érvényes bővítményindításkor, vagy használjon egy felügyelet nélküli háttérmunkához tervezett, saját féltől származó/beépített szerverfolyamatot.

figyelem

Ne kezelje az ütemezett feladatokat megbízhatóként csak azért, mert a szerverén futnak. A feladatnak továbbra is szerveroldali ellenőrzésre, ütemellenőrzésre, visszajátszás elleni védelemre és érvényes Chastify jogosultságútvonalra van szüksége a követelmény előrehaladásának rögzítése előtt.

Értesítések

notifications.custom

Használd ezt a bővítményed háttérrendszeréből, hogy egyéni bővítményértesítést küldj a viselőnek, a kulcsbirtokosnak vagy mindkettőnek.

Végpont:

POST /api/extensions/sessions/:sessionId/notifications/custom
Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH

Példa törzs:

{
"title": "Extension Reminder",
"message": "Your next challenge is ready.",
"showPageOverlay": false,
"target": "both"
}

Megjegyzések:

  • A showPageOverlay alapértelmezett értéke false.
  • A target alapértelmezett értéke wearer.
  • Az API létrehozza a extension_app_message típusú értesítést.

Bővítmény állapota

A bővítmény állapota a bővítmény tulajdonában lévő JSON-adatok az aktuális zárolási munkamenethez. Az állapotírás csak a háttérben történik, és alkalmazásszintű fejlesztői API-kulcsot, valamint a mainToken munkamenetet igénylik. Az iframe-ek a state.get paraméterrel olvashatják az állapotot, de közvetlenül nem írhatják az állapotot.

state.put

Mit csinál:

  • A teljes állapotobjektumot lecseréli az új data objektumra.
  • Háttérbeli hitelesítő adatokat igényel.

Mikor kell használni:

  • Kezdeti mentés.
  • Teljes felülírás, ha már megvan a teljesen új állapot.

Példa:

curl -X PUT "https://chastify.net/api/extensions/sessions/$SESSION_ID/state" \
-H "Authorization: Bearer $DEVELOPER_KEY" \
-H "x-chastify-main-token: $MAIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"counter": 1,
"notes": "first test"
}
}'

Terepi megjegyzések:

  • payload.data: bármely érvényes JSON érték/objektum, amelyre a bővítménynek szüksége van.
  • Avoid Mongo-unsafe key names ($ prefix or keys containing .).
  • Az állapot munkamenet-alapú és méretkorlátozást a bővítményalkalmazás stateMaxBytes kódja határoz meg, alapértelmezés szerint 64 KiB-ra állítva.
  • A fájlazonosítókat állapot szerint tárold, ne bináris fájlokban vagy aláírt URL-ekben. A files.get kóddal frissítsd az aláírt URL-eket a média renderelése előtt.

state.patch

Mit csinál:

  • JSON egyesítési javítást alkalmaz a meglévő állapotra.
  • Csak a megváltoztatott kulcsokat kell elküldeni.
  • Háttérbeli hitelesítő adatokat igényel.

Mikor kell használni:

  • Felhasználói interakciókból származó fokozatos frissítések.
  • Egy mező frissítése az összes újraküldése nélkül.

Példa:

curl -X PATCH "https://chastify.net/api/extensions/sessions/$SESSION_ID/state" \
-H "Authorization: Bearer $DEVELOPER_KEY" \
-H "x-chastify-main-token: $MAIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"counter": 2
}
}'

state.get

Mit csinál:

  • Beolvassa a kiterjesztés aktuális állapotát.
  • Elérhető az iframe bridge-en keresztül.

Mikor kell használni:

  • iframe betöltéskor.
  • Írás után, ha újra szeretné szinkronizálni a helyi felhasználói felületet.

Példa:

{
"action": "state.get",
"payload": {}
}

Fájltárolás

Használd a files.* kódot bináris adathordozókhoz, például kirakós képekhez, generált előnézetekhez vagy kihívásfotókhoz. A visszaadott file.id kódot tárold háttérben írt állapotban vagy a saját adatbázisodban. Rendereld a file.signedUrl kóddal, és frissítsd az aláírt URL-t a files.get kóddal, amikor az iframe később betöltődik.

A zárolás/munkamenet létrehozása előtt futó beállítási képernyők szakaszos feltöltéseket használnak a files.upload helyett. A szakaszos fájlok ideiglenesek, amíg a bővítménykonfigurációt provider: "chastify_storage" és fileId hivatkozással nem mentik. A Chastify automatikusan igényli ezeket a fájlokat a zárolás/sablon mentésekor; nincs külön böngészőoldali igénylési hívás.

Állapot/fájl felosztási példa a backendből:

curl -X PATCH "https://chastify.net/api/extensions/sessions/$SESSION_ID/state" \
-H "Authorization: Bearer $DEVELOPER_KEY" \
-H "x-chastify-main-token: $MAIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"puzzleImageFileId": "file_record_id"
}
}'

Később oldja fel a képet a megjelenítés előtt:

const state = await bridge.request("state.get", {});
const file = await bridge.request("files.get", {
fileId: state.data.puzzleImageFileId
});
image.src = file.file.signedUrl;

files.capabilities

Ezt ellenőrizd a feltöltési vezérlők megjelenítése előtt.

{
"action": "files.capabilities",
"payload": {}
}

Futásidejű files.upload

A futásidejű fájlfeltöltés mutálja a bővítmény munkamenet-adatait, tehát nem iframe bridge parancs. Tölts fel futásidejű fájlokat a háttérrendszeredről egy alkalmazás-hatókörű fejlesztői API-kulccsal és a x-chastify-main-token paraméterrel.

files.get

Frissítsen egy aláírt R2 URL-t egy stabil fájlazonosítóból.

{
"action": "files.get",
"payload": {
"fileId": "file_record_id"
}
}

files.list

{
"action": "files.list",
"payload": {}
}

A files.delete futásidejű változata is csak háttérrendszeren érhető el, ugyanazon okból kifolyólag, mint a feltöltés.

Zárolási műveletek

Idő hozzáadása

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Hozzáad vagy eltávolít időt a zárolási visszaszámlálásból a deltaSeconds-tól függően.

Mikor kell használni:

  • Jutalom/büntetés gombok.
  • A játék kimenetele (a győzelem időt ad, a vereség időt vesz).

Példa:

{
"name": "add_time",
"params": 300 // +300 sec = +5 minutes
}

Terepi megjegyzések:

  • A pozitív érték időt ad hozzá.
  • A negatív érték eltávolítja az időt (ha a szerver szabályai megengedik).

Fagy

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Egy bizonyos ideig befagyasztja a zárolás folyamatát.

Mikor kell használni:

  • Lehűlési mechanikák.
  • Jutalmazási ellenőrzőpontok.

Példa:

{
"name": "freeze",
"params": { "durationSeconds": 120 }
}

durationSeconds nélkül is hívhatod:

{
"name": "freeze",
"params": {}
}

Terepi megjegyzések:

  • A durationSeconds paraméter megadása opcionális.
  • Ha kihagyjuk, az aktuális alapértelmezett érték 3600 másodperc (1 óra).
  • Az elfogadott tartomány 60 és 86400 másodperc között van.

Kiolvaszt

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Befejezi az aktív befagyasztást, és visszatér a normál időzítő viselkedéshez.

Mikor kell használni:

  • Manuális felülbírálás a bővítmény munkafolyamataiban.
  • „Rögzítés visszavonása” vezérlők.

Példa:

{
"name": "unfreeze",
"params": {}
}

Pellengér

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Elindítja a pellengéridőszakot az aktív zárolási munkamenethez.

Mikor kell használni:

  • Büntetőmechanika sikertelen feladatok/kihívások után.
  • Eszkalációs folyamatok, amelyek ideiglenesen korlátozzák a zárak közötti interakciót.

Példa:

{
"name": "pillory",
"params": {
"durationSeconds": 600,
"reason": "Missed scheduled check-in"
}
}

Terepi megjegyzések:

  • A name kódnak pillory-nak kell lennie.
  • A params.durationSeconds megadása kötelező.
  • A params.reason paraméter megadása opcionális.
  • Engedélyezni kell a pillory-t a munkamenet konfigurációjában.

Vége a pellengérnek

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Azonnal befejezi az aktuális aktív pellengérülést.

Példa:

{
"name": "pillory.end",
"params": {}
}

Terepi megjegyzések:

  • A name kódnak pillory.end-nak kell lennie.
  • pillory_not_active kóddal hibát jelez, ha a zár jelenleg nincs pellengérben.

Feladat hozzárendelése

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Létrehoz egy aktív feladatot a viselő számára a kiterjesztési logikából.
  • Felülbírálhatja a már megnyitott feladat futtatását.

Példa:

{
"name": "task.assign",
"params": {
"taskText": "Clean your room",
"points": 10,
"verificationRequired": true,
"durationSeconds": 1800
}
}

Terepi megjegyzések:

  • A taskText megadása kötelező.
  • A points opcionális és szerveroldalilag rögzített.
  • A verificationRequired alapértelmezett értéke false.
  • A durationSeconds opcionális (a 0 azt jelenti, hogy nincs szükség időzítőre).
  • Engedélyezett Feladatok modult igényel a záron.

Feladatidőzítő indítása

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Elindítja vagy újraindítja a visszaszámláló ablakot az aktuálisan aktív időzített feladathoz.

Példa:

{
"name": "task.start_timer",
"params": {}
}

Terepi megjegyzések:

  • Aktív feladat futtatását igényli.
  • Hibát jelez, ha az aktuális feladathoz nincs konfigurálva időtartam.

Feladat elvégzése

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Befejezettként vagy sikertelenként jelöli az aktív feladat futtatását.

Példa (siker):

{
"name": "task.complete",
"params": {
"successful": true
}
}

Példa (sikertelen):

{
"name": "task.complete",
"params": {
"successful": false,
"reason": "Did not finish in time"
}
}

Ideiglenes nyitás indítása

Végpont: POST /api/extensions/sessions/:sessionId/action

Mit csinál:

  • Elindít egy ideiglenes higiéniai nyitási ablakot a bővítménylogikából.

Példa:

{
"name": "hygienic_unlock.start",
"params": {
"durationSeconds": 900
}
}

Terepi megjegyzések:

  • A záron engedélyezni kell a higiénikus nyitást.
  • Sikertelen, ha már folyamatban van egy higiéniai nyitás.
  • A durationSeconds opcionális; hiányában a zárolás alapértelmezett értéke érvényes.

Metaadatok és kezdőlapon végrehajtott műveletek

metadata.patch

Mit csinál:

  • A zárolási oldal felhasználói felülete által használt bővítmény metaadatokat tárolja.
  • Támogatja a unlockBlockers és homeActions kódokat.
  • Támogatja a homeActions[].intent mélyhivatkozási viselkedését a bővítmény megnyílásakor.

Mikor kell használni:

  • A bővítményed által birtokolt zárolási munkamenet-feloldási feltételek kikényszerítése.
  • Adj hozzá gyors műveleteket a zárolási oldalon, amelyek szándékosan nyitják meg a bővítményt.
  • Irányítsa a felhasználókat közvetlenül egy adott képernyőre/munkafolyamatra, amikor egy kezdőlap műveletre kattintanak.

Végpont:

PATCH /api/extensions/sessions/:sessionId/metadata
Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH

Példa törzs:

{
"unlockBlockers": ["Finish extension task"],
"homeActions": [
{
"slug": "tasks",
"title": "Tasks",
"description": "Open tasks panel",
"intent": {
"type": "open_panel",
"title": "Tasks",
"message": "Open tasks panel",
"payload": {
"panel": "regular-actions"
}
}
}
]
}

Terepi megjegyzések:

  • unlockBlockers: a bővítményedből aktív zárolási munkamenet-feloldási blokkolók listája.
  • Egyszerre több blokkolót is megadhatsz (legfeljebb 25-öt), minden nem teljesült feltételhez egyet.
  • A feloldás blokkolva marad, amíg bármilyen blokkoló elem fennáll az engedélyezett bővítmények között.
  • A Chastify összesíti a blokkolókat az összes kiterjesztésből a zárolási munkamenethez.
  • A bővítményednek csak a saját metaadataiban szabad hozzáadnia/eltávolítania a blokkolókat.
  • Ne törölj blokkolókat más kiterjesztésekből; csak akkor töröld a tömbödet, ha a saját feltételeid teljesülnek.
  • homeActions: gyorsműveleti gombok megjelenítése a zárolási felületen.
  • homeActions[].slug: a művelet stabil azonosítója.
  • homeActions[].title: felhasználó által látható címke.
  • homeActions[].description: opcionális segédszöveg.
  • homeActions[].intent: opcionális mélyhivatkozási utasítás, amely megnyitáskor átadódik a mellékednek.
  • A bővítőkártya felhasználói felületén ezek a műveletek menüként/listaként jelennek meg a művelet címe szerint (belsőleg a slug által kulcsolva).
  • Amikor a felhasználó rákattint egyre, a Chastify megnyitja a bővítményt és átadja a következőt:
    • homeActionSlug
    • homeAction (kiválasztott műveleti objektum)
    • intent (normalizált szándékobjektum) így a bővítményed betöltéskor azonnal a megfelelő nézetre/műveletre irányíthat át.

Intent: fejlesztői alkalmazás példa

Használd ezt a mintát a bővítményalkalmazásodban, hogy reagáljon a menüre kattintási szándékokra betöltéskor.

import { useEffect, useRef } from "react";
import { parseHashPayload, type IframeHashPayload } from "../lib/ChastifyBridge";

export function useHomeActionIntent(
payload: IframeHashPayload,
routeToPanel: (panel: string) => void,
showToast: (message: string) => void,
) {
const handledRef = useRef<string>("");

useEffect(() => {
const homeActionSlug = payload?.homeActionSlug ?? null;
if (!homeActionSlug) return;

// Prevent duplicate handling if component re-renders.
const key = `${payload.lockId || "lock"}:${homeActionSlug}`;
if (handledRef.current === key) return;
handledRef.current = key;

const intent = payload?.intent ?? payload?.homeAction?.intent ?? null;
if (!intent) return;

if (intent.type === "open_panel") {
const panel = String(intent.payload?.panel || "");
if (panel) routeToPanel(panel);
return;
}

if (intent.message) {
showToast(String(intent.message));
}
}, [payload, routeToPanel, showToast]);
}

// Example app bootstrap
const payload = parseHashPayload();
if (!payload) throw new Error("Missing iframe hash payload");

Mit csinál ez a példa:

  • Beolvassa a homeActionSlug + intent kódot az iframe hash hasznos adatából.
  • Minden kattintást csak egyszer kezel zár/akció slug-onként.
  • Egy panelhez irányít, ha a szándék open_panel.
  • Egyéni szándéktípusok esetén szándéküzenet megjelenítésére tér vissza.

Eszközparancs

device.command

Mit csinál:

  • Eszközvezérlő parancsot küld (ha az adott munkamenet/eszköz támogatja).
  • Lehetővé teszi a hosszabbító szabványosított ütés-/rezgéshatások kiváltását a Chastify segítségével.

Mikor kell használni:

  • Támogatott ütés-/rezgésparancsok indítása a bővítőlogikából.
  • Interaktív kiegészítő funkciók (játékok, büntetések, jutalmak, rutinok) kidolgozása.

Végpont:

POST /api/extensions/sessions/:sessionId/device-command
Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH

Példa törzs:

{
"command": "shock.start",
"params": {
"durationSeconds": 30,
"intensityPct": 50
}
}

Gyakori parancsok:

  • shock.start paraméterekkel: { durationSeconds, intensityPct, message? }
  • shock.stop
  • vibration.start paraméterekkel: { durationSeconds, intensityPct, frequencyPct?, message? }
  • vibration.stop
  • all.stop
  • shock.random.set paraméterekkel: { enabled, minIntensityPct?, maxIntensityPct?, message? } (csak Lockink AA-A1012 esetén)
  • shock.berserk.set paraméterekkel: { enabled, message? } (csak Lockink AA-A1012 esetén)

Ajánlott áramlás:

  1. Betöltéskor hívja meg a session.get függvényt.
  2. Eszközképességek olvasása a deviceControl.supportedCommands kódból.
  3. Csak a támogatott parancsok renderelési vezérlői.
  4. Küldd el a device.command kódot érvényesített értékekkel.
  5. A active válasz frissítése vagy megbízhatóvá tétele jelzőkkel jelzi az élő felhasználói felület állapotát.

Paraméter útmutató:

  • durationSeconds: a szerver biztonságos korlátokhoz van kötve (a jelenlegi szabályzat maximuma 300 másodperc).
  • intensityPct: várható százalékos érték (1-100 stílusú bemenet, szerveroldali rögzítés).
  • frequencyPct: várható százalékos érték (1-100) rezgési folyamatokhoz (szerveroldali rögzítés).
  • Véletlenszerű mód esetén ügyeljen a minIntensityPct <= maxIntensityPct kódra.

Biztonságosabb felhasználói felület minta példa:

// 1) Get capabilities first
const session = await bridge.request("session.get", {});
const supported = new Set(session?.deviceControl?.supportedCommands ?? []);

// 2) Only call command if supported
if (supported.has("shock.start")) {
await bridge.request("device.command", {
command: "shock.start",
params: { durationSeconds: 30, intensityPct: 50 }
});
}

Fontos:

  • Először hívd meg a session.get függvényt, és olvasd be a támogatott parancsokat.
  • Csak az aktuális munkamenetben támogatott parancsok vezérlőinek megjelenítése.
  • A parancsparaméterek elküldése előtt ellenőrizze a felhasználói bemeneteket.
  • A device.command írási jogosultságot (locks:write) igényel a kiterjesztési munkamenethez.
  • A híd/szerver hibákat (insufficient_scope, nem támogatott parancs, érvényesítési hibák) megfelelően kell kezelni.

Kiterjesztési követelmények

A kiterjesztés követelményei lehetővé teszik a kiterjesztés számára, hogy ismétlődő teljesítési szabályokat definiáljon, amelyek megjelennek a zár „Mai haladás” felhasználói felületén, és büntetést alkalmazhatnak, ha a viselője elmulaszt egy ablakot.

Használja ezt a szerver által megbízható bővítménytevékenységekhez, például:

  • Naponta 1 rejtvényt oldj meg.
  • Végezzen el 3 bejelentkezést 2 naponta.
  • Végezzen el 5 kiegészítő feladatot hetente.

Konfigurációs alakzat

A követelmény a bővítmény munkamenet-konfigurációjában a extensionRequirements alatt tárolódik:

{
"extensionRequirements": {
"enabled": true,
"metric": "completion",
"requiredCount": 1,
"cadence": {
"every": 1,
"unit": "day"
},
"punishment": {
"type": "add_time",
"seconds": 900,
"reason": "Missed extension requirement"
}
}
}

Mezők:

  • enabled: be-/kikapcsolja az ismétlődő követelményt.
  • metric: stabil számláló neve. Használjon egyszerű neveket, például completion, win vagy verification.
  • requiredCount: hány megbízható eseménynek kell történnie az ablakban.
  • cadence.every: intervallum mérete.
  • cadence.unit: day vagy week.
  • Az ablak időzónáját a Chastify oldja fel a viselő által konfigurált User.timezone paraméterből. A bővítmény konfigurációjának nem szabad időzónát fixen kódolnia.
  • punishment.type: none, add_time, freeze vagy pillory.
  • punishment.seconds: büntetés időtartama add_time, freeze vagy pillory esetén.
  • punishment.reason: opcionális audit/hibakeresési ok.

Haladási modell

A követelmények előrehaladása megbízható szerveroldali állapot, nem iframe-local állapot.

Ne használja a state.patch / state.put paramétereket egy követelmény teljesítettként való megjelölésére. Ezek a műveletek csak a háttérben futó általános állapotírások, nem pedig a követelmény előrehaladását jelző API-k. A követelmény előrehaladását csak azután kell rögzíteni, hogy a szerver validálja a számolni kívánt eseményt.

Például:

  • Egy rejtvénybővítménynek csak azután kell rögzítenie a haladást, miután a szerver validálta az aláírt rejtvény futtatását és a befejezett állapotot.
  • Az ellenőrző bővítménynek csak azután kell rögzítenie a folyamatot, hogy a szerver elfogadta a beküldött bizonyítékot.
  • Egy játékbővítménynek csak azután kell rögzítenie a haladást, hogy a háttérrendszer validálja a játék eredményét vagy a megbízható befejezési eseményt.

Futásidejű viselkedés

Konfigurálva:

  • A zárolási irányítópult a Mai haladás részben megjelenítheti a követelményt.
  • A Chastify nyomon követi a haladást kiterjesztett edzésenként és ütemablakonként.
  • Az ütemezett követelményfeladat kiértékeli a befejezett ablakokat, és minden kihagyott ablak után egyszer alkalmazza a konfigurált büntetést.
  • A büntetések ablakonként idempotensek, így az újrapróbálkozások nem halmozódnak a büntetések duplikációjával.
  1. Konfigurálja a extensionRequirements kódot a bővítmény beállítása/konfigurálása felhasználói felületén.
  2. Futás közbeni indításkor hívja meg a session.get függvényt, és olvassa be az aktív konfigurációt.
  3. Hajtsa végre a bővítmény tevékenységét a felhasználói felületen.
  4. Küldd el a befejezést egy megbízható háttér-útvonalra az adott bővítményhez.
  5. Hagyja, hogy a háttérrendszer validálja az eseményt és rögzítse a követelmény előrehaladását.
  6. A befejezés után frissítse a helyi felhasználói felületet a session.get / state.get paranccsal.

Fontos:

  • A state.* tárhelyet csak bővítmény tulajdonában lévő tárhelyként kezelje. Használjon dedikált, megbízható API-kat a haladáshoz, a kísérletekhez, a jutalmakhoz és a büntetésekhez.
  • Ne bízzon meg a csak kliensnek szóló befejezési jelzőkben a követelmények esetében.
  • Tartsa a metric neveket stabilan; a metrika megváltoztatása egy másik tárolóba kezd számolni.
  • A Chastify a viselő által konfigurált időzónát használja a ritmusablakokhoz. Ha a felhasználónál nincs elérhető időzóna, a szerver a UTC-ra vált vissza.
  • A büntetéseket korlátozottan és magyarázhatóan kell tárolni az auditnaplókban.
  1. Indításkor hívja meg a session.get függvényt.
  2. Állapot olvasása a state.get kóddal.
  3. Szükség esetén állapotírást végezhet a háttérrendszerből a PUT/PATCH /state használatával.
  4. Csak akkor futtasson zárolási/eszközműveleteket, ha támogatott és látható a felhasználói felületen.
  5. A követelmények által támogatott tevékenységek befejezését egy megbízható háttérútvonalon kell jelenteni.
  6. Helyi nézet frissítése fontos írások/műveletek után.