Skip to main content

API-esimerkkejä

Käytä tätä sivua kopioidaksesi oikean pyyntömuodon kullekin laajennustyönkululle.

  • Iframe-sillan esimerkeissä käytetään postMessage-toimintoja, kuten session.get, state.get ja files.get.
  • Etuoikeutetut esimerkit käyttävät omaa laajennustaustajärjestelmääsi Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY:n ja x-chastify-main-token:n avulla.
  • Älä koskaan lähetä kehittäjän API-avainta iframeen tai selainkoodiin.
info

iframe-silta on tarkoitettu käyttöliittymän käynnistykseen ja matalan riskin istuntotoimintoihin. Käytä sitä kontekstin lukemiseen, laajennuksen omistaman tilan tallentamiseen ja tiedostojen URL-osoitteiden selvittämiseen.

caution

Selaimen iframe-koodi on käyttäjän hallinnassa. Älä käytä iframe-siltapyyntöjä ajan asettamiseen/poistamiseen, tehtävien suorittamiseen, lukituksen avaamisen estäjien poistamiseen, suorituksenaikaisten tiedostojen lataamiseen/poistamiseen, ilmoitusten lähettämiseen, lokien kirjoittamiseen tai laitteiden komentamiseen.

Pyyntö- ja vastausmuoto

Turvalliset iframe-siltatoiminnot lähetetään tämän siltapyyntökirjekuoren sisällä:

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

Ja saat:

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

Jos ok on false, tarkista error.code ja error.message.

Vain taustajärjestelmää käyttävät esimerkit käyttävät palvelimesi normaaleja HTTPS-pyyntöjä. Niitä ei lähetetä iframe-sillan kautta.

Istunto ja konteksti

session.get

Käytä tätä ensimmäisenä lähes jokaisessa laajennustyönkulussa.

Mitä se tekee:

  • Varmistaa, että siltayhteys toimii.
  • Palauttaa istunnon kontekstin (lukitustila, rooli, laajennuksen kokoonpano, ominaisuudet).
  • Palauttaa laitteen ominaisuustiedot, joita käyttöliittymäsi voi käyttää ennen kuin pyytää taustajärjestelmääsi kutsumaan device.command:ta.

Mihin sitä käytetään:

  • Käyttöliittymän uudelleenkäynnistys.
  • Ominaisuuksien ottaminen käyttöön/poistaminen käytöstä roolin ja käyttöoikeuksien perusteella.
  • Tuettujen laitekomentojen tarkistaminen ennen laiteohjainten renderöintiä.

Esimerkki toiminnon hyötykuormasta:

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

Esimerkki session.get-vastauksen otteesta (ajonaikaiset lukitustiedot):

{
"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
}
}
}

Tietosuojahuomautuksia:

  • wearerLastSeenTimestamp / keyholderLastSeenTimestamp palautetaan vain, jos käyttäjällä on showOnlineStatus !== false.
  • Jos online-tilan näkyvyys on poistettu käytöstä, nämä kentät ovat muotoa null.

Taustajärjestelmän laajennustyönkulut

Nämä esimerkit osoittavat turvallisen tuotantomallin:

  1. iframe lukee mainToken:n ja sessionId:n hajautussisällöstä.
  2. iframe lähettää ne taustajärjestelmääsi.
  3. Taustajärjestelmäsi validoi oman pelisi/tehtäväsi/yrityksesi tilan.
  4. Taustajärjestelmäsi kutsuu Chastify:ta sovelluskohtaisella kehittäjän API-avaimella ja x-chastify-main-token:lla.

Älä käytä sessionId-avainta yksinään todennukseen. Käsittele mainToken-avainta selaimessa näkyvänä käynnistyskontekstina ja kehittäjän API-avaintasi vain taustajärjestelmän käytettävissä olevana salaisuutena.

warning

