En este caso, puedes hacer uso de Séntisis Webhook, que estará disponible en los productos en los que hayas contratado la funcionalidad. Gracias a él, pretendemos facilitar y optimizar la exportación e ingestión de datos, para que no sea necesario la descarga manual de las menciones (en archivos .csv).
¿Como se configura el conector?
Si quieres activar esta opción, tienes dos opciones:
Envíanos un correo a support@sentisis.com con la URL donde quieres recibir la información (http://example.com/endpoint).
Configura el webhook tú mismo desde la opción Integraciones del dashboard;
Una vez analizadas, las menciones se enviarán en tiempo real mediante una petición HTTP POST al endpoint indicado y estarán disponibles para su ingestión. Además, también se enviarán a través del conector las alertas que tengas configuradas.
No olvides que las menciones seguirán estando disponibles en tus productos dentro de sentisis.io
¿Qué formato tienen los datos?
La información de los mensajes se envía en un JSON con el siguiente formato, dependiendo de si se trata de mensajes de redes sociales, de medios o de alertas:
Mensajes de redes sociales (Mención base)
Cada tipo de mención se extiende desde el "Mention base object":
{
id: String
sentiment: String[POSITIVE|NEGATIVE|OBJECTIVE]
categories: [{ id: String, name: String }]
feed: { id: String, name: String }
date: Date
msgId: String
type: String[
Tweet|
Retweet|
FacebookPost|
FacebookComment|
InstagramPost|
InstagramComment|
Youtube
]
}
Mensajes de Twitter
Debido a la política de privacidad de Twitter, los mensajes de esta red vendrán con la siguiente información:
{
user: {
gender: String[FEMALE|MALE|UNKNOWN]
location: {
country: String
region: String
subregion: String
}
}
link: String
}
Puedes captar el resto de información mediante este booster.
Mensajes de Media (noticias, blogs y foros)
{
title: String
summary: String
text: String
source: {
title: String
}
link: String
}
Mensajes de Facebook
{
text: String
user: {
id: String
username: String
name: String
gender: String[FEMALE|MALE|UNKNOWN]
}
link: String
isDarkPost: Boolean
adAccount: {
id: String
}
Mensajes de Instagram
{
text: String
user: {
id: String
username: String
name: String
followers: Number
gender: String[FEMALE|MALE|UNKNOWN]
}
link: String
isDarkPost: Boolean
adAccount: {
id: String
}
}
Mensajes de Youtube
{
text: String
user: {
id: String
username: String
gender: String[FEMALE|MALE|UNKNOWN]
followers: Number
}
link: String
}
YoutubeComment {
text: String
user: {
id: String
username: String
gender: String[FEMALE|MALE|UNKNOWN]
}
link: String
}
Mensajes de TikTok
{
text: String
user: {
id: String
username: String
gender: String[FEMALE|MALE|UNKNOWN]
followers: Number
}
link: String
}
TikTokComment {
text: String
user: {
id: String
username: String
gender: String[FEMALE|MALE|UNKNOWN]
}
link: String
}
Mensajes de Reseñas
{
text: String
rating: Number
location: {
address: String
locality: String
name: String
region: String
link: String
}
user: {
name: String
}
}
Mensajes de Alertas
{
id: String
name: String
alert_type: String[
VOLUME |
VOLUME_POSITIVE |
VOLUME_NEGATIVE |
INFLUENCE |
INFLUENCE_POSITIVE |
INFLUENCE_NEGATIVE |
AUTHOR |
AUTHOR_POSITIVE |
AUTHOR_NEGATIVE |
VIRALITY |
VIRALITY_POSITIVE |
VIRALITY_NEGATIVE
]
delivery: {
type: String
receiver: [String]
}
lastnotification: String
interval: String
source: String[
Facebook |
Twitter |
Instagram |
Youtube |
Media |
Review |
Tiktok |
All
]
authors: [String]
message: {
id: String
feedId: String
text: String
date: String
userName: String
followers: String
source: String[
Facebook |
Twitter |
Instagram |
Youtube |
Media |
Review |
Tiktok |
All
]
}
}
Ejemplos de mensajes
Los datos están blanqueados para que no contengan información real
Twitter:
{
"id": "5ae7b623ce6800019067b66",
"sentiment": "OBJECTIVE",
"categories": [
{
"id": "54b557ecc45f3d73a357bdf",
"name": "Accion social"
},
{
"id": "5995654ed8e3390a0f18987",
"name": "Promocion"
},
],
"feed": {
"id": "2aed3e8f7a411171911b346",
"name": "Nombre marca"
},
"msgId": "99111360727289601",
"type": "Tweet",
}
Media (noticias, blogs y foros):
{
"id": "5ae7b623ce63800019067b66",
"title": "Título de la noticia/blog/foro",
"summary": "Resumen del contenido de la noticia",
"text": "Este es el cuerpo completo de la noticia. Puede contener varios párrafos",
"sentiment": "POSITIVE",
"categories": [
{
"id": "54b557ecc545fd73a357bdf",
"name": "Acción social"
},
{
"id": "5995654ed48e390a0f18987",
"name": "Promoción"
},
],
"feed": {
"id": "2aed3e87a411117191b346",
"name": "Nombre marca",
},
"date": "2018-04-26T12:19:11.000Z",
"msgId": "33894752217",
"source": {
"title": "Nombre del medio",
},
"type": "Media",
"link": "http://ct.moreover.com/?a=33894752217&p=1tg&v=1&x=EA9JefwoRHkRa223rbva"
}
Facebook:
{
"id": "59a5842de3d02a000f8abc3",
"sentiment": "OBJECTIVE",
"categories": [
{
"id": "54b557ecc545f3d73a357bdf",
"name": "Acción social"
},
{
"id": "5995654ed48e3390a0f18987",
"name": "Promoción"
}
],
"feed": {
"id": "2aed3e8f7a4111171911b34",
"name": "Nombre marca"
},
"date": "2017-08-29T14:02:15.000Z",
"msgId": "155619407443876_1560144877376929",
"type": "FacebookComment",
"text": "Buenos días, este es el contenido del mensaje interno: nombres, cédula, mail y celular. \r\nSaludos.",
"link": "https://facebook.com/1556194074438676_156014476929",
"clicks": 12,
"isDarkPost": true,
"adAccount": {
"id": "act_1245341172064281"
}
}
Instagram:
{
"id": "5942de02a000f8abc3",
"sentiment": "OBJECTIVE",
"categories": [
{
"id": "54b557ecc545f3d73a357bdf",
"name": "Deseo de consumo"
},
{
"id": "54b557ecc545f3d73a357bdd",
"name": "Expresa risa"
},
],
"feed": {
"id": "2aed3e8f7a4111171911b34",
"name": "Nombre marca"
},
"date": "2017-06-14T14:19:37.000Z",
"msgId": "1537044239360_628059",
"type": "InstagramPost",
"text": "Este es el contenido del post",
"link": "https://www.instagram.com/p/BVUrZ-6nA/",
"isDarkPost": false
}
Youtube:
{
"sentiment": "OBJECTIVE",
"categories": [
{
"id": "54b557ecc54f3d73a357bdd",
"name": "Expresa risa"
}
],
"feed": {
"id": "2aed3e8f7a4111171911b34",
"name": "Nombre marca"
},
"date": "2017-08-29T16:04:29.000Z",
"msgId": "s7r62LMc",
"type": "YoutubeVideo",
"text": "hola, este es el contenido del mensaje",
"user": {
"id": "UC5_DK5TY48EecjYfA",
"username": "Nombreusuario",
"gender": "MALE"
},
"link": "https://youtube.com/watch?v=s234u62LMc"
}
Reseñas:
{
"id": "54b557ecc54f3d73a351adb",
"text": "Este es el contenido de la reseña de Google My Business",
"sentiment": "POSITIVE",
"rating": 5,
"location": {
"address": "Dirección de la tienda",
"locality": "Madrid",
"name": "Nombre de la tienda",
"region": "Madrid",
"link": "URL de la ubicación de la tienda en Google Maps"
},
"user": {
"name": "Nombre del usuario"
},
"categories": [
{
"id": "54b557ecc545fd73a357bdf",
"name": "Acción social"
},
{
"id": "5995654ed48e390a0f18987",
"name": "Promoción"
}
],
"feed": {
"id": "2aed3e87a411117191b346",
"name": "Nombre del feed"
},
"date": "2020-11-23T14:20:00.000Z",
"msgId": "33894752244566",
"type": "Review"
}
Seguridad
Una vez que tu servidor esté configurado para recibir mensajes, escuchará todo tipo de peticiones, incluidas las de procedencia desconocida. Por razones de seguridad, es posible que desees limitar las solicitudes a las que provengan de Séntisis. Con este objeto ofrecemos un sistema opcional de validación basado en tokens.
El webhook calculará un hash del cuerpo de la petición (firma) y lo enviará junto a la petición en una cabecera para que lo puedas verificar programáticamente desde tu aplicación. Para ello usará funciones no reversibles y un secreto compartido.
Configurar el secret
Entra en el dashboard de Séntisis y selecciona Webhook
Rellena el secret (cualquier string entre 3 y 256 caracteres) y guarda los cambios
Una vez configurado el secret, el webhook enviará una cabecera adicional en cada petición, x-sentisis-signature, con el token de validación.
Validar la petición
Imaginemos un servidor básico:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 4444;
app.use(bodyParser.json());
app.post('/messages', (req, res) => {
console.log(Received ${JSON.stringify(req.body, null, 2)});
res.status(200).end();
});
app.listen(port, () => console.log(Example app listening on port ${port}!));
La idea es calcular el token de validación de la misma forma que lo hace Séntisis y asegurarse de que sea igual al enviado en la cabecera x-sentisis-signature. Séntisis usa una firma HMAC-SHA1 sobre el cuerpo de la petición, de manera que el código podría quedar así:
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();
const port = 4444;
app.use(bodyParser.json());
function verifySignature(body, requestSignature) {
const signature = crypto
.createHmac('sha1', process.env.SENTISIS_SECRET)
.update(JSON.stringify(body))
.digest('hex');
return signature === requestSignature;
}
app.post('/messages', (req, res) => {
console.log(Received ${JSON.stringify(req.body, null, 2)});
if (!verifySignature(req.body, req.headers['x-sentisis-signature'])) {
res.status(500).send('Invalid signature');
}
res.status(200).end();
});
app.listen(port, () => console.log(Example app listening on port ${port}!));
Por supuesto tendrás que adaptar el código al lenguaje que use tu servidor.
WARN: Recuerda no compartir nunca tu secret ni especificarlo directamente en tu código. Como puedes ver en el ejemplo, hemos usado una variable de entorno para almacenar el secret de Séntisis.
¡No dudes en ponerte en contacto con nosotros si deseas utilizar esta funcionalidad!
Es necesaria la utilización de un desarrollo/herramienta que permita esta conexión.