Aller au contenu principal

Essayez l'API de développement d'extensions

Utilisez ce guide si vous souhaitez créer une extension Chastify, héberger une page d'extension iframe ou appeler l'API développeur depuis votre propre backend.

Cette page est le point de départ : quel mode choisir, que lancer en premier et où aller ensuite.

Pour des exemples concrets de comportement d'extension tels que le déverrouillage des bloqueurs, les actions requises régulières, les récompenses et les punitions, voir Fonctionnalités de l'API d'extension.

astuce

Vous souhaitez simplement contrôler votre propre serrure ?

Si vous n'avez pas besoin de créer une extension publique, la page API externes et programmes est la solution la plus simple pour commencer. Il vous suffit de créer un jeton DEV et d'appeler des points de terminaison REST simples : aucune configuration d'extension, aucun iframe, aucune gestion de session n'est requise. Cette page permet d'ajouter/supprimer du temps, de figer des tâches, d'exécuter des commandes sur l'appareil, et bien plus encore.

À quoi sert cette API ?

L'API Extensions Developer vous permet de créer des expériences d'extension tierces qui s'exécutent dans des sessions verrouillées Chastify.

Grâce à lui, vous pouvez :

  • Lire la session et le contexte de verrouillage (session.get pour les extensions, /api/apps/v1/session pour votre propre automatisation de verrouillage)
  • Lire les données appartenant à l'extension par session de verrouillage (state.get) et les écrire depuis votre backend (PUT/PATCH /state).
  • Stockez les fichiers image appartenant à l'extension avec le stockage R2 géré par Chastify (files.*)
  • Ajouter des actions d'interface utilisateur d'extension sur les cartes de verrouillage (metadata.homeActions)
  • Flux de déverrouillage de porte avec bloqueurs de déverrouillage appartenant à l'extension (metadata.unlockBlockers)
  • Actions de verrouillage déclenchées depuis un serveur de confiance (ajout/suppression de temps, gel/dégel, modification des paramètres)
  • Actions de déclenchement et d'hygiène (task.assign, task.start_timer, task.complete, hygienic_unlock.start)
  • Soumettez des actions régulières avec prise en charge des compteurs/cadences
  • Envoyer les commandes des périphériques pris en charge lorsqu'elles sont disponibles
  • Écrire des entrées de journal d'extension personnalisées pour verrouiller l'historique

Ce que vous pouvez construire

Les fonctionnalités appropriées dépendent du domaine de confiance.

Les extensions iframe frontales uniquement permettent de créer des expériences UI-first qui ne nécessitent pas de mutation de verrou de confiance :

  • Pages de configuration qui collectent la configuration de l'extension
  • Tableaux de bord qui lisent le contexte de session
  • Interfaces utilisateur de puzzle, de liste de contrôle ou de jeu qui lisent l'état de la session et envoient la progression vérifiée via un serveur dorsal
  • Flux multimédias qui lisent les fichiers d'extension déjà stockés par Chastify
  • Points d'entrée d'action d'accueil qui ouvrent votre iframe avec une intention

Les extensions côté serveur peuvent intégrer des fonctionnalités affectant les verrous, car votre serveur vérifie les résultats avant d'appeler les API privilégiées :

  • Systèmes de tâches ou d'habitudes avec exigences de déverrouillage
  • Exigences quotidiennes ou hebdomadaires avec sanctions prévues en cas de non-respect des délais
  • Jeux qui récompensent la réussite ou pénalisent l'échec par des changements de durée de verrouillage
  • Flux de vérification qui lèvent les blocages de déverrouillage après validation côté serveur
  • Flux compagnons de contrôle des périphériques utilisant les commandes de périphériques prises en charge
  • Flux de travail Webhook/base de données qui conservent l'état de l'extension en dehors de l'iframe

Les programmes externes servent à l'automatisation privée de votre propre serrure active :

  • Scripts locaux
  • Tableaux de bord personnels
  • Outils d'automatisation utilisant une clé DEV à l'échelle de l'utilisateur