Taustajärjestelmäsi on validoitava oman peli-/tehtävätilansa ennen Chastify-kutsun kutsumista. mainToken- ja sessionId-kulmien välittäminen iframe-kehyksestä tunnistaa vain avatun laajennusistunnon; se ei todista käyttäjän suorittaneen haasteen.

Nouda istunnon konteksti turvallisesti

iframesi voi käyttää käyttöliittymän käynnistykseen turvasiltaa session.get. Jos taustajärjestelmäsi tarvitsee saman kontekstin ennen etuoikeutetun toiminnon suorittamista, nouda se taustajärjestelmästäsi molemmilla tunnistetiedoilla.

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
})
});

Taustajärjestelmäsi:

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
});
});

Käytä aikaa laajennuksen taustajärjestelmästä

Selain voi pyytää taustajärjestelmääsi antamaan palkinnon tai rangaistuksen, mutta selaimen ei tule päättää, onko toiminto pätevä. Tarkista toiminto ensin palvelimen puolella.

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());
});

Käytä rangaistuksiin koodia add_time ja palkkioihin koodia remove_time.

Palvelimen vahvistama pelin suorittaminen

Simon Saysin kaltaisissa peleissä älä luota asiakkaan raportoimaan voittoon. Luo suoritus palvelimen puolella, tallenna odotettu sekvenssi tai sen tiiviste ja tarkista lähetetty syöte ennen Chastify-kutsun käyttämistä.

Selaimessa näkyvä muistipeli ei voi todistaa, että ihminen on pelannut rehellisesti, koska selaimen on vastaanotettava sekvenssi pelin renderöimiseksi. Palvelimen vahvistus estää edelleen väärennetyt Chastify-mutaatiot ja antaa taustajärjestelmällesi mahdollisuuden valvoa suoritustunnuksia, vanhenemista, vaikeusastetta, kadenssia, pisteytystä ja uusintapelin estoa ennen palkintojen tai rangaistusten soveltamista.

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 });
});

Tarkka suoritustallennuskaava on sinun. verifySessionLaunch:n tulisi kutsua Chastify:ta sovelluslaajuisella Developer API -avaimellasi ja x-chastify-main-token:lla ennen kuin luottaa sessionId:hon. Tärkeä sääntö on, että Chastify-mutaatiot tapahtuvat vasta sen jälkeen, kun taustajärjestelmäsi on vahvistanut käynnistyksen ja tuloksen.

Aikataulun mukaiset vaatimukset

Backend-järjestelmäsi omistaa aikataulut, kadenssitarkistukset ja todistusten validoinnin. Käytä Chastify-funktiota vain luotettavan edistymisen tallentamiseen tai lukituksen avaamisen estäjien päivittämiseen sen jälkeen, kun backend-järjestelmäsi on päättänyt vaatimuksen täyttyneen.

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
})
});
}

Nykyiset asennettujen laajennusten istuntojen API-rajapinnat vaativat kelvollisen iframe-käynnistystunnuksen x-chastify-main-token-koodissa; käynnistystunnukset vanhenevat tällä hetkellä 10 tunnin kuluttua. Ajoitettujen töiden osalta, jotka suoritetaan kyseisen tunnuksen vanhenemisen jälkeen, tallenna omat odottavat todisteesi ja lähetä edistyminen seuraavan kelvollisen laajennuksen käynnistyksen yhteydessä tai käytä ensimmäisen osapuolen/sisäänrakennettua palvelintyönkulkua, joka on suunniteltu valvomattomaan taustatyöhön.

caution

Älä käsittele ajoitettuja töitä luotettuina vain siksi, että ne suoritetaan palvelimellasi. Työ tarvitsee silti palvelinpuolen varmuuden, kadenssitarkistukset, toistosuojauksen ja kelvollisen Chastify-valtuutuspolun ennen vaatimusten edistymisen tallentamista.

Ilmoitukset

notifications.custom

Käytä tätä laajennuksen taustajärjestelmässäsi lähettääksesi mukautetun laajennusilmoituksen käyttäjälle, avaimenhaltijalle tai molemmille.

