Según su sitio internet, Nube de sonido es “la plataforma de sonido social líder en el mundo donde cualquiera puede crear sonidos y compartirlos en todas partes”. Para los artistas, es un canal para distribuir vistas previas de sus pistas, y para personas como yo es una buena manera de hacer algunos ajustes en la API. ¡A cada uno lo suyo, supongo!
Vi varias solicitudes en el Google+ Administrador de etiquetas de Google comunidad sobre una integración de SoundCloud, así que decidí investigarla para ver si podía crear una.
SoundCloud tiene algo llamado API de widgetsque escucha window.postMessage
llamadas desde dentro de los iframes integrados de SoundCloud. El beneficio de esto versus, por ejemplo, el API de YouTube es que no es necesario hacer nada en el iframe para que esto funcione. Todo lo que necesita hacer es cargar la API de widgets y luego indicar qué iframe desea escuchar para las interacciones.
incógnita
El boletín a fuego lento
Suscríbete al Boletín a fuego lento para recibir las últimas noticias y contenido de Simo Ahava en su bandeja de entrada de correo electrónico.
la configuración
Para que esto funcione, necesitará lo siguiente:
-
Etiqueta HTML personalizada que carga la API de widgets, agrega los oyentes y hace el
dataLayer.push()
llamadas -
Activador de evento personalizado que activa tu etiqueta cuando se registra un evento de SoundCloud
-
Variables de capa de datos para categoría de evento, acción de evento y etiqueta de evento
-
Etiqueta de evento que se activa cuando se activa el activador y envía el evento a Google Analytics
El componente más complejo es la etiqueta HTML personalizada, así que comencemos por ahí.
La etiqueta HTML personalizada
Aquí está el código de etiqueta completo. Cópielo y péguelo en una nueva etiqueta HTML personalizada:
<script src="https://w.soundcloud.com/participant/api.js">script>
<script>
(perform() {
attempt {
// initWidget known as when a SoundCloud iframe is discovered on the web page
var initWidget = perform(w) {
var currentSound, act, pos, q1, q2, q3, go, lab;
var cat = 'SoundCloud';
var widget = SC.Widget(w);
// Occasions.READY is dispatched when the widget has been loaded
widget.bind(SC.Widget.Occasions.READY, perform() {
// Get the title of the at the moment enjoying sound
widget.getCurrentSound(perform(cs) {
lab = cs('title');
});
// Fireplace a dataLayer occasion when Occasions.PLAY is dispatched
widget.bind(SC.Widget.Occasions.PLAY, perform() {
act = 'Play';
sendDl(cat, act, lab);
});
// Fireplace a dataLayer occasion when Occasions.PAUSE is dispatched
// The one exception is when the sound ends, and the auto-pause just isn't reported
widget.bind(SC.Widget.Occasions.PAUSE, perform(obj) {
pos = Math.spherical(obj('relativePosition') * 100);
if (pos !== 100) {
act = 'Pause';
sendDl(cat, act, lab);
}
});
// Because the play progresses, ship occasions at 25%, 50% and 75%
widget.bind(SC.Widget.Occasions.PLAY_PROGRESS, perform(obj) {
go = false;
pos = Math.spherical(obj('relativePosition') * 100);
if (pos === 25 && !q1) {
act = '25%';
q1 = true;
go = true;
}
if (pos === 50 && !q2) {
act = '50%';
q2 = true;
go = true;
}
if (pos === 75 && !q3) {
act = '75%';
q3 = true;
go = true;
}
if (go) {
sendDl(cat, act, lab);
}
});
// When the sound finishes, ship an occasion at 100%
widget.bind(SC.Widget.Occasions.FINISH, perform() {
act = '100%';
q1 = q2 = q3 = false;
sendDl(cat, act, lab);
});
});
};
// Generic technique for pushing the dataLayer occasion
// Use a Customized Occasion Set off with "scEvent" because the occasion title
// Keep in mind to create Knowledge Layer Variables for eventCategory, eventAction, and eventLabel
var sendDl = perform(cat, act, lab) {
window.dataLayer.push({
'occasion' : 'scEvent',
'eventCategory' : cat,
'eventAction' : act,
'eventLabel' : lab
});
};
// For every SoundCloud iFrame, provoke the API integration
var i,len;
var iframes = doc.querySelectorAll('iframe(src*="api.soundcloud.com")');
for (i = 0, len = iframes.size; i < len; i += 1) {
initWidget(iframes(i));
}
} catch(e) { console.log('Error with SoundCloud API: ' + e.message); }
})();
script>
Asegúrese de que esta etiqueta HTML personalizada se energetic en un Vista de página Set off, donde está el Tipo de Set off Listo para DOM. Si no funciona, intente cambiar el tipo de disparador a Ventana cargada. Es posible que surja una condición de carrera, donde la etiqueta HTML personalizada se activa antes de que se carguen los widgets de SoundCloud, y cambiar el disparador para que se energetic en Ventana cargada debería solucionarlo.
Cortémoslo en pedazos para entender qué está pasando. ¡Esta vez empezaremos desde el closing!
// For every SoundCloud iFrame, provoke the API integration
var i,len;
var iframes = doc.querySelectorAll('iframe(src*="api.soundcloud.com")');
for (i = 0, len = iframes.size; i < len; i += 1) {
initWidget(iframes(i));
}
El código anterior recorre todos los iframes de la página. Si encuentra un iframe que carga un widget de SoundCloud integrado, llama al initWidget
método, utilizando el objeto iframe como parámetro. Esto es tan easy como parece. Lo bueno es que cada iframe tiene sus propios enlaces, por lo que puedes ejecutar el script con múltiples widgets de SoundCloud en la página.
var initWidget = perform(w) {
var currentSound, act, pos, q1, q2, q3, go, lab;
var cat = 'SoundCloud';
var widget = SC.Widget(w);
// Occasions.READY is dispatched when the widget has been loaded
widget.bind(SC.Widget.Occasions.READY, perform() {
// Get the title of the at the moment enjoying sound
widget.getCurrentSound(perform(cs) {
lab = cs('title');
});
El initWidget
La función se llama para todos los iframes de SoundCloud en la página. Primero, declara algunas variables de utilidad. A continuación, utiliza la API de widgets. SC.Widget
constructor para crear un nuevo objeto widget que la API utiliza para los enlaces.
En las siguientes líneas, el SC.Widget.Occasions.READY
El evento está vinculado al objeto del widget. Este evento se activa cuando el objeto SoundCloud incrustado se ha cargado y está listo para interactuar con él. Todos los oyentes se colocan en esta devolución de llamada de función, ya que no queremos comenzar a escuchar eventos antes de que se haya cargado el archivo incrustado, ¿verdad?
Lo primero que hacemos es obtener el título del sonido, y para ello necesitamos usar el asincrónico getCurrentSound
función, cuya devolución de llamada devuelve el objeto de sonido. Luego, accedemos a este objeto. title
clave y guárdela en una variable. Ahora tenemos todas las variables estáticas definidas y podemos crear nuestros cuatro oyentes.
// Fireplace a dataLayer occasion when Occasions.PLAY is dispatched
widget.bind(SC.Widget.Occasions.PLAY, perform() {
act = 'Play';
sendDl(cat, act, lab);
});
El primer oyente está obligado a SC.Widget.Occasions.PLAY
evento, que, sorprendentemente, se envía cuando se registra un evento “Reproducir” en el widget. Una vez que esto suceda, configuramos el act
variable a “Reproducir” e invocar la sendDl
(ver más abajo), que hace el dataLayer.push()
. Los parámetros son los cat
(“SoundNube”), act
(“Jugar”), y lab
(Título del sonido) variables.
// Fireplace a dataLayer occasion when Occasions.PAUSE is dispatched
// The one exception is when the sound ends, and the auto-pause just isn't reported
widget.bind(SC.Widget.Occasions.PAUSE, perform(obj) {
pos = Math.spherical(obj('relativePosition') * 100);
if (pos !== 100) {
act = 'Pause';
sendDl(cat, act, lab);
}
});
El próximo evento que vincularemos es SC.Widget.Occasions.PAUSE
que se envía cuando se registra un evento de “Pausa” en el widget. Es prácticamente lo mismo que el evento “Reproducir”, pero necesitamos agregar una marca adicional allí. SoundCloud pausa automáticamente el sonido cuando se completa, por lo que GA recibiría una cantidad de eventos de “Pausa” que no fueron iniciados por el usuario. Es por eso que tenemos la verificación en la primera línea de la devolución de llamada, donde básicamente vemos si el evento “Pausa” ocurrió cuando la posición del sonido está al 100%. Esto indicaría que es una pausa automática y no invocaremos sendDl
en ese caso.
// Because the play progresses, ship occasions at 25%, 50% and 75%
widget.bind(SC.Widget.Occasions.PLAY_PROGRESS, perform(obj) {
go = false;
pos = Math.spherical(obj('relativePosition') * 100);
if (pos === 25 && !q1) {
act = '25%';
q1 = true;
go = true;
}
if (pos === 50 && !q2) {
act = '50%';
q2 = true;
go = true;
}
if (pos === 75 && !q3) {
act = '75%';
q3 = true;
go = true;
}
if (go) {
sendDl(cat, act, lab);
}
});
El siguiente enlace es para el SC.Widget.Occasions.PLAY_PROGRESS
. Este evento se envía cada pocos milisegundos y el objeto que devuelve tiene la posición relativa del sonido en el momento del evento. Esta posición relativa es en realidad un porcentaje de hasta qué punto el usuario ha escuchado la pista. Entonces, debido a que elegí enviar un evento al 25%, 50%, 75% y 100%, necesito verificar si la posición relativa está en estos hitos. También uso un par de booleanos, q1 q2 q3 go
que evitan que el mismo hito se envíe varias veces. El go
La variable garantiza que el evento GA solo se energetic cuando se alcancen los hitos, y no para cada iteración del evento PLAY_PROGRESS.
// When the sound finishes, ship an occasion at 100%
widget.bind(SC.Widget.Occasions.FINISH, perform() {
act = '100%';
q1 = q2 = q3 = false;
sendDl(cat, act, lab);
});
Finalmente cuando termina el sonido enviamos el evento 100%, y también reseteamos las variables de utilidad. Si no los restablecemos, las escuchas repetidas no se grabarán.
// Generic technique for pushing the dataLayer occasion
// Use a Customized Occasion Set off with "scEvent" because the occasion title
// Keep in mind to create Knowledge Layer Variables for eventCategory, eventAction, and eventLabel
var sendDl = perform(cat, act, lab) {
window.dataLayer.push({
'occasion' : 'scEvent',
'eventCategory' : cat,
'eventAction' : act,
'eventLabel' : lab
});
};
Y aquí está el sendDl
método. Simplemente toma los parámetros y los introduce en un dataLayer
objeto.
El gatillo
Para activar etiquetas GTM cuando se registra un evento de SoundCloud, cree un nuevo activador de evento personalizado que se vea así:
Es easy. Este disparador disparará sus etiquetas cuando el sendDl
Se invoca el método que construimos anteriormente.
Las variables de la capa de datos
A continuación, asegúrese de tener tres Variables de la capa de datos. uno para eventCategory
uno para eventAction
y uno para eventLabel
. Se verían así:
Estos son bastante genéricos, por lo que pueden resultarle útiles. en otra parte también.
La etiqueta de evento
Finalmente, necesita una etiqueta de evento para llevar esta información a Google Analytics. Configúrelo como lo haría con cualquier otra etiqueta de evento y asegúrese de que se energetic con el activador que creó antes (Evento – scEvent). Luego, agregue las tres Variables que creó a sus respectivos campos:
¡Y eso es todo! Ahora su sitio debería estar listo para recopilar visitas de los widgets de SoundCloud.
Resumen y advertencias
Primero, algunas advertencias.
De vez en cuando noté una molesta condición de carrera, donde el widget se había cargado antes de que la etiqueta HTML personalizada de GTM tuviera tiempo de completarse. Esto significa que el SC.Widget.Occasions.READY
se envió demasiado pronto para que el oyente lo captara. Esta condición de carrera podría solucionarse teniendo un tiempo de espera de un segundo o algo así, que luego realiza las vinculaciones de todos modos. No lo escribí en esta solución, pero debería ser bastante trivial de implementar una vez que comprendas cómo funciona la API de widgets.
Algunas otras cosas que noté fueron errores de cuota de la API. No hay nada que puedas hacer al respecto, aunque creo que puedes suscribirte a alguna cuenta Premium donde estos errores no surjan. Sin embargo, hasta donde yo sé, no tuvieron ningún impacto en esta solución de seguimiento y, de todos modos, los eventos se enviaron.
De todos modos, esta es una solución bastante easy para rastrear los widgets de SoundCloud en su sitio. He tratado de reflejar el excelente guía de seguimiento de youtube por Camino Cardenal.
El API de widgets tiene otras interfaces que puede aprovechar si desea mejorar aún más la solución. ¡Avíseme si encontró algún problema o si tiene concepts sobre cómo mejorar esta solución!