API Console

La même API que celle que nous utilisons dans notre console est disponible via HTTP avec une authentification par clé API. Vous pouvez utiliser cette API pour automatiser certaines de vos tâches ou créer votre propre mini-console. Cette API vous permet d'accéder aux données et d'effectuer des actions sur un site web spécifique. Les points de terminaison au niveau du compte, comme la création d'un nouveau site web ou la gestion de l'abonnement et de la facturation, ne sont pas disponibles.

Pour commencer

  • CrĂ©ez une clĂ© API Console dans Console → Paramètres → API.
  • Dans chaque requĂŞte, dĂ©finissez l'en-tĂŞte X-API-KEY avec la clĂ© API que vous avez créée.
  • L'URL de base est https://talk.hyvor.com/api/console/v1/{website_id}
  • Tous les points de terminaison nĂ©cessitent website_id dans l'URL. Vous trouverez l'ID de votre site web dans la console.
  • Tous les points de terminaison renvoient des donnĂ©es JSON. La rĂ©ponse sera un objet ou un tableau d'objets.
  • Les mĂ©thodes HTTP sont les suivantes :
    • GET - Lire une ressource ou une liste de ressources
    • POST - CrĂ©er une ressource ou effectuer une action
    • PATCH - Mettre Ă  jour une ressource
    • DELETE - Supprimer une ressource
  • Les paramètres de requĂŞte peuvent ĂŞtre dĂ©finis en JSON (recommandĂ©) ou en application/x-www-form-urlencoded.

Authentification de l'utilisateur

Par défaut, l'API Console est authentifiée en tant que propriétaire du site web, ce qui donne accès à tous les points de terminaison. De plus, lorsqu'une action est effectuée, elle est enregistrée comme effectuée par le propriétaire. Par exemple, si vous modérez un commentaire via l'API, l'historique du commentaire indiquera qu'il a été modéré par le propriétaire du site web. Vous pouvez cependant changer l'utilisateur authentifié.

Pour vous authentifier en tant qu'un autre modérateur, définissez l'un des en-têtes suivants :

  • X-AUTH-USER-EMAIL - E-mail du compte HYVOR de l'utilisateur en tant que lequel s'authentifier.
  • X-AUTH-USER-SSO-ID - Si vos modĂ©rateurs sont connectĂ©s Ă  un compte SSO, vous pouvez utiliser l'ID de l'utilisateur SSO (dans votre système) pour vous authentifier en tant que cet utilisateur.

Notez que l'utilisateur doit être modérateur du site web pour pouvoir s'authentifier en tant que lui.

Catégories

Accéder à chaque catégorie

Dans cette documentation, nous utilisons la syntaxe TypeScript pour décrire les objets de requête et de réponse. Par exemple, type Response = { id: number } signifie que la réponse sera un objet avec une propriété id de type number.

Site web

Points de terminaison :

Objets :

Récupérer les données du site web

type Request = {}
type Response = Website

Mettre à jour les données du site web

type Request = Website // sauf id
type Response = Website

Commentaires

Points de terminaison :

Objets :

Récupérer les commentaires

GET /comments
type Request = {
    type: null | 'published' | 'pending' | 'deleted' | 'spam' | 'flagged',

    // filtrer par page
    page_id: number | null,
    page_identifier: string | null, // page-id défini dans l'embed

    // filtrer par utilisateur
    user_htid: string | null, // ID avec type : hyvor_100 | sso_100,
    user_sso_id: string | null, // ID de l'utilisateur SSO

    // filtrer par IP
    ip_address: string | null,

    // filtrer par badge de l'utilisateur
    badge_id: number | null,

    // filtrer par d'autres propriétés du commentaire
    filter: null | 'unread' | 'unreplied' | 'guest' | 'has_questions' | 'has_links' | 'has_media',

    // rechercher par texte du commentaire
    search: string | null,

    limit: number | null, // par défaut : 50, max: 100
    offset: number | null, // par défaut : 0
    before_id: number | null // pour la pagination (Ă  la place de offset)
}

type Response = Comment[]

Remarque : si vous définissez le paramètre search , badge_id et type=flagged seront ignorés.

Récupérer le nombre de commentaires non lus

Nombre de commentaires non lus par les modérateurs (has_mod_seen = 0) pour chaque statut. Le total est la somme de tous les statuts.

GET /comments/unread-counts
type Request = {};
type Response = {
    published: number,
    pending: number,
    spam: number,
    deleted: number
}

Marquer des commentaires comme lus

Marque des commentaires comme lus par les modérateurs (has_mod_seen = 1). Si le statut est défini, seuls les commentaires de ce statut seront marqués comme lus. Sinon, tous les commentaires seront marqués comme lus. Ce processus est asynchrone.

POST /comments/read
type Request = {
    status: null | 'published' | 'pending' | 'deleted' | 'spam'
}
type Response = {}

Publier un commentaire

Publie un commentaire en tant qu'utilisateur SSO ou invité. Il n'est pas possible de publier en tant qu'utilisateur HYVOR.

POST /comment
type Request = {
    page_id: number | null,
    page_identifier: string | null, // page-id défini dans l'embed
    body: string | null,    // au format JSON ProseMirror
    body_html: string | null,   // au format HTML
    user_sso_id: string | null,
    guest_name: string | null,
    guest_email: string | null,
    parent_id: number | null,
    created_at: number | null, // timestamp UNIX
    ip: string | null,

    check_premoderation: boolean,   // par défaut : true
    spam_detection: boolean,    // par défaut : true
    rules: boolean   // par défaut : true
}
type Response = Comment
  • L'un des deux, page_id ou page_identifier est requis.
  • L'un des deux, body ou body_html est requis.
  • L'un des deux, user_sso_id ou guest_name est requis. user_sso_id est l'ID dans votre système.
  • check_premoderation = false contourne la prĂ©-modĂ©ration.
  • spam_detection = false contourne la dĂ©tection du spam.
  • rules = false contourne les règles.