Päätepiste:

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

Esimerkki rungosta:

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

Huomautuksia:

  • showPageOverlay:n oletusarvo on false.
  • target:n oletusarvo on wearer.
  • API luo ilmoitustyypin extension_app_message.

Laajennustila

Laajennuksen tila on laajennuksesi omistama JSON-data nykyisestä lukitusistunnosta. Tilakirjoituksia voi tehdä vain taustajärjestelmässä ja ne vaativat sovelluskohtaisen kehittäjän API-avaimen sekä istunnon mainToken. Iframe-kehykset voivat lukea tilan state.get:lla, mutta ne eivät voi kirjoittaa tilaa suoraan.

state.put

Mitä se tekee:

  • Korvaa koko tilaobjektin uudella data-objektilla.
  • Vaatii taustajärjestelmän tunnistetiedot.

Milloin käyttää:

  • Alkuperäinen tallennus.
  • Täydellinen ylikirjoitus, kun sinulla on jo täysin uusi tila.

Esimerkki:

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"
}
}'

Kenttähuomautuksia:

  • payload.data: mikä tahansa kelvollinen JSON-arvo/objekti, jota laajennuksesi tarvitsee.
  • Avoid Mongo-unsafe key names ($ prefix or keys containing .).
  • Tila on istuntokohtainen ja sen kokoa rajoittaa laajennussovelluksen stateMaxBytes, oletusarvoisesti 64 KiB.
  • Tallenna tiedostotunnukset tilaan, älä binääritiedostoihin tai allekirjoitettuihin URL-osoitteisiin. Käytä files.get-koodia päivittääksesi allekirjoitetut URL-osoitteet ennen median renderöintiä.

state.patch

Mitä se tekee:

  • Käyttää JSON-yhdistämiskorjausta olemassa olevaan tilaan.
  • Vain vaihdetut avaimet tarvitsee lähettää.
  • Vaatii taustajärjestelmän tunnistetiedot.

Milloin käyttää:

  • Käyttäjien vuorovaikutuksesta saatavat lisäpäivitykset.
  • Yhden kentän päivittäminen lähettämättä kaikkea uudelleen.

Esimerkki:

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ä se tekee:

  • Lukee laajennuksen nykyisen tilan.
  • Saatavilla iframe-sillan kautta.

Milloin käyttää:

  • iframe-latauksen yhteydessä.
  • Kirjoitusten jälkeen, jos haluat synkronoida paikallisen käyttöliittymän uudelleen.

Esimerkki:

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

Tiedostojen tallennus

Käytä files.*-koodia binääritiedostoille, kuten pulmakuville, luoduille esikatseluille tai haastekuville. Tallenna palautettu file.id taustajärjestelmään kirjoitettuna tai omaan tietokantaasi. Renderöi file.signedUrl-koodilla ja päivitä allekirjoitettu URL-osoite files.get-koodilla, kun iframe latautuu myöhemmin.

Ennen lukituksen/istunnon luomista suoritettavat asennusnäytöt käyttävät vaiheittaisia ​​​​latauksia files.upload:n sijaan. Vaiheistetut tiedostot ovat väliaikaisia, kunnes laajennuksen määritykset tallennetaan provider: "chastify_storage"- ja fileId-viittauksilla. Chastify vaatii nämä tiedostot automaattisesti lukituksen/mallin tallennuksen yhteydessä; erillistä selainpuolen vaatimuskutsua ei ole.

Esimerkki tilan/tiedoston jakamisesta taustajärjestelmästäsi:

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"
}
}'

Myöhemmin, ratkaise kuva ennen näyttöä:

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

Tarkista tämä ennen latausohjainten näyttämistä.

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

Suorituksenaikainen files.upload

Suorituksenaikaisten tiedostojen lataus muuttaa laajennusistunnon tietoja, joten se ei ole iframe-siltakomento. Lataa suorituksenaikaiset tiedostot taustajärjestelmästäsi sovelluskohtaisella kehittäjän API-avaimella ja x-chastify-main-token:lla.

