Exécuter des requêtes Data Explorer avec l'API Discourse

:bookmark: Ce guide explique comment utiliser l’API Discourse pour créer, exécuter et gérer des requêtes avec le plugin Data Explorer.

:person_raising_hand: Niveau d’utilisateur requis : Administrateur

Virtuellement toute action pouvant être effectuée via l’interface utilisateur de Discourse peut également être déclenchée avec l’API Discourse.

Ce document fournit un aperçu complet de l’utilisation de l’API spécifiquement en conjonction avec le plugin Data Explorer.

Pour un aperçu général sur la façon de trouver la bonne requête API pour une action, consultez : Reverse engineer the Discourse API .

Exécution d’une requête Data Explorer

Pour exécuter une requête Data Explorer via l’API, effectuez une requête POST vers /admin/plugins/explorer/queries/<query-id>/run. Vous pouvez trouver l’ID de la requête en la visitant via votre site Discourse et en vérifiant le paramètre id dans la barre d’adresse.

Ci-dessous se trouve une requête d’exemple avec un ID de 20 qui retourne les sujets par vues à une date spécifiée :

--[params]
-- date :viewed_at

SELECT
topic_id,
COUNT(1) AS views_for_date
FROM topic_views
WHERE viewed_at = :viewed_at
GROUP BY topic_id
ORDER BY views_for_date DESC

Cette requête peut être exécutée depuis un terminal avec :

curl -X POST "https://your-site-url/admin/plugins/explorer/queries/20/run" \
-H "Content-Type: multipart/form-data;" \
-H "Api-Key: <api-key>" \
-H "Api-Username: system" \
-F 'params={"viewed_at":"2019-06-10"}'

Notez que vous devrez remplacer <api-key> et <your-site-url> par votre clé API et votre domaine.

Gestion des grands ensembles de données

Le plugin Data Explorer limite les résultats à 1000 lignes par défaut. Pour paginer à travers de plus grands ensembles de données, vous pouvez utiliser la requête d’exemple ci-dessous :

--[params]
-- integer :limit = 100
-- integer :page = 0
SELECT * 
FROM generate_series(1, 10000)
OFFSET :page * :limit 
LIMIT :limit

Pour récupérer les résultats page par page, incrémentez le paramètre page dans la requête :

curl -X POST "https://your-site-url/admin/plugins/explorer/queries/27/run" \
-H "Content-Type: multipart/form-data;" \
-H "Api-Key: <api-key>" \
-H "Api-Username: system" \
-F 'params={"page":"0"}'

Arrêtez lorsque result_count est égal à zéro.

Pour des informations supplémentaires sur la gestion des grands ensembles de données, consultez : Result Limits and Exporting Queries

Suppression des données relations des résultats

Lorsque les requêtes Data Explorer sont exécutées via l’interface utilisateur, un objet relations est ajouté aux résultats. Ces données sont utilisées pour afficher l’utilisateur dans les résultats de l’interface utilisateur, mais vous n’en aurez probablement pas besoin lors de l’exécution de requêtes via l’API.

Pour supprimer ces données des résultats, ajoutez un paramètre download=true à votre requête :

curl -X POST "https://your-site-url/admin/plugins/explorer/queries/27/run" \
-H "Content-Type: multipart/form-data;" \
-H "Api-Key: <api-key>" \
-H "Api-Username: system" \
-F 'params={"page":"0"}' \
-F "download=true"

Authentification API

Les détails sur la génération d’une clé API pour les requêtes se trouvent ici : Create and configure an API key .

Si la clé API ne doit être utilisée que pour exécuter des requêtes Data Explorer, vous pouvez sélectionner « Granular » dans le menu déroulant Scope, puis sélectionner la portée « run queries ».

FAQs

Existe-t-il un endpoint d’API que je peux utiliser pour obtenir la liste des rapports et les numéros d’ID ? Je souhaite créer une liste déroulante avec la liste ?

Oui, vous pouvez effectuer une requête GET authentifiée vers /admin/plugins/explorer/queries.json pour obtenir une liste de toutes les requêtes sur le site.

Est-il possible de créer des requêtes via l’api ?

Oui. La documentation sur la façon de le faire se trouve à l’adresse Create a Data Explorer query using the API

Est-il possible d’envoyer des paramètres avec la requête post ?

Oui, incluez les paramètres SQL en utilisant l’option -F, comme montré dans les exemples.

L’exportation CSV pour les requêtes est-elle prise en charge par l’API ?