Trouvez plus d'informations sur le format ProseMirror JSON .

Récupérer un commentaire

GET /comment/{id}
type Request = {}
type Response = Comment

Mettre Ă  jour un commentaire

PATCH /comment/{id}
type Request = {
    status: null | 'published' | 'pending' | 'deleted' | 'spam',
    is_featured: boolean | null,
    is_loved: boolean | null,
    has_mod_seen: boolean | null,
    body: string | null,    // au format JSON ProseMirror
    body_html: string | null,   // au format HTML
    created_at: number | null, // timestamp UNIX,
    guest_name: string | null,
    guest_email: string | null,

    // Pris en compte uniquement si body ou body_html est défini
    is_author: boolean,     // par défaut : false
    check_premoderation: boolean,   // par défaut : true
    spam_detection: boolean,    // par défaut : true
    rules: boolean      // par défaut : true
}
type Response = Comment
  • L'un des deux, body ou body_html est requis.
  • is_author = true marque la mise Ă  jour comme effectuĂ©e par l'auteur du commentaire. Sinon, elle sera marquĂ©e comme effectuĂ©e par l' utilisateur API authentifiĂ© (un modĂ©rateur).
  • check_premoderation = false contourne la prĂ©-modĂ©ration.
  • spam_detection = false contourne la dĂ©tection du spam.
  • rules = false contourne les règles.

Trouvez plus d'informations sur le format ProseMirror JSON .

Supprimer un commentaire

DELETE /comment/{id}
type Request = {}
type Response = {}

Répondre à un commentaire

Par défaut, le compte du propriétaire du site web est utilisé pour répondre. Consultez Authentification de l'utilisateur pour le personnaliser.

POST /comment/{id}/reply
type Request = {
    body: string // au format ProseMirror
}
type Response = Comment;

Voter sur un commentaire

Par défaut, le compte du propriétaire du site web est utilisé pour voter. Consultez Authentification de l'utilisateur pour le personnaliser. Si user_sso_id est défini, le compte de l'utilisateur correspondant sera utilisé.

POST /comment/{id}/vote
type Request = {
    type: 'up' | 'down' | null // null pour supprimer un vote
    user_sso_id: string | null
}
type Response = Comment;

Récupérer les votants d'un commentaire

GET /comment/{id}/voters
type Request = {
    type: 'up' | 'down',
    limit: number | null, // par défaut : 25, max: 100
    offset: number|null // par défaut : 0
};
type Response = LoggedInUser[]

Supprimer un vote sur un commentaire

DELETE /comment/{id}/vote
type Request = {
    user_htid: string // ID de l'utilisateur ayant voté, obligatoire. Ex : hyvor_100 | sso_100
}
type Response = {}

Récupérer les signalements d'un commentaire

GET /comment/{id}/flags
type Request = {
    limit: number | null, // par défaut : 25, max: 100
    offset: number | null // par défaut : 0
};
type Response = Flag[]

Créer un signalement sur un commentaire

POST /comment/{id}/flags
type Request = {
    reason: string | null
    user_sso_id: string | null
};
type Response = Comment

Définissez user_sso_id pour signaler en tant qu'utilisateur SSO spécifique. Sinon, l' utilisateur API Console courant sera utilisé.

Supprimer un signalement sur un commentaire

DELETE /comment/{id}/flag
type Request = {
    flag_id: number // ID du signalement Ă  supprimer
}
type Response = {}

Modérer plusieurs commentaires

POST /comments/bulk-moderate
type Request = {
    // un seul parmi user_htid/user_sso_id, ip_address ou comment_ids doit être défini

    user_htid: string | null, // ID avec type : hyvor_100 | sso_100
    user_sso_id: string | null, // ID de l'utilisateur SSO

    ip_address: string | null,
    comment_ids: number[] | null,
    status: 'published' | 'pending' | 'deleted' | 'spam'
}
type Response = {}

Réactions

Points de terminaison :

Objets :

Récupérer les réactions

GET /reactions
type Request = {
    page_id: number | null,

    user_htid: string | null, // ID avec type : hyvor_100 | sso_100
    user_sso_id: string | null, // ID de l'utilisateur SSO

    type: null | 'superb' | 'love' | 'wow' | 'sad' | 'laugh' | 'angry',
    limit: number | null, // par défaut : 50, max: 100
    offset: number | null // par défaut : 0
}
type Response = Reaction[]

Supprimer une réaction

DELETE /reaction/{id}
type Request = {}
type Response = {}

Notes

Points de terminaison :

Objets :

Récupérer les notes

GET /ratings
type Request = {
    page_id: number | null,

    user_htid: string | null, // ID avec type : hyvor_100 | sso_100
    user_sso_id: string | null, // ID de l'utilisateur SSO

    rating: number | null, // min : 1, max : 5
    limit: number | null, // par défaut : 50, max: 100
    offset: number | null // par défaut : 0
}
type Response = Rating[]

Supprimer une note

DELETE /rating/{id}
type Request = {}
type Response = {}

Pages

Points de terminaison :

{id} dans l'URL

Par défaut, {id} est l'ID de la page défini par Hyvor Talk (interne). Vous le trouverez dans l' Objet Page. Cependant, dans la plupart des cas, vous voudrez utiliser l' page-id attribut que vous avez défini dans l'embed. Pour cela, définissez l'en-tête HTTP X-ID-Type sur page_id.

Objets :

Récupérer les pages

GET /pages
type Request = {
    search: string | null, // rechercher par titre ou identifiant
    filter: null | 'open' | 'closed' | 'premoderation_on',
    sort: null | 'newest' | 'oldest' | 'recently_commented' | 'most_commented' | 'most_reactions' | 'most_ratings', // par défaut : newest
    limit: number | null, // par défaut : 25, max: 100
    offset: number | null // par défaut : 0
}
type Response = Page[];

Créer une page