files.get

Päivitä yksi allekirjoitettu R2-URL-osoite vakaasta tiedostotunnuksesta.

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

files.list

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

Myös ajonaikainen files.delete on vain taustajärjestelmäversio samasta syystä kuin lataus.

Lukitustoiminnot

Lisää aika

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Lisää tai poistaa aikaa lukituslaskennasta koodista deltaSeconds riippuen.

Milloin käyttää:

  • Palkinto-/rangaistuspainikkeet.
  • Pelin lopputulos (voitto lisää aikaa, häviö vähentää).

Esimerkki:

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

Kenttähuomautuksia:

  • Positiivinen arvo lisää aikaa.
  • Negatiivinen arvo poistaa ajan (jos palvelimen säännöt sen sallivat).

Jäädytä

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Jäädyttää lukituksen etenemisen tietyksi ajaksi.

Milloin käyttää:

  • Jäähtymismekaniikka.
  • Palkintotarkastuspisteet.

Esimerkki:

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

Voit kutsua sitä myös ilman koodia durationSeconds:

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

Kenttähuomautuksia:

  • durationSeconds on valinnainen.
  • Jos tätä ei tehdä, nykyinen oletusarvo on 3600 sekuntia (1 tunti).
  • Hyväksytty alue on 60 - 86400 sekuntia.

Vapauttaa

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Lopettaa aktiivisen jäädytyksen ja palaa normaaliin ajastimen toimintaan.

Milloin käyttää:

  • Manuaalinen ohitus laajennustyönkuluissa.
  • ”Peruuta jäädytys” -säätimet.

Esimerkki:

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

Häpeäpaalun

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Aloittaa aktiivisen lukitusistunnon häpeäpaalun.

Milloin käyttää:

  • Rangaistusmekaniikka epäonnistuneiden tehtävien/haasteiden jälkeen.
  • Eskalointivirrat, jotka tilapäisesti rajoittavat lukkojen vuorovaikutusta.

Esimerkki:

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

Kenttähuomautuksia:

  • name:n on oltava pillory.
  • params.durationSeconds on pakollinen.
  • params.reason on valinnainen.
  • Edellyttää, että häpeäpilkku on käytössä istunnon asetuksissa.

Loppu häpeäpaalu

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Lopettaa nykyisen aktiivisen häpeäpaalun istunnon välittömästi.

Esimerkki:

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

Kenttähuomautuksia:

  • name:n on oltava pillory.end.
  • Epäonnistuu koodilla pillory_not_active, jos lukko ei ole parhaillaan häpeäpaaluun pakkotilassa.

Määritä tehtävä

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Luo käyttäjälle aktiivisen tehtäväsuorituksen laajennuslogiikasta.
  • Voi ohittaa jo avoimen tehtäväsuorituksen.

Esimerkki:

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

Kenttähuomautuksia:

  • taskText on pakollinen.
  • points on valinnainen ja rajoitettu palvelinpuolella.
  • verificationRequired:n oletusarvo on false.
  • durationSeconds on valinnainen (0 tarkoittaa, ettei ajastinta tarvita).
  • Edellyttää, että Tehtävät-moduuli on käytössä lukossa.

Käynnistä tehtäväajastin

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Käynnistää tai käynnistää uudelleen lähtölaskurin aktiiviselle ajastetulle tehtävälle.

Esimerkki:

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

Kenttähuomautuksia:

  • Vaatii aktiivisen tehtävän suorittamisen.
  • Epäonnistuu, jos nykyiselle tehtävälle ei ole määritetty kestoa.

Suorita tehtävä

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Merkitsee aktiivisen tehtävän suorituksen suoritetuksi tai epäonnistuneeksi.

Esimerkki (onnistuminen):

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

Esimerkki (epäonnistui):

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

Käynnistä väliaikainen avaaminen

