Resumen
Este artículo explica cómo autenticar y consumir la API de SMARTFENSE desde Microsoft Power BI Desktop usando OAuth 2.0 (Client Credentials), incluyendo un ejemplo de paginación para unificar resultados de múltiples páginas en una sola tabla.
Introducción
SMARTFENSE expone una API que permite integrar datos de tu instancia con herramientas como Microsoft Power BI para reporting y análisis. En este ejemplo se utiliza el flujo OAuth 2.0 Client Credentials, pensado para integraciones servidor a servidor (sin un usuario presente), típico de un administrador o partner que necesita consultar información de campañas y módulos.
URL Base
Todas las solicitudes a la API de SMARTFENSE deben realizarse utilizando la siguiente URL base:
https://tenant.takesecurity.com/
| Nota: Reemplace tenant por el subdominio correspondiente a su instancia de SMARTFENSE. |
Autenticación
La API de SMARTFENSE utiliza OAuth 2.0, soportando los siguientes flujos:
- Client Credentials
- Authorization Code
Para integraciones con Power BI, se utiliza el flujo Client Credentials, ya que está diseñado para interacciones servidor a servidor, sin intervención de un usuario final.
Reglas importantes
- Todas las solicitudes deben realizarse mediante HTTPS.
- Cada request debe incluir un Bearer Token en el encabezado Authorization.
- Las credenciales deben almacenarse de forma segura.
Obtención de credenciales
- Ingrese a la plataforma SMARTFENSE.
- Diríjase a Configuración → Integraciones → API
-
Presione Registrar nueva aplicación.
- Configure los alcances necesarios según los endpoints a consumir
(documentación disponible en:
https://tenant.takesecurity.com/api/schema/redoc/)
- Al finalizar, obtendrá:
- client_id
- client_secret
| Importante: El client_secret otorga acceso directo a la información de su instancia. No debe compartirse ni exponerse públicamente. |
Estructura recomendada en Power BI
Para la integración se recomienda crear las siguientes funciones:
-
fnGetToken
Obtiene el token OAuth 2.0. -
fnGetPagedResults
Obtiene y unifica los resultados paginados de la API. -
Función por endpoint
Ejemplo: fnGetCampaignTrainings para Módulos Interactivos.
La autenticación se maneja dentro del código M, por lo que en Power BI el origen se configura como Anónimo.
| Nota: La autenticación real se realiza dentro del código M, usando la cabecera Authorization y la función fnGetToken. Por eso, a nivel de Power BI el origen se deja como “Anónimo”. |
Crear función para obtener el token
Iniciar Power BI. Ir a la sección de Obtener datos de otros orígenes
En la ventana de Obtener datos, seleccionar del menú lateral izquierdo Otras y seleccionar Consulta en blanco, luego clic en Conectar.
Cambiar el nombre de la consulta por fnGetToken y luego ir a Editor avanzado.
En Editor avanzado pegar el siguiente código:
let
fnGetToken = () as text =>
let
// Datos de la aplicación OAuth
// Reemplazar con los valores reales
client_id = "client_id de la plataforma SMARTFENSE",
client_secret = "client_secret de la plataforma SMARTFENSE",
base_url = "https://instancia.takesecurity.com",
// Tiempo máximo de espera en minutos para las llamadas HTTP
timeoutMinutes = 120,
// "client_id:client_secret" en Base64 para Authorization: Basic
TextToEncode = client_id & ":" & client_secret,
Encoded = Binary.ToText(Text.ToBinary(TextToEncode), BinaryEncoding.Base64),
// Cuerpo para grant_type=client_credentials
Body = "grant_type=client_credentials",
TokenResponse = Json.Document(
Web.Contents(
base_url & "/oauth/token/",
[
Content = Text.ToBinary(Body),
Headers = [
#"Content-Type" = "application/x-www-form-urlencoded",
#"Cache-Control" = "no-cache",
Authorization = "Basic " & Encoded
],
Timeout = #duration(0, 0, timeoutMinutes, 0)
]
)
),
AccessToken = TokenResponse[access_token]
in
AccessToken
in
fnGetToken
En la sección que dice "// Reemplazar con los valores reales" colocar los datos obtenidos al registrar la aplicacion en la plataforma SMARTFENSE y presionar en el botón Listo.
La URL "https://instancia.takesecurity.com" debe tener el subdominio de la instancia de SMARTFENSE.
Crear función para obtener datos paginados (fnGetPagedResults)
-
En menú Inicio->Nuevo origen seleccionar "Consulta en blanco".
-
Cambiar el nombre de la consulta por fnGetPagedResults y luego ir a Editor avanzado.
En Editor avanzado pegar el siguiente código:
let
fnGetPagedResults = (initialPath as text) as list =>
let
// URL base de la instancia (host)
base_url = "https://instancia.takesecurity.com",
// Timeout máximo por request (en minutos)
timeoutMinutes = 120,
// Obtener token usando la función anterior (se usa en el header Authorization)
token = fnGetToken(),
// Armar la primera URL absoluta del endpoint
FirstUrl = base_url & initialPath,
// Función local para obtener una página (request + parseo JSON)
GetPage = (url as text) as record =>
let
Response =
Json.Document(
Web.Contents(
url,
[
Headers = [ Authorization = "Bearer " & token ],
Timeout = #duration(0, 0, timeoutMinutes, 0)
]
)
)
in
Response,
// Extraer la lista de items de una página, soportando ambos formatos:
// - {"results": [...]}
// - {"campaigns": [...]}
GetItems = (page as record) as list =>
let
items =
if Record.HasFields(page, "results") then page[results]
else if Record.HasFields(page, "campaigns") then page[campaigns]
else {}
in
if items is list then items else {},
// Recorrer todas las páginas mientras exista el campo "next"
Pages = List.Generate(
// Estado inicial: primera URL y primera página descargada
() => [ Url = FirstUrl, Page = GetPage(FirstUrl) ],
// Condición: seguimos mientras Page no sea null
each [Page] <> null,
// Siguiente estado: leer "next" y traer la siguiente página si existe
each
let
NextUrl = try [Page][next] otherwise null
in
[
Url = NextUrl,
Page = if NextUrl <> null then GetPage(NextUrl) else null
],
// De cada página, devolver la lista detectada (results o campaigns)
each try GetItems([Page]) otherwise {}
),
// Unir todas las listas en una sola lista final
AllResults = List.Combine(Pages)
in
AllResults
in
fnGetPagedResults Presionar en el botón "Listo".
Crear función para Módulos Interactivos (ejemplo)
-
En menú Inicio->Nuevo origen seleccionar "Consulta en blanco".
Cambiar el nombre de la consulta por fnGetCampaignTrainings y luego ir a Editor avanzado.
En Editor avanzado pegar el siguiente código:
let
initial_path = "/api/v1/users/campaigns/trainings",
ResultsList = fnGetPagedResults(initial_path)
in
ResultsList
Presionar en el botón "Listo".
Configurar las credenciales en Power BI Desktop
-
Presionar en Editar credenciales.
Buscar el origen: https://nombreinstancia.takesecurity.com y presionar en Conectar.
-
Para especificar los datos de privacidad presione en Continuar.
Nivel de privacidad: Organizativo.
Guardar y cerrar.
Crear la tabla final para el modelo
-
Si la conexión fue exitosa se nos abrirá el Editor de Power Query mostrando la siguiente información.
Presionamos en el botón "A la tabla" en la esquina superior izquierda y luego en el botón "Aceptar".
-
Luego presionamos en el botón expandir para ampliar la información que deseamos traer.
-
Luego se deben seleccionar los campos que se deseen observar en la tabla y presionar en "Aceptar".
-
Con la barra inferior movemos a la derecha hasta ver la columna results.related_campaigns y hacemos clic en el botón de expandir de la columna.
-
Seleccionamos Expandir en nuevas fila.
-
Hacemos nuevamente clic en el botón expandir de la columna para ver los datos que nos traerá y allí podemos seleccionar todos o los que deseemos ver. Clic en Aceptar.
-
De esta forma visualizaremos todos los datos de los resultados de las campañas del componente en distintas columnas.
-
Luego podemos ir al Menú superior y Cerrar y aplicar para avanzar con la creación de las consultas que se deseen realizar.
| Nota: Si usas estos datos para tableros compartidos con tu equipo de soporte técnico, es recomendable limitar campos a los necesarios para mejorar rendimiento y relevancia en búsquedas (por ejemplo, para Copilot o análisis interno). |
Consideraciones finales
- La actualización de datos es manual.
- Al presionar Actualizar en Power BI, se consultan los datos actuales de la instancia.
- No existe actualización automática programada desde la API.
- Es posible reutilizar esta estructura para cualquier endpoint documentado en la API de SMARTFENSE..
Mejores prácticas
Protege el client_secret: guárdalo en un lugar seguro y evita exponerlo en archivos compartidos o repositorios públicos, especialmente si el acceso lo gestiona un administrador o un partner.
Valida los alcances antes de construir reportes: confirma permisos y endpoints disponibles en tenant.takesecurity.com/api/schema/redoc/ para evitar errores y re-trabajo.
Reduce el volumen en Power Query: expande solo las columnas necesarias (por ejemplo, evita expandir listas completas si no aportan valor al modelo).
Estandariza el base_url por instancia: si administras múltiples instancias, define un criterio claro para mantener consistencia y evitar consultar datos equivocados.
Importante: Deberás reemplazar la palabra instancia de la url de cada API por el subdomino de la instancia en cuestión.