Crée une nouvelle page avec l'identifiant donné. Si une page avec le même identifiant existe déjà, elle sera mise à jour avec les données fournies.

POST /page
type Request = {
    identifier: string, // identifiant unique de la page (page-id)
    url: string, // URL de la page
    title: string | null,
    author_email: string | null,
    created_at: number | null // timestamp UNIX
}
type Response = Page;

Mettre Ă  jour une page

PATCH /page/{id}
type Request = {
    is_closed: boolean | null,
    is_premoderation_on: boolean | null
    author_email: string | null
}
type Response = Page;

Réinitialiser les données d'une page

Ce point de terminaison réinitialise les données de la page demandée (commentaires/réactions/notes). À utiliser avec précaution. Il n'est pas possible d'annuler.

POST /page/{id}/reset

type Request = {
    is_closed: boolean | null,
    is_premoderation_on: boolean | null
}
type Response = Page;

Déplacer les données d'une page

Utilisez ce point de terminaison pour déplacer toutes les données d'une page vers une autre. C'est utile lorsque vous modifiez l' page-id attribut de l'embed.

POST /page/{id}/move
type Request = {
    to_page_id: number,
}

type Response = {};

Supprimer une page

Ce point de terminaison supprime toutes les données de la page (commentaires, réactions, notes) ainsi que la page elle-même. À utiliser avec précaution. Il n'est pas possible d'annuler.

DELETE /page/{id}

type Request = {}
type Response = {}

Utilisateurs

Points de terminaison :

{id} dans l'URL

Par défaut, {id} est la propriété htid de l' objet User. Si vous utilisez l'authentification unique, il est logique d'utiliser l'ID de l'utilisateur dans votre système. Pour cela, définissez l'en-tête HTTP X-ID-Type sur sso_user_id.

Objets :

Récupérer les utilisateurs

GET /users
type Request = {
    search: string | null,
    badge_id: number | null,
    plan_id: number | null,
    last_ip_address: string | null,
    state: null | 'default' | 'banned' | 'shadowed' | 'trusted', // par défaut : null
    sort: null | 'recently_commented' | 'most_commented' | 'recently_seen' | 'recently_joined', // par défaut : recently_commented
    limit: number | null, // par défaut : 25, max: 100
    offset: number | null // par défaut : 0
}
type Response = LoggedInUser[]

search peut être utilisé pour filtrer les utilisateurs :

  • par nom
  • par nom d'utilisateur HYVOR exact (utilisateurs HYVOR uniquement)
  • par e-mail exact (utilisateurs SSO uniquement)
  • par ID SSO exact

Récupérer un utilisateur

GET /user/{id}
type Request = {}
type Response = LoggedInUser

Mettre Ă  jour un utilisateur

PATCH /user/{id}
type Request = {
    state: null | 'default' | 'banned' | 'shadowed' | 'trusted',
    state_ends_at: number | null, // timestamp UNIX auquel les utilisateurs bannis sont automatiquement débannis
    note: string | null,
    badge_ids: number[] | null,
    badge_ids_strategy: null | 'overwrite' | 'merge' | 'remove' // par défaut : 'overwrite'
}
type Response = LoggedInUser

Récupérer le nombre de commentaires et de signalements d'un utilisateur

GET /user/{id}/counts
type Request = {}
type Response = {
    comments: {
        total: number,
        published: number,
        pending: number,
        spam: number,
        deleted: number
    },
    flags: {
        received: number,
        given: number
    }
}

Supprimer un utilisateur

DELETE /user/{id}
type Request = {
    data: boolean // définir à true pour supprimer l'utilisateur avec toutes ses données
}
type Response = {}

Récupérer le statut d'abonnement aux notifications par e-mail d'un utilisateur

GET /user/{id}/email-notification
type Request = {}
type Response = {
    reply: boolean,
    mention: boolean
}

Mettre Ă  jour le statut d'abonnement aux notifications par e-mail d'un utilisateur

POST /user/{id}/email-notification
type Request = {
    reply: boolean | null,
    mention: boolean | null
}
type Response = {}

Statistiques

Points de terminaison :

Récupérer les statistiques du site web

GET /analytics/stats
type Request = {}
type Response = {
    comments: {
        total: number,
        last_30d: number
    },
    users: {
        total: number,
        last_30d: number
    },
    members: {
        total: number,
        last_30d: number
    }
}

Récupérer les statistiques de crédits

GET /analytics/credits
type Request = {
    event: null | 'embed_comments' | 'embed_gated_content' | 'embed_comment_counts'  | 'email_notifications' |
            'spam_detection_akismet' | 'spam_detection_fortguard' | 'api_data',
    start_timestamp: number | null,
    end_timestamp: number | null,
    group_by: 'day' | 'week' | 'month' | 'year'
}
type Response = {
    timeseries: [
        {
            date: string, // AAAA-MM-JJ 00:00:00,
            credits: number,
            events: number
        },
        ...
    ]
}

Récupérer les statistiques de commentaires

GET /analytics/comments
type Request = {
    start_timestamp: number | null,
    end_timestamp: number | null,
    group_by: 'day' | 'week' | 'month' | 'year'
}
type Response = {
    timeseries: [
        {
            date: string, // AAAA-MM-JJ 00:00:00,
            count: number,
            published: number,
            pending: number,
            spam: number,
            deleted: number
        },
        ...
    ]
}

Modérateurs

Les modérateurs peuvent accéder à la console pour modérer les commentaires/utilisateurs et modifier les paramètres de votre site web.

Points de terminaison :

Objets :

Récupérer les modérateurs

GET /mods
type Request = {}
type Response = Mod[]

Mettre à jour un modérateur

PATCH /mod/{id}
type Request = {
    role: null | 'mod' | 'admin',
    sso_user_htid: string | null, // ID avec type : hyvor_100 | sso_100
    is_alias_used: boolean | null
}
type Response = Mod

role : vous pouvez changer le rôle d'un mod en admin, et inversement. Le rôle du propriétaire ne peut pas être modifié. Consultez le point de terminaison make-owner pour transférer la propriété du site web.