Bien que la sortie JSON soit standard, vous pouvez convertir manuellement les résultats en CSV. L’exportation CSV native n’est plus prise en charge.

Ressources supplémentaires

39 « J'aime »
Watching API
"DataExplorer::ValidationError: Missing parameter end_date of type string
Get total list of topics and their view counts from Discourse API
Best API for All First Posts in a Category
Category API request downloads all topics
Reports by Discourse
TimeStamp of Tag
How can I get the list of Discourse Topic IDs dynamically
Passing params to Data Explorer using API requires enclosing a value
Get Latest topic for Current user
Getting recently updated posts using the REST API
`DataExplorer::ValidationError: Missing parameter` when running Data Explorer queries with [params] via API
`DataExplorer::ValidationError: Missing parameter` when running Data Explorer queries with [params] via API
Backend data retrieve for analytics
Discourse-user-notes API
Admin dashboard report reference guide
How to query the topics_with_no_response.json API with filters
Use API to get topics for a period using js
Access Discourse database with n8n
Why getUserById doesn't return the user's email?
Grant a custom badge through the API
Is there an API endpoint for recently edited posts
How to query gamification score via the API?
1.5X cheers on specific TL's or groups
Page Publishing
Identifying users in multiple groups using AND rather than OR?
Validation error even when parameter passed while running data explorer API with Curl
How to change the response default_limit in data explorer?
How to change the response default_limit in data explorer?
Order/Filter searched topics by latest update to First Post
API Filter users by emails, including secondary emails
Ability to have granular scope for data explorer?
Daily, weekly, or total stats by user over a specified time range
Looking for help posting automating data explorer reports to my forum
How to get all topics from a specific category using offset/page param in the API query?
Discourse 有哪个接口能直接获取某个帖子的最后一条评论信息
想得到活跃的用户——通过api
API endpoint to create invite links has moved to /invites.json
How to get a password from database?
Can I send an external URL to the Discourse API for it to return topics linking to that URL?
How to fetch posts/topics by multiple usernames
Restrict moderator access to only the stats panel on the admin dashboard?
How to get all the deleted posts for a specific topic
Discourse forum traffic query data
Download a user's posting history via Discourse API?
Discourse Data Explorer Query Response to Slack
Filter topics in category containing file attachments
Discord Integration with Webhooks
Download result of queries into Google Spreadsheet
Who's online "API"?
Is there any endpoint that would provide a user's external account IDs from their Discourse ID?
API post request without an Accept header returns 406
Best way to get (via API) a list of users from a group, and their bios
Create a Data Explorer query using the API
How to get a full list of badges of all users
API rate limits

Ce commentaire semble impliquer que vous pouvez faire une exportation CSV à partir de l’API. Est-ce possible ? Je suis juste curieux car j’ai besoin des données au format CSV. Je peux toujours les obtenir au format JSON et les convertir en CSV, mais s’il existe un moyen intégré d’obtenir du CSV, ce serait un peu plus facile.

Est-il possible de faire une requête « comme créé ou mis à jour dans les 50 dernières secondes » ?

:robot: L’IA dit

-- [params]
-- int :seconds = 50

SELECT
    p.id AS post_id,
    p.created_at,
    p.updated_at,
    p.raw AS post_content,
    p.user_id,
    t.title AS topic_title,
    t.id AS topic_id
FROM posts p
INNER JOIN topics t ON t.id = p.topic_id
WHERE
    (EXTRACT(EPOCH FROM (NOW() - p.created_at)) <= :seconds
    OR EXTRACT(EPOCH FROM (NOW() - p.updated_at)) <= :seconds)
    AND p.deleted_at IS NULL
    AND t.deleted_at IS NULL
ORDER BY p.created_at DESC
LIMIT 50

J’ai fait un test rapide, ça semble fonctionner :slight_smile:

1 « J'aime »

Je ne vois pas le « j’aime :heart: » que j’ai ajouté à une publication en utilisant votre requête.

Je pense que vous devez utiliser post_actions

--[params]
--string :timespan = 50 seconds

SELECT post_id,
       user_id,
       created_at,
       updated_at,
       deleted_at
FROM  post_actions
WHERE post_action_type_id=2 AND updated_at > NOW() - INTERVAL :timespan

Version avec de plus beaux résultats

--[params]
--string :timespan = 50 seconds
--boolean :include_in_timespan_deleted = false