Choisissez votre mode

Choisissez l'un de ces modes :

  1. Hosted iframe extension : hébergez une interface utilisateur statique iframe sur Cloudflare Pages ou un service similaire. Utilisez le pont pour la configuration, le contexte de session et les lectures sécurisées. N’utilisez pas ce mode seul pour les écritures d’état, les récompenses, les sanctions, la validation du déblocage ou la progression des exigences de confiance.
  2. Server-backed extension : hébergez l’interface utilisateur iframe et exécutez votre propre serveur. L’iframe envoie son code de lancement mainToken à votre serveur, qui appelle ensuite l’API d’extension Chastify avec une clé API développeur spécifique à l’application et le code x-chastify-main-token. Utilisez ce mode pour les actions privilégiées, le déblocage des éléments bloquants, la validation de la progression, les récompenses, les sanctions, les webhooks et les bases de données externes.
  3. External API & Programs : utilisez la touche DEV (utilisateur unique) pour les scripts, les programmes locaux ou les automatisations qui contrôlent votre propre verrou actif. Ce mode n’est pas destiné aux utilisateurs tiers installant votre extension.

Pour des tests rapides, commencez par le mode iframe pour l'interface utilisateur et les lectures sécurisées. Ajoutez un backend avant d'implémenter les écritures d'état, les récompenses fiables, les changements d'heure, la progression des exigences planifiées ou la levée des blocages.

attention

Le code de l'iframe ne constitue pas une limite de confiance. Tout élément visible par l'iframe, y compris les données de hachage et les jetons de lancement, peut être inspecté et rejoué par l'utilisateur.

10 premières minutes (mode Iframe)

  1. Lire la charge utile location.hash depuis l'iframe Chastify ouverte.
  2. Créer une requête de pont pour session.get.
  3. Confirmez la réponse avec type: "chastify:ext:resp" et ok: true.
  4. Lecture de l'état de test avec state.get.
  5. Ajout du redimensionnement automatique et de la prise en charge des thèmes pour que l'iframe se comporte correctement dans l'interface utilisateur.

La prise en charge des thèmes est intégrée à une iframe prête à l'emploi. Chastify transmet les valeurs ui dans le hachage de lancement et envoie des mises à jour de thème en temps réel tant que l'iframe est ouverte. Consultez Thèmes d'iframe pour des exemples clairs/sombres et des motifs Tailwind compatibles avec les contrastes.

Valeurs de charge utile requises :

  • bridge.nonce
  • bridge.parentOrigin
  • sessionId
  • lockId

Exemple de requête de pont :

{
"type": "chastify:ext:req",
"v": 1,
"id": "request-id", // unique id per request
"nonce": "nonce-from-hash",
"action": "session.get",
"payload": {}
}

Exemple de réponse du pont :

{
"type": "chastify:ext:resp",
"v": 1,
"id": "request-id",
"ok": true,
"data": {}
}

Actions essentielles pour apprendre en premier

  • session.get
  • state.get
    Lisez le stockage JSON appartenant à l'extension pour la session de verrouillage. Écrivez l'état depuis votre backend avec les identifiants de l'API développeur.
  • files.capabilities, files.list, files.get Utilisez la lecture du stockage de fichiers pour les médias binaires tels que les images de puzzles ou les aperçus générés. Stockez les identifiants de fichiers dans l'état écrit par le serveur, puis actualisez les URL signées avec files.get.
  • metadata.get Lire les bloqueurs de déverrouillage de session et les actions/intentions d'accueil de la carte d'extension.
  • regularActions.get

Les modifications de session telles que les écritures d'état, les soumissions d'actions régulières, le chargement/la suppression de fichiers en cours d'exécution, les changements d'heure, les mises à jour des bloqueurs de déverrouillage, l'achèvement des tâches, les démarrages de nettoyage et les commandes de l'appareil doivent être effectuées depuis votre serveur à l'aide d'une clé API développeur. Le code iframe du navigateur n'est pas autorisé pour ces actions.