sso_user_htid : si votre site web utilise le SSO, vous pouvez définir sso_user_htid pour connecter le modérateur à un utilisateur SSO. Cela lui permettra de modérer les commentaires dans l'embed. De plus, lorsqu'il répond depuis la console, son compte SSO sera utilisé à la place de son compte HYVOR.

is_alias_used : si vous avez configuré un alias pour votre site web, les commentaires de ce modérateur seront publiés avec l'alias. C'est utile si vous souhaitez publier des commentaires au nom de votre site web.

Supprimer un modérateur

DELETE /mod/{id}
type Request = {}
type Response = {}

Faire d'un modérateur le propriétaire

Ce point de terminaison fait du modérateur donné le propriétaire du site web. Le propriétaire actuel sera rétrogradé au rang d'admin. Seul le propriétaire actuel peut accéder à ce point de terminaison.

POST /mod/{id}/make-owner
type Request = {}
type Response = {}

Récupérer les invitations de modérateurs

GET /mod-invites
type Request = {}
type Response = ModInvite[]

Inviter un modérateur

Tous les modérateurs doivent avoir un compte HYVOR. username ou email est le nom d'utilisateur/e-mail du compte HYVOR du modérateur. Un e-mail d'invitation sera envoyé à l'utilisateur, qui deviendra modérateur/admin une fois l'invitation acceptée.

POST /mod-invite
type Request = {
    // soit username, soit email est requis
    username: string | null,
    email: string | null,
    role: 'mod' | 'admin',
}
type Response = ModInvite

Renvoyer une invitation de modérateur

POST /mod-invite/{id}/resend
type Request = {}
type Response = {}

Supprimer une invitation de modérateur

DELETE /mod-invite/{id}
type Request = {}
type Response = {}

Abonnements

Points de terminaison :

Objets :

Récupérer le statut Stripe

GET /memberships/stripe/connect
type Request = {}
type Response = {
    is_connected: boolean,
    data: StripeConnect | null
}

Récupérer l'URL d'intégration Stripe

POST /memberships/stripe/connect/
type Request = {}
type Response = {
    url: string // rediriger ici pour l'intégration Stripe
}

Récupérer les forfaits d'abonnement

GET /membership-plans
type Request = {}
type Response = Plan[]

Créer un forfait d'abonnement

Un site web peut avoir au maximum 3 forfaits d'abonnement.

POST /membership-plan

type Request = {
    name: string,
    description: string | null,
    features: string | null, // longueur max. : 1024
    monthly_price: number, // min : 1, max : 9999 Ex : 4.99
    badge_id: number | null
}
type Response = Plan

Mettre Ă  jour un forfait d'abonnement

PATCH /membership-plan/{id}
type Request = {
    name: string | null,
    description: string | null,
    features: string | null, // longueur max. : 1024
    monthly_price: number | null, // min : 1, max : 9999 Ex : 4.99
    badge_id: number | null
}
type Response = Plan

Supprimer un forfait d'abonnement

DELETE /membership-plan/{id}
type Request = {}
type Response = {}

Récupérer le contenu réservé

GET /memberships/gated-content
type Request = {
    limit: number | null, // par défaut : 10, max: 100
    offset: number | null // par défaut : 0
}
type Response = GatedContent[]

Créer du contenu réservé

POST /memberships/gated-content
type Request = {
    key: string, // la clé doit être unique
    content: string, // longueur max. : 60 000
    gate: string | null, // longueur max. : 60 000
    minimum_plan_id: number | null
}
type Response = GatedContent

Mettre à jour du contenu réservé

PATCH /memberships/gated-content/{id}
type Request = {
    key: string | null, // la clé doit être unique
    content: string | null, // longueur max. : 60 000
    gate: string | null, // longueur max. : 60 000
    minimum_plan_id: number | null
}
type Response = GatedContent

Supprimer du contenu réservé

DELETE /memberships/gated-content/{id}
type Request = {}
type Response = {}

Domaine d'e-mail

Points de terminaison :

Objets :

Créer un domaine d'e-mail

POST /email/domain
type Request = {
    domain: string // Ex : example.com
}
type Response = EmailDomain

Vérifier un domaine d'e-mail

POST /email/domain/verify
type Request = {}
type Response = {
    data: {
        verified: string,
        debug: string | null
    },
    domain: EmailDomain
}

Supprimer un domaine d'e-mail

DELETE /email/domain
type Request = {}
type Response = {}

Règles

Règles servent à automatiser la modération.

Points de terminaison :

Objets :

Récupérer les règles

GET /rules
type Request = {}
type Response = Rule[]

Créer une règle

POST /rule
type Request = Rule // sauf id
type Response = Rule

Mettre à jour une règle

PATCH /rule/{id}
type Request = Rule // sauf id
type Response = Rule

Supprimer une règle

DELETE /rule/{id}
type Request = {}
type Response = {}

Journaux d'e-mails

Points de terminaison :

Objets :

Récupérer les journaux d'e-mails

GET /email-logs
type Request = {
    type: null | 'reply' | 'mention' | 'mod' | 'author',

    user_htid: string | null, // ID avec type : hyvor_100 | sso_100
    user_sso_id: string | null,

    limit: number | null, // par défaut : 50, max: 100
    offset: number | null // par défaut : 0
}
type Response = EmailLog[]

IP

Les modérateurs peuvent bloquer des utilisateurs au niveau de l'adresse IP.

Points de terminaison :

Objets :

Récupérer les adresses IP

Ce point de terminaison ne renvoie que les adresses IP qui ont été bannies, bannies en secret, de confiance, ou pour lesquelles une note a été ajoutée.

GET /ips

type Request = {
    limit: number | null, // par défaut : 25, max: 100
    offset: number | null // par défaut : 0
};
type Response = IP[]

Récupérer une adresse IP

GET /ip/{ip}
type Request = {}
type Response = IP