Päätepiste: POST /api/extensions/sessions/:sessionId/action

Mitä se tekee:

  • Käynnistää väliaikaisen hygienia-avausikkunan laajennuslogiikasta.

Esimerkki:

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

Kenttähuomautuksia:

  • Edellyttää, että lukossa on käytössä hygieeninen avaus.
  • Epäonnistuu, jos hygienia-avaus on jo käynnissä.
  • durationSeconds on valinnainen; jos sitä ei käytetä, käytetään lukituksen oletusarvoa.

Metadata ja kotisivun toiminnot

metadata.patch

Mitä se tekee:

  • Tallentaa lukitussivun käyttöliittymän käyttämät laajennuksen metatiedot.
  • Tukee unlockBlockers- ja homeActions-koodeja.
  • Tukee homeActions[].intent:ta syvälinkkien toiminnassa laajennuksen avautuessa.

Milloin käyttää:

  • Pakota laajennuksesi omistamat lukitusistunnon avausehdot.
  • Lisää lukitussivulle pikatoimintoja, jotka avaavat laajennuksesi tietyllä tavalla.
  • Ohjaa käyttäjät suoraan tietylle näytölle/työnkulkuun, kun he napsauttavat aloitusnäyttötoimintoa.

Päätepiste:

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

Esimerkki rungosta:

{
"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"
}
}
}
]
}

Kenttähuomautuksia:

  • unlockBlockers: luettelo laajennuksesi aktiivisista lukitusistunnon avauksen estäjistä.
  • Voit sisällyttää useita estotekijöitä kerralla (enintään 25), yhden kutakin täyttämätöntä ehtoa kohden.
  • Lukituksen avaaminen pysyy estettynä, kun käytössä on jokin estotoiminto kaikissa käytössä olevissa laajennuksissa.
  • Chastify kokoaa yhteen estäjät kaikista lukitusistunnon laajennuksista.
  • Laajennuksesi tulisi lisätä/poistaa omat estonsa vain omissa metatiedoissaan.
  • Älä tyhjennä muiden laajennusten estäjiä; tyhjennä oma taulukkosi vasta, kun omat ehtosi täyttyvät.
  • homeActions: pikatoimintopainikkeet näkyvät lukituskokemuksessa.
  • homeActions[].slug: toiminnon vakaa tunniste.
  • homeActions[].title: käyttäjälle näkyvä otsikko.
  • homeActions[].description: valinnainen aputeksti.
  • homeActions[].intent: valinnainen syvälinkkiohje, joka välitetään laajennuksellesi avattaessa.
  • Laajennuskortin käyttöliittymässä nämä toiminnot näkyvät valikkona/luettelona toiminnon otsikon mukaan (sisäisesti slug-näppäilemät).
  • Kun käyttäjä napsauttaa yhtä, Chastify avaa laajennuksen ja välittää:
    • homeActionSlug
    • homeAction (valittu toiminto-objekti)
    • intent (normalisoitu tarkoitusobjekti) jotta laajennuksesi voi välittömästi ohjata oikeaan näkymään/toimintoon latauksen yhteydessä.

Intents: kehittäjäsovelluksen esimerkki

Käytä tätä mallia laajennussovelluksessasi reagoidaksesi valikon napsautusaikeisiin latauksen aikana.

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ä tämä esimerkki tekee:

  • Lukee homeActionSlug + intent iframe-hajautussisällöstä.
  • Käsittelee jokaisen napsautuksen vain kerran lukitus-/toimintoetanaa kohden.
  • Ohjaa paneeliin, kun tarkoitus on open_panel.
  • Palaa näyttämään tarkoitusviestin mukautettujen tarkoitustyyppien kohdalla.

Laitekomento

device.command

Mitä se tekee:

  • Lähettää laiteohjauskomennon (jos kyseinen istunto/laite sitä tukee).
  • Antaa jatkeen laukaista standardoituja isku-/tärinätoimintoja Chastify:n kautta.

