Ejecuta consultas de Data Explorer con la API de Discourse

:bookmark: Esta guía explica cómo usar la API de Discourse para crear, ejecutar y administrar consultas con el plugin Data Explorer.

:person_raising_hand: Nivel de usuario requerido: Administrador

Prácticamente cualquier acción que se pueda realizar a través de la interfaz de usuario de Discourse también se puede activar con la API de Discourse.

Este documento proporciona una descripción general completa para utilizar la API específicamente en conjunto con el plugin Data Explorer.

Para una descripción general de cómo encontrar la solicitud de API correcta para una acción, consulte: Reverse engineer the Discourse API .

Ejecutar una consulta de Data Explorer

Para ejecutar una consulta de Data Explorer a través de la API, realice una solicitud POST a /admin/plugins/explorer/queries/<query-id>/run. Puede encontrar el ID de la consulta visitándola a través de su sitio de Discourse y verificando el parámetro id en la barra de direcciones.

A continuación se muestra una consulta de ejemplo con un ID de 20 que devuelve temas por vistas en una fecha especificada:

--[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

Esta consulta se puede ejecutar desde una terminal con:

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

Tenga en cuenta que deberá reemplazar <api-key> y <your-site-url> con su clave de API y dominio.

Manejo de grandes conjuntos de datos

El plugin Data Explorer limita los resultados a 1000 filas por defecto. Para paginar a través de conjuntos de datos más grandes, puede usar la consulta de ejemplo a continuación:

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

Para obtener los resultados página por página, incremente el parámetro page en la solicitud:

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

Deténgase cuando result_count sea cero.

Para obtener información adicional sobre el manejo de grandes conjuntos de datos, consulte: Result Limits and Exporting Queries

Eliminación de datos de relations de los resultados

Cuando las consultas de Data Explorer se ejecutan a través de la interfaz de usuario, se agrega un objeto relations a los resultados. Estos datos se utilizan para representar al usuario en los resultados de la interfaz de usuario, pero es poco probable que los necesite al ejecutar consultas a través de la API.

Para eliminar esos datos de los resultados, agregue un parámetro download=true con su solicitud:

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"

Autenticación de API

Los detalles sobre cómo generar una clave de API para las solicitudes se pueden encontrar aquí: Create and configure an API key .

Si la clave de API solo se va a utilizar para ejecutar consultas de Data Explorer, puede seleccionar “Granular” en el menú desplegable Scope, y luego seleccionar el ámbito “run queries”.

Preguntas frecuentes

¿Hay algún endpoint de api que pueda usar para obtener la lista de informes y los números de ID? Quiero crear un menú desplegable con la lista.

Sí, puede realizar una solicitud GET autenticada a /admin/plugins/explorer/queries.json para obtener una lista de todas las consultas en el sitio.

¿Es posible crear consultas a través de la api?

Sí. La documentación sobre cómo hacerlo se encuentra en Create a Data Explorer query using the API

¿Es posible enviar parámetros con la solicitud post?

Sí, incluya parámetros SQL usando la opción -F, como se muestra en los ejemplos.

¿La exportación a CSV es compatible con la API para las consultas?

Aunque la salida JSON es estándar, puede convertir manualmente los resultados a CSV. La exportación nativa a CSV ya no es compatible.

Recursos adicionales

39 Me gusta
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

Este comentario parece implicar que puedes hacer exportaciones CSV desde la API. ¿Es eso posible? Solo tengo curiosidad porque necesito los datos en formato CSV. Siempre puedo obtenerlos en JSON y convertirlos a CSV, pero si hay una forma integrada de obtener CSV, sería un poco más fácil.

¿Es posible hacer una consulta ‘como creada o actualizada en los últimos 50 segundos’?

:robot: La IA dice

-- [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

Hice una prueba rápida, parece que funciona :slight_smile:

1 me gusta

No veo el “me gusta :heart:” que agregué a una publicación usando tu consulta.

Creo que necesitas usar 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

Versión con resultados más bonitos

--[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 Me gusta

¡Oooh, lo leí mal! Leí la oración como "¿Es posible hacer una consulta como ‘creado o actualizado en los últimos 50 segundos’?
(nota la posición de la comilla simple)

1 me gusta

Gracias a todos,

Publiqué aquí porque allí es a donde me dirigió ask.discourse.
¿Estoy buscando si la API proporciona esta capacidad?

1 me gusta

Sí, por supuesto.

Creas la consulta en el explorador de datos y luego ejecutas la consulta a través de la API como se describe en esta guía.

Acabo de ejecutar la consulta de Moin a través de la API y devolvió correctamente los resultados esperados.

4 Me gusta

Yo también me preguntaba sobre esto. ¿Es JSON la única forma de exportar datos a través de la API o también se admite la exportación CSV para Data Explorer?

Gracias a todos,

Disculpen la demora en responder; estuve desconectado un tiempo.

Lo que estoy haciendo actualmente es buscar todos los temas/publicaciones creados hoy y filtrar los temas/publicaciones actualizados antes de la marca de tiempo.

1 me gusta

Si no quieres ensuciarte las manos, puedes preguntarle al bot en ask.discourse.com. Suele ser bastante preciso en lo que respecta a las consultas SQL relacionadas con Discourse (pero no asumas que es correcto, comprueba el código para estar seguro).

1 me gusta

¿Es correcto el encabezado Content-Type?
En las herramientas de desarrollador, al inspeccionar una consulta de Data Explorer con parámetros, el encabezado Content-Type aparece como:

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

Sin embargo, el comando cURL actual incluye:

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


1 me gusta
  • multipart/form-data
  • application/x-www-form-urlencoded
  • application/json

son todos los content-types válidos que puedes usar al hacer una solicitud a la API.

1 me gusta

@blake
language python
library requests
¿Podrías proporcionar una consulta de Data Explorer de API de ejemplo que incluya tres parámetros
referencia Tema que dice que los parámetros deben estar estrictamente entre comillas dobles

Claro, aquí tienes un ejemplo usando python:

import json
import requests

API_KEY      = "TU_API_KEY"
API_USERNAME = "system"
QUERY_ID     = 20
SITE_URL     = "https://tu-url-del-sitio"

# todos los valores deben ser cadenas
params = {
    "user_id":   "2",
    "viewed_at": "2019-06-10",
    "limit":     "5"
}

# Data Explorer espera los parámetros como una cadena codificada 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 Me gusta