Modifier l'état d'une adresse IP

PATCH /ip/{ip}
type Request = {
    state: null | 'default' | 'banned' | 'shadowed' | 'trusted',
    note: string | null,
    state_ends_at: number | null
}
type Response = IP

Domaines

Points de terminaison :

Objets :

Récupérer les domaines

GET /domains
type Request = {}
type Response = Domain[]

Créer un domaine

POST /domain
type Request = {
    domain: string
}
type Response = Domain

Mettre Ă  jour un domaine

PATCH /domain/{id}
type Request = {
    domain: string
}
type Response = Domain

Supprimer un domaine

DELETE /domain/{id}
type Request = {}
type Response = {}

Badges

Points de terminaison :

Objets :

Récupérer les badges

GET /badges
type Request = {}
type Response = Badge[]

Créer un badge

POST /badge
type Request = {
    text: string, // longueur max. : 50
    color: string, // code couleur hexadécimal Ex : #ff0000
    background_color: string, // code couleur hexadécimal Ex : #0000ff
    icon_url: string | null
}
type Response = Badge

Mettre Ă  jour un badge

PATCH /badge/{id}
type Request = {
    text: string | null, // longueur max. : 50
    color: string | null,  // code couleur hexadécimal Ex : #ff0000
    background_color: string, | null // code couleur hexadécimal Ex : #0000ff
    icon_url: string | null
}
type Response = Badge

Supprimer un badge

DELETE /badge/{id}
type Request = {}
type Response = {}

Authentification unique

Points de terminaison :

Objets :

Récupérer les utilisateurs SSO

GET /sso/users
type Request = {
    limit: number | null, // par défaut : 50, max: 100
    offset: number | null, // par défaut : 0
    search: string | null // rechercher par nom, e-mail ou ID donné
}
type Response = LoggedInUser[]

Créer ou mettre à jour des utilisateurs SSO

POST /sso/user
type Request = {
    id: string,
    name: string,
    email: string,
    picture_url: string | null,
    title: string | null,
    website_url: string | null,
    bio: string | null,
    location: string | null,
}
type Response = LoggedInUser

Supprimer un utilisateur SSO

DELETE /sso/user
type Request = {
    id: string,
    data: boolean | null // par défaut : false
}
type Response = {}

id est l'ID de l'utilisateur dans votre système. Par défaut, seules les données de profil de l'utilisateur sont supprimées. Tous les commentaires de l'utilisateur seront affichés sous le nom « Utilisateur anonyme ». Définissez {data: true}, si vous souhaitez supprimer également les commentaires de l'utilisateur.

Tâches

Points de terminaison :

Objets :

Récupérer les tâches

GET /jobs
type Request = {
    type: null | 'import_comments' | 'import_newsletter_subscribers' | 'export' | 'bulk_moderate_comments'
}
type Response = Job[]

Importer des commentaires

Consultez la documentation sur l'import pour plus de détails. L'import est asynchrone. Nous préviendrons le propriétaire du site web par e-mail lorsqu'il sera terminé.

POST /data/import/comments
type Request = {
    file: File,
    format: 'wordpress' | 'disqus' | 'hyvor',
    identifier_type: null | 'post_id' | 'relative_path' | 'absolute_url'
}
type Response = Job

Exporter les données

Consultez la documentation sur l'export. L'export est asynchrone. Nous enverrons par e-mail à l'adresse donnée (celle du propriétaire si elle est vide) un lien pour télécharger le fichier lorsqu'il sera prêt.

POST /data/export
type Request = {
    format: 'hyvor_talk_json' | 'wordpress_xml' | 'newsletter_subscribers_csv',
    from: number | null, // timestamp UNIX, filtre les commentaires par date (borne inférieure)
    to: number | null, // timestamp UNIX, filtre les commentaires par date (borne supérieure)
    email: string | null // si vide, l'e-mail du propriétaire sera utilisé
}
type Response = Job

Webhooks

Points de terminaison :

Objets :

Récupérer les configurations de webhooks

GET /webhooks
type Request = {}
type Response = WebhookConfiguration[]

Créer une configuration de webhook

POST /webhook
type Request = {
    url: string,
    event: [
        'comment.create' | 'comment.update' | 'comment.delete' |
        'reaction.created' | 'reaction.updated' | 'reaction.deleted' |
        'rating.created' | 'rating.updated' | 'rating.deleted' |
        'comment.vote.created' | 'comment.vote.updated' | 'comment.vote.deleted' |
        'comment.flag.created' | 'comment.flag.deleted' |
        'user.created' | 'user.updated' | 'media.created' | 'media.deleted' |
        'memberships.subscription.created' |
        'memberships.subscription.updated' | 'memberships.subscription.deleted'
    ] // le tableau peut contenir un ou plusieurs événements
}
type Response = WebhookConfiguration

Mettre Ă  jour une configuration de webhook

PATCH /webhook/{id}
type Request = {
    url: string | null,
    event: null | [
        'comment.create' | 'comment.update' | 'comment.delete' |
        'reaction.created' | 'reaction.updated' | 'reaction.deleted' |
        'rating.created' | 'rating.updated' | 'rating.deleted' |
        'comment.vote.created' | 'comment.vote.updated' | 'comment.vote.deleted' |
        'comment.flag.created' | 'comment.flag.deleted' |
        'user.created' | 'user.updated' | 'media.created' | 'media.deleted' | 'memberships.subscription.created' |
        'memberships.subscription.updated' | 'memberships.subscription.deleted'
    ] // le tableau peut contenir un ou plusieurs événements
}
type Response = WebhookConfiguration

Supprimer une configuration de webhook

DELETE /webhook/{id}
type Request = {}
type Response = {}

Récupérer les livraisons de webhooks

GET /webhook/deliveries
type Request = {
    limit: number | null, // par défaut : 25, max: 100
    offset: number | null // par défaut : 0
}
type Response = WebhookDelivery[]