Milloin käyttää:

  • Tuettujen isku-/tärinäkomentojen laukaiseminen laajennuslogiikasta.
  • Interaktiivisten laajennusominaisuuksien (pelit, rangaistukset, palkinnot, rutiinit) rakentaminen.

Päätepiste:

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

Esimerkki rungosta:

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

Yleisiä komentoja:

  • shock.start parametreilla: { durationSeconds, intensityPct, message? }
  • shock.stop
  • vibration.start parametreilla: { durationSeconds, intensityPct, frequencyPct?, message? }
  • vibration.stop
  • all.stop
  • shock.random.set parametreilla: { enabled, minIntensityPct?, maxIntensityPct?, message? } (vain Lockink AA-A1012)
  • shock.berserk.set parametreilla: { enabled, message? } (vain Lockink AA-A1012)

Suositeltu virtaus:

  1. Kutsu session.get:ta latauksen aikana.
  2. Lue laitteen ominaisuudet koodista deviceControl.supportedCommands.
  3. Renderöi vain tuettujen komentojen ohjausobjektit.
  4. Lähetä koodi device.command validoitujen arvojen kera.
  5. Päivitä tai luota vastaukseen active merkitsemällä se reaaliaikaisen käyttöliittymän tilan.

Parametrien ohjeet:

  • durationSeconds: palvelin rajoittaa käyttöaikansa turvallisiin rajoihin (nykyinen käytäntömaksimi on 300 sekuntia).
  • intensityPct: odotettu prosenttiarvo (1-100-tyylinen syöte, rajoitettu palvelinpuolella).
  • frequencyPct: odotettu prosenttiarvo (1-100) värähtelyvirroille (palvelinpuolen lukitus).
  • Satunnaistilassa varmista, että koodi on minIntensityPct <= maxIntensityPct.

Turvallisemman käyttöliittymän malliesimerkki:

// 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 }
});
}

Tärkeää:

  • Kutsu ensin session.get-funktiota ja lue tuetut komennot.
  • Näytä vain niiden komentojen ohjausobjektit, joita tuetaan nykyisessä istunnossa.
  • Tarkista käyttäjän syötteet ennen komentoparametrien lähettämistä.
  • device.command vaatii kirjoitusoikeuden (locks:write) laajennusistuntoa varten.
  • Käsittele silta-/palvelinvirheet sujuvasti (insufficient_scope, ei-tuettu komento, validointivirheet).

Laajennusvaatimukset

Laajennusvaatimukset antavat laajennuksen määrittää toistuvia täydennyssääntöjä, jotka näkyvät lukon Tänään-edistyminen-käyttöliittymässä, ja ne voivat määrätä rangaistuksen, jos käyttäjä ei ehdi suorittaa tiettyä aikaikkunaa.

Käytä tätä palvelimen luottamiin laajennustoimintoihin, kuten:

  • Ratkaise yksi palapeli päivässä.
  • Tee 3 sisäänkirjautumista kahden päivän välein.
  • Suorita 5 jatkotoimenpidettä viikossa.

Konfiguraation muoto

Vaatimus tallennetaan laajennusistunnon kokoonpanoon kohdassa extensionRequirements:

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

Kentät:

  • enabled: ottaa toistuvan vaatimuksen käyttöön/pois käytöstä.
  • metric: vakaan laskurin nimi. Käytä yksinkertaisia ​​nimiä, kuten completion, win tai verification.
  • requiredCount: kuinka monta luotettua tapahtumaa ikkunassa täytyy tapahtua.
  • cadence.every: aikavälin koko.
  • cadence.unit: day tai week.
  • Ikkunan aikavyöhyke ratkaistaan ​​käyttäjän määrittämän Chastify:n perusteella. Laajennusmäärityksiin ei tule koodata aikavyöhykettä kiinteästi.
  • punishment.type: none, add_time, freeze tai pillory.
  • punishment.seconds: rangaistuksen kesto koodille add_time, freeze tai pillory.
  • punishment.reason: valinnainen tarkastus-/virheenkorjaussyy.