URL complètes des API (prises en charge)

Domaine de base : https://chastify.net

API de session d'extension (/api/extensions/*)

Ces routes ont des modes d'accès différents. Ne considérez pas l'ensemble de la surface /api/extensions/* comme étant compatible avec les iframes.

Les routes de pontage iframe sécurisées sont acheminées via le parent Chastify après les requêtes de pontage postMessage :

  • GET https://chastify.net/api/extensions/sessions/:sessionId
  • GET https://chastify.net/api/extensions/sessions/:sessionId/state
  • GET https://chastify.net/api/extensions/sessions/:sessionId/metadata
  • GET https://chastify.net/api/extensions/sessions/:sessionId/regular-actions
  • GET https://chastify.net/api/extensions/sessions/:sessionId/files/capabilities
  • GET https://chastify.net/api/extensions/sessions/:sessionId/files
  • GET https://chastify.net/api/extensions/sessions/:sessionId/files/:fileId

Les routes d'extension installées uniquement côté serveur nécessitent une clé API développeur au niveau de l'application et le jeton de lancement iframe :

Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH
info

Ce modèle à deux jetons lie une requête backend à la fois au développeur de l'extension (Authorization) et à la session d'extension actuellement ouverte (x-chastify-main-token).

  • PATCH https://chastify.net/api/extensions/sessions/:sessionId/metadata
  • PUT https://chastify.net/api/extensions/sessions/:sessionId/state
  • PATCH https://chastify.net/api/extensions/sessions/:sessionId/state
  • PATCH https://chastify.net/api/extensions/sessions/:sessionId/regular-actions/config
  • POST https://chastify.net/api/extensions/sessions/:sessionId/regular-actions
  • POST https://chastify.net/api/extensions/sessions/:sessionId/files
  • DELETE https://chastify.net/api/extensions/sessions/:sessionId/files/:fileId
  • POST https://chastify.net/api/extensions/sessions/:sessionId/logs/custom
  • POST https://chastify.net/api/extensions/sessions/:sessionId/notifications/custom
  • POST https://chastify.net/api/extensions/sessions/:sessionId/device-command
  • POST https://chastify.net/api/extensions/sessions/:sessionId/action
  • POST https://chastify.net/api/extensions/sessions/:sessionId/requirements/progress

API de jetons backend (/api/apps/v1/*)

Utilisez Authorization: Bearer <user-wide DEV token>. Ces points de terminaison gèrent les sessions de verrouillage actives du propriétaire du jeton et sont destinés aux scripts/programmes d'API externes, et non aux sessions d'extensions tierces installées.

  • GET https://chastify.net/api/apps/v1/session
  • GET https://chastify.net/api/apps/v1/state
  • PUT https://chastify.net/api/apps/v1/state
  • PATCH https://chastify.net/api/apps/v1/state
  • GET https://chastify.net/api/apps/v1/metadata
  • PATCH https://chastify.net/api/apps/v1/metadata
  • POST https://chastify.net/api/apps/v1/action
  • POST https://chastify.net/api/apps/v1/lock/apply-time
  • POST https://chastify.net/api/apps/v1/lock/freeze
  • POST https://chastify.net/api/apps/v1/lock/unfreeze
  • POST https://chastify.net/api/apps/v1/logs/custom

Commandes du pont Iframe

Les commandes du pont sont envoyées par iframe (chastify:ext:req) et acheminées par le parent Chastify. Le pont est volontairement limité aux opérations d'interface utilisateur sécurisées/de session.

  • session.get -> GET https://chastify.net/api/extensions/sessions/:sessionId
  • state.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/state
  • files.capabilities -> GET https://chastify.net/api/extensions/sessions/:sessionId/files/capabilities
  • files.list -> GET https://chastify.net/api/extensions/sessions/:sessionId/files
  • files.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/files/:fileId avec { "fileId": "file_record_id" }
  • metadata.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/metadata
  • regularActions.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/regular-actions

Les points de terminaison de modification de session sont des appels directs à l'API du serveur, et non des commandes de pont iframe. Cela inclut les modifications d'état, la soumission d'actions classiques et le chargement/la suppression de fichiers en cours d'exécution, car le code iframe peut être contrôlé par l'utilisateur.

Exemples d'API de session côté serveur

Votre serveur dorsal doit envoyer les deux en-têtes pour les appels privilégiés d'extension installée :

Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH

Exemples d'actions côté serveur :

  • metadata.patch -> PATCH /api/extensions/sessions/:sessionId/metadata
  • regularActions.submit -> POST /api/extensions/sessions/:sessionId/regular-actions
  • files.upload -> POST /api/extensions/sessions/:sessionId/files
  • files.delete -> DELETE /api/extensions/sessions/:sessionId/files/:fileId
  • lock.applyTime -> POST /api/extensions/sessions/:sessionId/action avec { "name": "add_time", "params": <deltaSeconds> }
  • lock.freeze -> POST /api/extensions/sessions/:sessionId/action avec { "name": "freeze", "params": { "durationSeconds": 900 } }
  • lock.unfreeze -> POST /api/extensions/sessions/:sessionId/action avec { "name": "unfreeze", "params": {} }
  • lock.settings.patch -> POST /api/extensions/sessions/:sessionId/action avec { "name": "settings.patch", "params": { ... } }
  • task.assign -> POST /api/extensions/sessions/:sessionId/action
  • task.start_timer -> POST /api/extensions/sessions/:sessionId/action avec { "name": "task.start_timer", "params": {} }
  • task.complete -> POST /api/extensions/sessions/:sessionId/action avec { "name": "task.complete", "params": { "successful": true } }
  • hygienic_unlock.start -> POST /api/extensions/sessions/:sessionId/action avec { "name": "hygienic_unlock.start", "params": { "durationSeconds": 900 } }
  • pillory.end -> POST /api/extensions/sessions/:sessionId/action avec { "name": "pillory.end", "params": {} }
  • device.command -> POST /api/extensions/sessions/:sessionId/device-command
  • logs.custom -> POST /api/extensions/sessions/:sessionId/logs/custom
  • notifications.custom -> POST /api/extensions/sessions/:sessionId/notifications/custom
  • requirements.progress -> POST /api/extensions/sessions/:sessionId/requirements/progress

Jeton, portée, révocation et comportement d'audit

Utilisez le jeton approprié pour la limite de confiance appropriée.

attention

Les clés API développeur sont des informations confidentielles. Si l'une d'elles est exposée dans le code du navigateur, révoquez-la immédiatement et renouvelez la variable d'environnement côté serveur.

Jeton de lancement d'iframe (mainToken)

  • Livré dans le hachage de l'iframe lorsqu'un utilisateur ouvre une page d'extension installée.
  • Conçu pour être visible par le navigateur, il identifie la session d'extension ouverte, mais ne constitue pas une information confidentielle du serveur.
  • Durée de vie limitée. Les jetons de lancement actuels expirent après 10 heures ; actualisez-les en rouvrant la page de l’extension.
  • Requis sous la forme x-chastify-main-token lorsque votre backend appelle les routes de session d'extension installée, afin que Chastify puisse lier la requête backend à l'utilisateur/session qui a ouvert l'extension.
  • Ne doit pas être utilisé seul pour autoriser les changements d'heure, le déverrouillage de la fin du blocage, l'achèvement des tâches, les commandes de l'appareil, les téléchargements/suppressions en cours d'exécution, les journaux personnalisés ou les notifications personnalisées.

Clé API développeur à portée de l'application

  • Créé à partir de l'interface utilisateur développeur pour une application d'extension.
  • Secret réservé au backend. Ne l'intégrez jamais dans du JavaScript iframe, des bundles d'applications mobiles, une configuration d'hébergement statique ou des journaux lisibles par le navigateur.
  • Utilisé avec Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY et x-chastify-main-token.
  • Les API de session d'extension installée ne peuvent être appelées que pour les sessions correspondant à l'application d'extension et au jeton de lancement.
  • Ne s'expire pas automatiquement. Révoquez-le immédiatement s'il est exposé et changez régulièrement votre variable d'environnement backend.

Clé API développeur pour l'ensemble de l'utilisateur

  • Créé à partir de l'interface utilisateur du développeur sans sélectionner d'application d'extension.
  • Secret réservé au backend pour /api/apps/v1/*.
  • Contrôle les sessions de verrouillage actives actuelles et futures du propriétaire de la clé.
  • Ne peut pas être utilisé comme identifiant d'accès au serveur d'une extension tierce installée.

Révocation

  • Les clés API développeur révoquées cessent d'autoriser les nouvelles requêtes.
  • Les clés révoquées peuvent être supprimées définitivement de l'interface utilisateur du développeur.
  • Chaque nouvelle iframe reçoit un nouveau jeton de lancement. Ne conservez pas mainToken comme identifiant permanent.

Portées et rôles

  • Les étendues d'application d'extension décrivent ce que l'application est autorisée à demander.
  • Les appels de pont iframe sécurisés sont limités à l'initialisation de l'interface utilisateur, aux lectures de session, à l'état appartenant à l'extension, aux lectures de métadonnées, aux lectures d'actions régulières et aux lectures de fichiers.
  • Les mutations de session installée privilégiées nécessitent des informations d'identification du serveur dorsal même lorsque l'extension a une portée correspondante.
  • Les actions sensibles au rôle peuvent toujours être rejetées selon que le lancement appartienne à un porteur ou à un détenteur de clé.

Audit et limites

  • Les métadonnées relatives à la dernière utilisation des clés API développeur sont mises à jour lorsque les clés sont utilisées.
  • Les routes d'action privilégiées sont soumises à une limitation de débit et renvoient des erreurs explicites telles que server_credentials_required ou user_wide_dev_key_required lorsqu'un type d'identifiant incorrect est utilisé.
  • Les journaux personnalisés enregistrent des entrées d'historique de verrouillage visibles.
  • Les notifications personnalisées créent des notifications Chastify pour la cible demandée.
  • Une couverture d'audit complète pour chaque mutation d'extension privilégiée est suivie en tant qu'élément de renforcement de la sécurité en production.

Valeurs de commande prises en charge

/api/extensions/sessions/:sessionId/action et /api/apps/v1/action

name prend en charge :

  • add_time
  • remove_time
  • freeze
  • pillory
  • unfreeze
  • toggle_freeze
  • settings.patch
  • task.assign
  • task.start_timer
  • task.complete
  • hygienic_unlock.start
  • pillory.end

Contraintes d'action :

  • Les actions de tâche nécessitent l'activation de l'extension/du module Tâches sur le verrou.
  • hygienic_unlock.start nécessite l'activation de l'ouverture hygiénique et l'absence de session d'hygiène active.

Assistants de données de verrouillage session.get

session.get / GET /api/apps/v1/session inclut également lockData avec des booléens, des nombres et des chaînes de caractères adaptés à l'exécution pour les moteurs de règles.

Exemples :

  • booléens : frozen, unlockable, trusted, taskAssigned (true lorsqu’un TaskRun ouvert existe)
  • numéros : timeLockedSeconds, timeRemainingSeconds, maxTimeRemainingSeconds, taskPoints
  • chaînes de caractères : lockTitle, champs du profil du porteur/détenteur de la clé

Confidentialité:

  • wearerLastSeenTimestamp et keyholderLastSeenTimestamp sont null lorsque cet utilisateur a désactivé le statut en ligne (showOnlineStatus === false).

Commandes de l'appareil

Les sessions d'extension peuvent utiliser le point de terminaison basé sur la session :

POST /api/extensions/sessions/:sessionId/device-command

Les programmes externes disposant d'un jeton DEV peuvent utiliser le point de terminaison v1 plus simple (aucun ID de session requis) :

POST /api/apps/v1/device-command

Les deux acceptent le même corps de requête et renvoient la même réponse. Consultez la section API externes et programmes pour plus de détails.

Si votre extension possède une interface utilisateur de configuration :

  1. Le parent envoie chastify:ext:setup:init (configuration enregistrée + contexte).
  2. Votre iframe de configuration renvoie des mises à jour avec chastify:ext:setup:config.
  3. Le parent peut demander la configuration actuelle avec chastify:ext:setup:get_config.

Flux de jetons côté serveur (lorsque vous avez besoin d'appels côté serveur)

Pour les scripts simples et les programmes externes, utilisez un jeton DEV global depuis la page API développeur. Voir API externe et programmes.

Flux par défaut en mode iframe d'extension :

  1. Chastify émet un jeton de lancement éphémère visible dans le navigateur pour la session d'extension active.
  2. Le jeton de lancement est intégré dans la charge utile de hachage de l'iframe sous la forme mainToken.
  3. Votre iframe redirige mainToken vers votre serveur.
  4. Votre système dorsal appelle https://chastify.net/api/extensions/sessions/:sessionId/* avec Authorization: Bearer <app-scoped Developer API key> et x-chastify-main-token: <mainToken>.

Ne transmettez pas les clés API développeur au code iframe/navigateur. mainToken identifie la session d'extension ouverte ; il ne s'agit pas d'un secret du serveur et il ne peut être utilisé seul pour des actions privilégiées.

Solution de repli manuelle :

  • Si vous devez récupérer/faire tourner explicitement le jeton de lancement iframe depuis l'interface utilisateur de première partie, appelez GET https://chastify.net/api/extensions/sessions/:sessionId/auth.

Utilisez le mode backend si vous avez besoin de tâches planifiées, de webhooks ou d'automatisation lorsque la page Chastify est fermée. Les mutations de session des extensions installées nécessitent toujours un jeton de lancement iframe valide de 10 heures ; par conséquent, les tâches sans surveillance doivent stocker la preuve en attente et la soumettre lors du prochain lancement valide, sauf si vous utilisez un flux serveur interne conçu pour une exécution en arrière-plan.

info

Pour un fonctionnement entièrement automatisé en production, privilégiez un flux serveur intégré ou attendez l'autorisation explicite d'extensions en arrière-plan. Les API de session à portée applicative sont actuellement liées au jeton de lancement.

Backend vs Pages Cloudflare (sans serveur)

Utilisez Cloudflare Pages (sans serveur backend) lorsque :

  • Vous souhaitez la configuration la plus simple et la moins chère (hébergement gratuit possible).
  • Vous n'avez besoin d'actions pilotées par l'interface utilisateur que lorsque l'utilisateur est activement sur la page de votre extension.
  • Vous n'avez pas besoin d'écritures d'état d'extension persistantes sur le serveur.
  • Vous créez rapidement des prototypes ou des extensions légères.

Exemple de test local (PowerShell) :

cloudflared tunnel --url http://localhost:5174

Utilisez l'URL publique générée comme URL de votre iframe lors des tests.

Utilisez un serveur backend lorsque :

  • Vous avez besoin de tâches planifiées (comportement similaire à cron).
  • Vous avez besoin de webhooks ou d'intégrations externes.
  • Vous avez besoin d'un traitement automatisé/en arrière-plan lorsque personne ne consulte la page de l'extension.
  • Vous avez besoin de flux de travail contrôlés par serveur qui doivent fonctionner en continu.

Limitation importante en l'absence de serveur dorsal :

  • Aucune exécution en arrière-plan. Votre extension ne peut agir que si l'utilisateur a actuellement l'iframe de l'extension ouverte et interagit avec elle.

Problèmes courants

  • 403 extension_not_enabled : l’extension n’est pas activée pour cette serrure.
  • 409 lock_ended : le verrou n’est plus actif.
  • 429 : limite de débit atteinte.
  • Aucune réponse dans l'iframe : vérifiez nonce, targetOrigin (parentOrigin) et les origines autorisées.

Guides suivants