Intégrations

Points de terminaison :

Objets :

Récupérer le statut de l'intégration Slack

GET /integrations/slack
type Request = {}
type Response = {
    connection: SlackConnection
}

Initialiser l'intégration Slack

POST /integrations/slack
type Request = {}
type Response = {
    url: string // rediriger ici pour la confirmation OAuth
}

Définir un canal Slack

POST /integrations/slack/channel
type Request = {
    channel: string
}
type Response = {}

Déconnecter l'intégration Slack

DELETE /integrations/slack
type Request = {}
type Response = {}

Médias

Points de terminaison :

Objets :

Récupérer les médias

GET /media
type Request = {
    limit: number | null, // par défaut : 50, max: 100
    offset: number | null // par défaut : 0
}
type Response = Media[]

Téléverser une image

POST /media/image
type Request = {
    image: File // taille max. : 5 Mo,
    // formats pris en charge : jpg, jpeg, png, gif, svg, webp, apng, avif
}
type Response = Media

Supprimer un média

DELETE /media/{id}
type Request = {}
type Response = {}

Objets

Objet Website

interface Website = {
    id: number,
    name: string,

    auth_type: 'hyvor' | 'sso',

    auth_sso_type: null | 'stateless' | 'openid',
    sso_stateless_private_key: string | null,
    sso_stateless_login_url: string | null,
    sso_stateless_is_keyless: boolean,
    sso_openid_issuer_url: string | null,
    sso_openid_client_id: string | null,
    sso_openid_client_secret: string | null,

    premoderation_status: 'off' | 'guest' | 'guest_and_new_commenters' | 'all', // par défaut : 'off'
    is_realtime_on: boolean,
    realtime_typing: 'off' | 'on_without_typer' | 'on_with_typer',
    is_realtime_online_count_on: boolean,
    is_realtime_users_on: boolean, // par défaut : true
    is_user_profile_on: boolean,
    is_keyboard_navigation_on: boolean,
    is_ip_collection_on: boolean,
    is_guest_commenting_on: boolean,
    guest_commenting_email: 'no' | 'optional' | 'required',
    guest_commenting_delay: number, // par défaut : 1
    default_avatar: string | null,

    text_comment_box: string | null, // par défaut : 'Write your comment...'
    text_no_comments: string | null, // par défaut : 'Be the first to comment...'
    text_comment_button: string | null,
    text_reply_box: string | null, // par défaut : 'Reply to this comment...'
    text_reply_button: string | null,
    text_reactions: string | null, // par défaut : 'What is your reaction?'
    text_ratings: string | null, // par défaut : 'What is your rating?'
    text_comment_count_0: string | null,
    text_comment_count_1: string | null,
    text_comment_count_multi: string | null,

    top_widget: 'none' | 'reactions' | 'ratings', // par défaut : 'reactions'

    ui_box_shadow: number, // par défaut : 1
    ui_box_roundness: number, // par défaut : 4
    ui_box_border_size: number, // par défaut : 0
    ui_box_width: number | null,
    ui_button_roundness: number, // par défaut : 4
    ui_box_border_color: string, // par défaut : 'aaaaaa'
    ui_custom_css: string | null,

    is_ch_new_on: boolean,
    ch_new_color: string | null,
    ch_upvote_1_threshold: number | null,
    ch_upvote_2_threshold: number | null,
    ch_upvote_1_color: string | null,
    ch_upvote_2_color: string | null,

    is_profile_pictures_on: boolean,

    display_name_type: 'name' | 'username', // par défaut : name
    comments_per_request: number, // par défaut : 50
    replies_per_request: number, // par défaut : 25
    nested_levels: number, // par défaut : 3
    display_replied_to_type: 'none' | 'deep' | 'all', // par défaut : 'deep'
    comments_char_limit: number, // par défaut : 50000
    comments_min_char_limit: number, // par défaut : 0

    comments_editing_enabled: boolean,
    comments_editing_timeout: number, // par défaut : 0 (aucun délai) en minutes
    comments_force_guest_commenting: boolean,

    is_emoji_enabled: boolean,
    is_images_enabled: boolean,
    is_embed_enabled: boolean,
    is_math_enabled: boolean,

    is_spam_detection_on: boolean,

    spam_detection_provider: 'none' | 'akismet' | 'fortguard',
    spam_detection_fortguard_content_score: number | null,
    spam_detection_fortguard_languages: string[],
    spam_detection_fortguard_languages_exclude: boolean,
    spam_detection_fortguard_countries: string[],
    spam_detection_fortguard_countries_exclude: boolean,
    spam_detection_fortguard_sentiments: string[],

    vote_type: 'both' | 'upvotes' | 'none', // par défaut : 'both'
    is_vote_viewing_on: boolean,
    is_guest_voting_on: boolean,
    sort: 'top' | 'newest' | 'oldest', // par défaut : 'top'
    language: string, // par défaut : 'en-us'
    note: string | null,
    close_after_days: number,

    color_text: string | null,
    color_background_text: string | null, // par défaut : '111111'
    color_accent: string | null, // par défaut : '000000'
    color_accent_text: string | null, // par défaut : 'ffffff'
    color_box: string | null, // par défaut : 'ffffff'
    color_box_text: string | null, // par défaut : '111111'
    color_box_text_light: string | null, // par défaut : '767676'
    color_input: string | null,

    color_dark_text: string | null,
    color_dark_background_text: string | null, // par défaut : 'ffffff'
    color_dark_accent: string | null, // par défaut : 'ffffff'
    color_dark_accent_text: string | null, // par défaut : '000000'
    color_dark_box: string | null, // par défaut : '232121'
    color_dark_box_text: string | null, // par défaut : 'ffffff'
    color_dark_box_text_light: string | null, // par défaut : 'aaaaaa'
    color_dark_input: string | null,

    color_theme: 'light' | 'dark' | 'os',
    ratings_color: string | null, // par défaut : 'ffcc48'