SELECT
  post_id,
  user_id,
  CASE
    WHEN EXTRACT(EPOCH FROM (NOW() - created_at)) < 60 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at))), ' seconds ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - created_at)) < 3600 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at)) / 60), ' minutes ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - created_at)) < 86400 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at)) / 3600), ' hours ago')
    ELSE CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at)) / 86400), ' days ago')
  END AS relative_created_at,
  CASE
    WHEN EXTRACT(EPOCH FROM (NOW() - updated_at)) < 60 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at))), ' seconds ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - updated_at)) < 3600 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at)) / 60), ' minutes ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - updated_at)) < 86400 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at)) / 3600), ' hours ago')
    ELSE CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at)) / 86400), ' days ago')
  END AS relative_updated_at,
  CASE
    WHEN deleted_at IS NULL THEN 'no'
    WHEN EXTRACT(EPOCH FROM (NOW() - deleted_at)) < 60 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at))), ' seconds ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - deleted_at)) < 3600 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at)) / 60), ' minutes ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - deleted_at)) < 86400 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at)) / 3600), ' hours ago')
    ELSE CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at)) / 86400), ' days ago')
  END AS relative_deleted_at
FROM
  post_actions
WHERE
  post_action_type_id = 2
  AND updated_at > NOW() - INTERVAL :timespan
  AND (
    :include_in_timespan_deleted = false
    OR (deleted_at IS NOT NULL AND deleted_at > NOW() - INTERVAL :timespan)
  )

2 « J'aime »

Oooh j’ai mal lu ! J’ai lu la phrase comme « Est-il possible de faire une requête comme « créé ou mis à jour au cours des 50 dernières secondes » ? »

(notez la position de la virgule simple)

1 « J'aime »

Merci à tous,

J’ai posté ici car c’est là que ask.discourse m’a dirigé.
Je cherche à savoir si l’API offre cette fonctionnalité.

1 « J'aime »

Oui, bien sûr.

Vous créez la requête dans l’explorateur de données, puis vous exécutez la requête via l’API comme décrit dans ce guide.

Je viens d’exécuter la requête de Moin via l’API et elle a correctement renvoyé les résultats attendus.

4 « J'aime »

Je me posais la même question. JSON est-il le seul moyen d’exporter des données via l’API ou l’export CSV est-il également pris en charge pour Data Explorer ?

Merci à tous,

Désolé pour ma réponse tardive - j’étais hors ligne pendant un moment.

Ce que je fais actuellement, c’est rechercher tous les sujets/messages créés aujourd’hui, et filtrer les sujets/messages mis à jour avant l’horodatage.

1 « J'aime »

Si vous ne voulez pas vous salir les mains, vous pouvez demander au bot sur ask.discourse.com. Il est généralement assez précis en ce qui concerne les requêtes SQL relatives à Discourse (mais ne supposez pas qu’il a raison, vérifiez le code pour être sûr).

1 « J'aime »

L’en-tête Content-Type est-il correct ?
Dans les outils de développement, lors de l’inspection d’une requête Data Explorer avec des paramètres, l’en-tête Content-Type apparaît comme suit :

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

Cependant, la commande cURL actuelle inclut :

-H "Content-Type: multipart/form-data;"


1 « J'aime »
  • multipart/form-data
  • application/x-www-form-urlencoded
  • application/json

sont tous des types de contenu valides que vous pouvez utiliser lors de la création d’une requête API.

1 « J'aime »

@blake
language python
library requests
Pourriez-vous fournir une requête d’exemple d’API Data Explorer qui inclut trois paramètres
référez-vous à Topic qui indique que les paramètres doivent être strictement entre guillemets doubles.

Bien sûr, voici un exemple utilisant Python :

import json
import requests

API_KEY      = "VOTRE_CLE_API"
API_USERNAME = "system"
QUERY_ID     = 20
SITE_URL     = "https://votre-url-de-site"

# toutes les valeurs doivent être des chaînes de caractères
params = {
    "user_id":   "2",
    "viewed_at": "2019-06-10",
    "limit":     "5"
}

# Data Explorer attend les paramètres sous forme de chaîne encodée en JSON
payload = {
    "params": json.dumps(params)
}

url = f"{SITE_URL}/admin/plugins/explorer/queries/{QUERY_ID}/run"
headers = {
    "Api-Key":       API_KEY,
    "Api-Username":  API_USERNAME,
    "Content-Type":  "application/json"
}

r = requests.post(url, headers=headers, json=payload)
r.raise_for_status()
print(r.json())
3 « J'aime »