Edistymismalli

Vaatimuksen edistyminen on luotettavan palvelimen puolen tilaa, ei iframe-local-tilaa.

Älä käytä state.patch / state.put -parametreja vaatimuksen merkitsemiseen valmiiksi. Nämä toiminnot ovat vain taustajärjestelmän yleisiä tilakirjoituksia, eivät vaatimusten edistymisen API-rajapintoja. Vaatimuksen edistyminen on kirjattava vasta sen jälkeen, kun palvelin on vahvistanut laskettavan tapahtuman.

Esimerkiksi:

  • Pulmalaajennuksen tulisi tallentaa edistyminen vasta sen jälkeen, kun palvelin on vahvistanut allekirjoitetun pulmapelin suorituksen ja sen valmistumistilan.
  • Vahvistuslaajennuksen tulisi tallentaa edistyminen vasta sen jälkeen, kun palvelin on hyväksynyt lähetetyn todisteen.
  • Pelilaajennuksen tulisi tallentaa edistyminen vasta sen jälkeen, kun taustajärjestelmä on vahvistanut pelin tuloksen tai luotetun valmistumistapahtuman.

Suorituksenaikainen toiminta

Kun konfiguroitu:

  • Lukitusnäkymässä vaatimus näkyy Tänään-edistymisessä.
  • Chastify seuraa edistymistä laajennusharjoitusta kohden ja poljinnopeusikkunaa kohden.
  • Ajoitettu vaatimustyö arvioi valmiit ikkunat ja soveltaa määritettyä rangaistusta kerran kutakin puuttuvaa ikkunaa kohden.
  • Rangaistukset ovat idempotentteja ikkunaa kohden, joten uudelleenyritykset eivät kasaa päällekkäisiä rangaistuksia.
  1. Määritä extensionRequirements laajennuksen asennus-/konfigurointikäyttöliittymässä.
  2. Suorituksenaikaisen käynnistyksen yhteydessä kutsu session.get-funktiota ja lue aktiivinen konfiguraatio.
  3. Suorita laajennustoiminto käyttöliittymässä.
  4. Lähetä suoritettu tiedosto kyseisen laajennuksen luotettavalle taustajärjestelmän reitille.
  5. Anna taustajärjestelmän validoida tapahtuman ja tallentaa vaatimuksen edistyminen.
  6. Päivitä paikallinen käyttöliittymä komennolla session.get / state.get valmistumisen jälkeen.

Tärkeää:

  • Käsittele state.*-tiedostoa vain laajennuksen omistamana tallennustilana. Käytä erillisiä luotettavia API-rajapintoja edistymiseen, yrityksiin, palkintoihin ja rangaistuksiin.
  • Älä luota vain asiakkaalle tarkoitettuihin täydennyslippuihin vaatimusten osalta.
  • Pidä metric-nimet vakaina; metriikan muuttaminen alkaa laskea eri säilöön.
  • Chastify käyttää käyttäjän määrittämää aikavyöhykettä tahti-ikkunoille. Jos käyttäjällä ei ole aikavyöhykettä, palvelin käyttää UTC:ta.
  • Pidä rangaistukset rajattuina ja selitettävissä lokitiedoissa.
  1. Kutsu session.get:ta käynnistyksen yhteydessä.
  2. Lue tila koodilla state.get.
  3. Suorita tilakohtaisia ​​kirjoituksia taustajärjestelmästäsi PUT/PATCH /state:lla tarvittaessa.
  4. Suorita lukitus-/laitetoimintoja vain, jos niitä tuetaan ja ne näkyvät käyttöliittymässä.
  5. Vaatimustenmukaisten toimintojen valmistuminen raportoidaan luotettavalle taustareitille.
  6. Päivitä paikallinen näkymä tärkeiden kirjoitusten/toimintojen jälkeen.