    reaction_1: string | null,
    reaction_2: string | null,
    reaction_3: string | null,
    reaction_4: string | null,
    reaction_5: string | null,
    reaction_6: string | null,

    is_reaction_1_on: boolean,
    is_reaction_2_on: boolean,
    is_reaction_3_on: boolean,
    is_reaction_4_on: boolean,
    is_reaction_5_on: boolean,
    is_reaction_6_on: boolean,

    reaction_1_text: string | null,
    reaction_2_text: string | null,
    reaction_3_text: string | null,
    reaction_4_text: string | null,
    reaction_5_text: string | null,
    reaction_6_text: string | null,

    reaction_display_type: 'text' | 'image' | 'both', // par défaut : 'both'

    email_send_to_users: boolean,
    notif_channel: 'email' | 'slack' | 'off', // par défaut : 'email'
    email_report_frequency: string,
    email_company_name: string | null,
    email_company_logo_url: string | null,
    email_company_address: string | null,
    email_alternate_address: string | null,
    email_website_url: string | null,
    email_notification_sending_address: string | null,

    encryption_key: string | null,
    data_api_key: string | null,
    is_data_api_public: boolean,
    console_api_key: string | null,

    webhook_url: string | null,
    webhook_on_create: boolean,
    webhook_on_edit: boolean,
    webhook_on_delete: boolean,
    webhook_secret: string | null,

    mod_badge_id: number | null,
    mod_alias_name: string | null,
    mod_alias_picture_url: string | null,

    memberships_enabled: boolean,
    memberships_currency: 'usd' | 'eur' | 'gbp', // par défaut : 'usd'
    memberships_yearly_discount: number | null,
    memberships_text_button: string | null,
    memberships_text_modal_title: string | null,
    memberships_text_modal_title_members: string | null,
    memberships_text_login_to_subscribe: string | null,
    memberships_text_subscribe_as: string | null,
    memberships_text_manage_subscription: string | null,
    memberships_text_payment_success: string | null,
    memberships_payment_success_url: string | null,
    memberships_gated_allow_google: boolean,

    email_report_daily: boolean,
    email_report_weekly: boolean,
    email_report_monthly: boolean,

    highlight_new: boolean,
    highlight_new_color: string | null, // par défaut : '29ab3f',
    highlight_upvote_threshold_1: number | null,
    highlight_upvote_threshold_1_color: string | null, // par défaut : 'f96436',
    highlight_upvote_threshold_2: number | null,
    highlight_upvote_threshold_2_color: string | null, // par défaut : '223696',
}

Objet Comment

interface Comment = {
    id: number,
    created_at: number,

    user: User,
    page: Page,

    body: string,
    body_html: string,

    status: 'published' | 'pending' | 'spam' | 'deleted',

    parent: Comment | null,
    ip_address: string | null,

    has_mod_seen: boolean,
    has_mod_replied: boolean,
    is_featured: boolean,
    is_loved: boolean,
    is_edited: boolean,

    has_questions: boolean,
    has_links: boolean,
    has_media: boolean,
    is_automatic_spam: boolean,

    flags_count: number,
    last_flag_at: number | null,

    upvotes: number,
    downvotes: number,

    user_vote: null, 'up' | 'down',

    history: CommentHistory[]
}

Objet Comment History

interface CommentHistory = {
    id: number,
    created_at: number,

    type: 'rule' | 'spam_detection' | 'moderation' | 'edit',
    new_status: null | 'published' | 'pending' | 'spam' | 'deleted',

    rule: Rule | null,
    mod: Mod | null,

    via: 'email' | 'slack' | null,
    additional_info: string | null
}

Objet Page

interface Page = {
    id: number,
    created_at: number,
    last_commented_at: number | null,
    title: string,
    identifier: string,
    url: string,
    is_closed: boolean,
    is_premoderation_on: boolean,
    author_email: string | null,
    comments_count: number,
    ratings: Rating
    reactions: Reaction
}

Objet Flag

interface Flag = {
    id: number,
    user: User | null,
    comment_id: number,
    reason: string,
    has_mod_seen: boolean
}

Objet Vote

interface Vote = {
    id: number,
    created_at: number | null,
    comment_id: number,
    user: User | null,
    ip_hash: string | null,
    type: 'up' | 'down'
}

Objet Rating

interface Rating = {
    id: number,
    created_at: number | null,
    page: Page | null,
    user: User | null,
    rating: number
}

Objet Reaction

interface Reaction = {
    id: number,
    created_at: number | null,
    page: Page | null,
    user: User | null,
    type: 'superb' | 'love' | 'wow' | 'sad' | 'laugh' | 'angry'
}

Objet User

Il existe plusieurs variantes de l'objet utilisateur. LoggedInUser est utilisé pour les utilisateurs connectés (HYVOR et SSO). GuestUser est utilisé avec les commentaires lorsque les commentaires d'invités sont activés. CommentingUser est l'union des deux.

interface LoggedInUser = {

    type: 'hyvor' | 'sso',
    id: number,
    htid: string,
    sso_id: string,
    name: string,
    title: string | null,
    username: string | null,
    email: string | null,
    picture_url: string | null,
    bio: string | null,
    location: string | null,
    website_url: string | null,

    created_at: number | null,
    last_commented_at: number | null,
    comments_count: number,
    state: 'default' | 'banned' | 'shadowed' | 'trusted',
    state_ends_at: number | null,
    note: string | null,
    ban_reason: string | null,
    badge_ids: number[],
    register_ip: string | null,
    last_ip: string | null,
    days_visited: number,
    last_seen_at: number | null,
    emails_sent: number,
    last_emailed_at: number | null,

    membership_plan_id: number | null,
    membership_stripe_customer_id: string | null,
    membership_started_at: number | null,
    membership_ends_at: number | null,

    role: null | 'owner' | 'mod' | 'admin'
}

interface GuestUser = {
    type: null,
    name: string | 'Anonymous',
    email: string | null,
    picture_url: string | null
}

