# Support pour les iframes

Les iframes intégrées sur votre site peuvent utiliser les commandes fournies par la [CMP API](https://cmp.docs.sirdata.net/cmp-api/fonctionnement).\
Pour cela, elles doivent effectuer des appels à la "frame" parente (ou à une frame ancêtre) sur laquelle la CMP est chargée, en envoyant les commandes sous forme de message grâce à la fonction `postMessage()`.

La frame vers laquelle effectuer l'appel peut être déterminée par l'ancêtre en cherchant la frame enfant `.frames["__tcfapiLocator"]`.

### Envoyer une commande <a href="#iframe-send-command" id="iframe-send-command"></a>

Le message à envoyer doit avoir le format ci-dessous où l'objet `__tcfapiCall` contient les informations de la commande à exécuter.\
`command` et `parameter` sont identiques aux paramètres passés à la fonction `__tcfapi()`, et `callId` est un ID unique à déterminer.

{% tabs %}
{% tab title="Format \_\_tcfapiCall" %}

```javascript
{
	__tcfapiCall: {
		command: *command*, // name of the command to execute
		version: 2, // version of the TCF specification
		parameter: *parameter*, // parameter to be passed to the command function
		callId: *uniqueId* // unique call ID
	}
}
```

{% endtab %}

{% tab title="Exemple" %}

```javascript
this.callId = this.callId || 0;
var message = {
	__tcfapiCall: {
		command: 'addEventListener',
		version: 2,
		parameter: null,
		callId: ++this.callId
	}
};
window.top.postMessage(message, '*');
```

{% endtab %}
{% endtabs %}

### Récupérer le résultat de la commande <a href="#iframe-get-result" id="iframe-get-result"></a>

Avant d'envoyer des messages, l'iframe doit mettre en place une fonction JavaScript à exécuter lorsqu'un message est renvoyé en retour. Pour cela, elle doit tracer l'évènement message avec la fonction `window.addEventListener()`.\
De cette façon, elle récupèrera et pourra traiter le résultat de la commande contenu dans `__tcfapiReturn`.

{% hint style="danger" %}
La fonction `window.addEventListener()` est différente de la commande [addEventListener](https://cmp.docs.sirdata.net/cmp-api/exemples#add-event-listener), qui est propre à la CMP API.
{% endhint %}

{% tabs %}
{% tab title="Exemple" %}

```javascript
function processMessage(event) {
	if (event && event.data && event.data.__tcfapiReturn && event.data.__tcfapiReturn.success) {
		console.log(event.data.__tcfapiReturn.returnValue);
	}
}
window.addEventListener('message', processMessage);
```

{% endtab %}
{% endtabs %}

Lorsqu'une commande est envoyée, le message renvoyé en retour (*event.data*) contient l'objet `__tcfapiReturn` avec le résultat de la commande.\
`returnValue` et `success` sont identiques aux paramètres passés à la callback de la fonction `__tcfapi()`, et `callId` correspond à l'ID de l'appel d'origine (`__tcfapiCall`).

{% tabs %}
{% tab title="Format \_\_tcfapiReturn" %}

```javascript
{
    __tcfapiReturn: {
        returnValue: *returnValue*, // result of the command
        success: *boolean*, // true if the call to the command was successful
        callId: *uniqueId* // call ID sent in the __tcfapiCall
    }
}
```

{% endtab %}

{% tab title="Exemple" %}

```javascript
function processMessage(event) {
	if (event && event.data && event.data.__tcfapiReturn && event.data.__tcfapiReturn.success) {
		var tcData = event.data.__tcfapiReturn.returnValue;
		if (!tcData.gdprApplies) {
			console.log("GDPR doesn't apply to user");
		}
		console.log("TC String : ", tcData.tcString);
	}
}
window.addEventListener('message', processMessage);

this.callId = this.callId || 0;
var message = {
	__tcfapiCall: {
		command: 'addEventListener',
		version: 2,
		parameter: null,
		callId: ++this.callId
	}
};
window.top.postMessage(message, '*');
```

{% endtab %}
{% endtabs %}

Vous trouverez ci-dessous un exemple de script qui émule l'API \_\_tcfapi() dans une iframe.

Il localise la trame ancêtre exécutant le CMP, exécute le postMessage et écoute le message de retour et transmet ses valeurs au rappel.

En clair, les scripts de l'iframe fonctionneront comme si la CMP y était chargée directement.

```javascript
<script>
    !function(){var a=window,c;var o={};for(;a;){try{if(a.frames.__tcfapiLocator){c=a;break}}catch(a){}if(a===window.top)break;a=a.parent}window.__tcfapi=function(a,t,n,e){c?(t={__tcfapiCall:{command:a,parameter:e,version:t,callId:e=Math.random()+""}},o[e]=n,c.postMessage(t,"*")):n({msg:"CMP not found"},!1)},window.addEventListener("message",function(a){var t={};try{t="string"==typeof a.data?JSON.parse(a.data):a.data}catch(a){}var n=t.__tcfapiReturn;n&&"function"==typeof o[n.callId]&&(o[n.callId](n.returnValue,n.success))},!1);window.__sdcmpapi=window.__tcfapi;}();
</script>
```

{% hint style="warning" %}
Ne chargez pas les scripts de la CMP dans l'iframe :)
{% endhint %}