type CommentingUser = LoggedInUser | GuestUser

email est null pour les utilisateurs HYVOR, car nous ne partageons pas les adresses e-mail des utilisateurs HYVOR avec les modérateurs du site web.

Objet UserMini

interface UserMini = {
    id: number,
    type:  null | 'hyvor' | 'sso',
    htid: string,
    name: string,
    username: string | null,
    picture_url: string | null
}

Objet Mod

interface Mod = {
    id: number,
    created_at: number,
    role: 'owner' | 'mod' | 'admin
    user: UserMini,
    sso_user: UserMini | null,
    is_alias_used: boolean
}

Objet Mod Invite

interface ModInvite = {
    id: number,
    created_at: number,
    role: 'owner' | 'mod' | 'admin
    user: UserMini,
    expires_at: number
}

Objet Stripe Connect

interface StripeConnect = {
    id: number,
    stripe_account_id: string,
    is_active: boolean
}

Objet Plan

interface Plan = {
    id: number,
    created_at: number,
    name: string,
    description: string | null,
    features: string | null,
    monthly_price: number,
    badge_id: number | null,
    stripe_product_id: string | null,
    stripe_monthly_price_id: string | null,
    stripe_yearly_price_id: string | null,
    members_count: number
}

Objet Gated Content

interface GatedContent = {
    id: number,
    created_at: number,
    key: string,
    content: string,
    gate: string | null,
    minimum_plan_id: number | null
}

Objet Membership Subscription

interface MembershipSubscription = {
    id: number,
    created_at: number | null,
    user: User | null,
    plan: Plan | null,
    is_yearly: boolean,
    stripe_id: string,
    status: 'pending' | 'active' | 'past_due' | 'canceled',
    cancel_at: number | null
}

Objet Segment

interface Segment = {
    id: number,
    created_at: number,
    name: string,
    description: string | null,
    subscribers: number
}

Objet Issue

interface Issue = {
    id: number,
    uuid: string,
    created_at: number,
    subject: string,
    from_name: string,
    from_email: string,
    reply_to_email: string,
    content: string,
    status: 'draft' | 'scheduled' | 'sending' | 'failed' | 'sent',
    segments: number[],
    scheduled_at: number | null,
    sending_at: number | null,
    sent_at: number | null
}

Objet Email Domain

interface EmailDomain = {
    id: number,
    domain: string,
    dkim_public_key: string,
    dkim_txt_name: string,
    dkim_txt_value: string,
    verified: boolean,
    verified_in_ses: boolean,
    requested_by_current_website: boolean
}

Objet Rule

interface Rule = {
    id: number,
    type: 'word_matches' | 'link_domain_matches' | 'user_name_matches' | 'link_count_exceeds' | 'flags_exceeds' | 'downvotes_exceeds' | 'upvotes_exceeds' | 'user_reputation_exceeds',
    value: string,
    to_status: 'published' | 'pending' | 'spam' | 'deleted',
    priority: number
}

Objet Email Log

interface EmailLog = {
    id: number,
    created_at: number,
    comment_id: number,
    type: 'reply' | 'mention' | 'mod' | 'author',
    comment_url: string,
    user: LoggedInUser | null,
    guest_email: string | null
}

Objet IP

interface IP = {
    ip: string,
    note: string | null,
    state: 'default' | 'banned' | 'shadowed' | 'trusted',
    state_ends_at: number | null
}

Objet Domain

interface Domain = {
    id: number,
    domain: string
}

Objet Badge

interface Badge = {
    id: number,
    text: string,
    background_color: string,
    color: string
}

Objet Job

interface Job = {
    id: number,
    created_at: number,

    started_at: number | null,
    completed_at: number | null,
    failed_at: number | null,

    data: { string : any },
    result: { string : any } | null,
    type: 'import_comments' | 'import_newsletter_subscribers' | 'export' | 'bulk_moderate_comments',
    status: 'pending' | 'running' | 'completed' | 'failed',
    error: string | null
}

Objet Webhook Configuration

interface WebhookConfiguration = {
    id: number,
    website_id: number,
    url: string,
    events: [
        'comment.create' | 'comment.update' | 'comment.delete' |
        'reaction.created' | 'reaction.updated' | 'reaction.deleted' |
        'rating.created' | 'rating.updated' | 'rating.deleted' |
        'comment.vote.created' | 'comment.vote.updated' | 'comment.vote.deleted' |
        'comment.flag.created' | 'comment.flag.deleted' |
        'user.created' | 'user.updated' | 'media.created' | 'media.deleted' |
        'memberships.subscription.created' |
        'memberships.subscription.updated' | 'memberships.subscription.deleted'
    ], // le tableau peut contenir un ou plusieurs événements
    secret: string
}

Objet Webhook Delivery

interface WebhookDelivery = {
    id: number,
    created_at: number | null,
    website_id: number,
    webhook_configuration_id: number,
    url: string,
    event: 'comment.create' | 'comment.update' | 'comment.delete' |
        'reaction.created' | 'reaction.updated' | 'reaction.deleted' |
        'rating.created' | 'rating.updated' | 'rating.deleted' |
        'comment.vote.created' | 'comment.vote.updated' | 'comment.vote.deleted' |
        'comment.flag.created' | 'comment.flag.deleted' |
        'user.created' | 'user.updated' | 'media.created' | 'media.deleted' |
        'memberships.subscription.created' |
        'memberships.subscription.updated' | 'memberships.subscription.deleted',
    status: 'pending' | 'completed' | 'retrying' | 'failed',
    request_body: string | null,
    num_attempts: number | null,
    last_attempt_at: number | null,
    response_body: string | null,
    response_code: number | null
}

Objet Slack Connection

interface SlackConnection = {
    has_token: boolean,
    channel_name: string | null
}

Objet Media

interface Media = {
    id: number,
    created_at: number,
    comment_id: number | null,
    name: string,
    size: number,
    url: string
}