Je vais aujourd’hui te présenter comment utiliser l’API de ConvertKit avec le langage de programmation Python.
Je t’avertis tout de suite, leur API est en cours de développement et n’est pas aussi complète qu’on pourrait le souhaiter.
Par exemple, les séquences automatisées et les actions automatiques ne sont pas encore couverts. Lorsque ces fonctionnalités seront disponibles, je vais venir bonifier cet article.
Cependant, il est déjà possible d’extraire des données de ses contacts et le contenu des courriels qui ont été envoyés. Et donc, on peut quand même faire des choses plutôt intéressantes !
Se préparer !
Variables d’environnement pour l’API de ConvertKit
Nous allons commencer par configurer deux variables d’environnement sur notre système. Ce sont les jetons d’application. Ils sont fournis par ConvertKit dans la section Settings / Advanced / API
Sur Linux ou MacOS, on peut configurer ces variables avec le script suivant dans .zshrc ou .bashrc:
export CONVERTKIT_API_KEY="" export CONVERTKIT_API_SECRET=""
Sur Windows, il faut utiliser PowerShell comme suit:
Set-Item -Path Env:CONVERTKIT_API_KEY -Value "" Set-Item -Path Env:CONVERTKIT_API_SECRET -Value ""
Démarrage du script
Nous allons charger les modules requis pour notre programme
import time import requests import json import os
time
permet de gérer le temps d’exécution, par exemple prendre une pause entre deux requêtes HTTP.requests
permet de faire des requêtes HTTP. Dans notre cas, ce sera à un API REST.json
permet de lire et d’écrire des fichiers jsonos
permet d’interagir avec le système d’exploitation
Puis, nous chargeons les variables d’environnement dans notre espace de travail Python
api_key=os.getenv("CONVERTKIT_API_KEY") api_secret=os.getenv("CONVERTKIT_API_SECRET") base_url="https://api.convertkit.com"
On crée ensuite un répertoire ./json
pour les fichiers de sortie s’il n’existe pas déjà.
try: os.mkdir("./json") except OSError as error: print(error)
Nous sommes maintenant prêts à débuter les extractions. L’API de Convertkit est relativement simple à utiliser.
Elle utilise la pagination, donc il faut parfois faire une boucle pour obtenir toutes les valeurs pour un point de terminaison.
Nous allons utiliser le module requests
pour faire toutes nos requêtes HTTP.
Le compte et les formulaires
Le compte
Nous pouvons obtenir les information de base sur le compte que nous utilisons avec le point de terminaison /v3/account
r = requests.get(url=base_url+"/v3/account", params={"api_secret":api_secret}) account = r.json() account
La réponse prend la forme suivante:
{'name': None, 'plan_type': 'creator', 'primary_email_address': '<ton courriel>'}
Les formulaires
Les formulaires sont les points d’entrée des abonnés dans le système de ConvertKit. Chaque abonné est toujours rattaché à un formulaire, et c’est à partir d’eux qu’on pourra les lister dans la prochaine section. On les obtient via le point de terminaison /v3/forms
La réponse prend la forme d’une liste
r = requests.get(url=base_url+"/v3/forms", params={"api_secret":api_secret}) forms = r.json() forms
{'forms': [{'id': XXXXXXX, 'name': 'Abonnement à la liste courriel', 'created_at': 'XXXXXXX', 'type': 'embed', 'format': 'inline', 'embed_js': 'https://tondomaineici.ck.page/XXXXXXX/index.js', 'embed_url': 'https://tondomaineici.ck.page/XXXXXXX', 'archived': False, 'uid': 'XXXXXXX'}, ...
Pour faciliter l’extraction des abonnés, on conserve les identifiants uniques des formulaires
form_ids = [form.get("id") for form in forms.get("forms")]
Les abonnés
La pagination dans l’API de ConvertKit
Pour extraire les comptes des abonnés, nous allons utiliser pour la première fois la pagination.
Ça nous donne du code un peu plus costaud.
Essentiellement, on itère sur chacun des formulaires, puis, on boucle sur chacune des pages de réponses s’il y en a plus qu’une, et on accumule les abonnés dans une liste.
Les comptes
Pour extraire les comptes, ça nous donne le code suivant.
subscribers_list = [] for form_id in form_ids: r = requests.get(url=base_url+ "/v3/forms/"+ str(form_id)+ "/subscriptions", params={"api_secret":api_secret, "subscriber_state":"active", "page":1}) page1 = r.json() nb_pages = page1.get("total_pages") subscribers_list.append(page1) if nb_pages>1: for i in range(1,nb_pages): time.sleep(1) page = requests.get( url=base_url+ "/v3/forms/"+ str(form_id)+ "/subscriptions", params={"api_secret":api_secret, "subscriber_state":"active", "page":i+1}) subscribers_list.append(page.json()) subscribers={"subscribers":subscribers_list}
Les étiquettes
Pour extraire les étiquettes, la requête est plutôt simple:
r = requests.get(url=base_url+"/v3/tags", params={"api_secret":api_secret}) tags=r.json()
On conserve ensuite les identifiants uniques de chacune des étiquettes, parce que c’est ce qui nous permet d’extraire la liste des abonnés pour chacunes d’elles.
tag_ids = [tagdict.get("id") for tagdict in tags.get("tags")]
Les abonnés par étiquette
On reprend la même logique que pour obtenir les abonnés par formulaire, mais avec les étiquettes cette fois.
tag_subscriptions = [] for tag_id in tag_ids: r = requests.get(url=base_url+ "/v3/tags/"+ str(tag_id)+ "/subscriptions", params={"api_secret":api_secret, "page":1, "subscriber_state": "active"}) tag_subscription_page1 = r.json() tag_subscriptions.append(tag_subscription_page1) nb_pages = page1.get("total_pages") if nb_pages>1: for i in range(1,nb_pages): time.sleep(1) page = requests.get(url=base_url+ "/v3/tags/"+ str(tag_id)+ "/subscriptions", params={"api_secret":api_secret, "page":i+1, "subscriber_state": "active"}) tag_subscriptions.append(page.json()) tag_subs={"tag_subscriptions":tag_subscriptions}
Les courriels
Les séquences
Selon le même modèle que précédemment avec les formulaires ou les étiquettes, on peut obtenir les séquences.
r = requests.get(url=base_url+"/v3/sequences", params={"api_secret":api_secret}) sequences=r.json()
On conserve les identifiants, pour extraire la liste des abonnés actifs dans chacune des séquences
sequences_ids = [sequencesdict.get("id") for sequencesdict in sequences.get("courses")]
Abonnés actuellement dans une séquence
On utilise le même modèle que pour les formulaires ou les étiquettes pour extraire les abonnés pour chacune des séquences
sequences_subscriptions = [] for sequences_id in sequences_ids: r = requests.get(url=base_url+ "/v3/sequences/"+ str(sequences_id)+ "/subscriptions", params={"api_secret":api_secret, "page":1, "subscriber_state": "active"}) sequences_subscription_page1 = r.json() sequences_subscriptions.append(sequences_subscription_page1) nb_pages = page1.get("total_pages") if nb_pages>1: for i in range(1,nb_pages): time.sleep(1) page = requests.get(url=base_url+"/v3/sequences/"+ str(sequences_id)+"/subscriptions", params={"api_secret":api_secret, "page":i+1, "subscriber_state": "active"}) sequences_subscriptions.append(page.json()) sequences_subs={"sequences_subscriptions":sequences_subscriptions}
Les contenus et leurs statistiques
On peut extraire une liste de tous les courriels envoyés. Il n’y a pas de moyen pour attraper automatiquement le nombre de pages, mais il y a 50 envois par page.
r1 = requests.get(url=base_url+"/v3/broadcasts", params={"api_secret":api_secret, "page":1}) r2 = requests.get(url=base_url+"/v3/broadcasts", params={"api_secret":api_secret, "page":2}) r3 = requests.get(url=base_url+"/v3/broadcasts", params={"api_secret":api_secret, "page":3}) broadcasts=[r1.json(),r2.json(),r3.json()]
On extrait les identifiants uniques de chacun des envois
broadcasts_ids = [broadcastsdict.get("id") for broadcastsdict in broadcasts.get("broadcasts")]
On peut maintenant faire une boucle sur chaque envoi et récupérer d’un seul coup le contenu des courriels, sous la forme d’un document HTML, ainsi que les statistiques actuelles.
for broadcast in broadcasts: broadcasts_ids = [broadcastsdict.get("id") for broadcastsdict in broadcast.get("broadcasts")] for broadcasts_id in broadcasts_ids: time.sleep(1) r = requests.get(url=base_url+"/v3/broadcasts/"+str(broadcasts_id), params={"api_secret":api_secret}) broadcast_content = r.json() rstats = requests.get(url=base_url+"/v3/broadcasts/"+str(broadcasts_id)+"/stats", params={"api_secret":api_secret}) broadcast_stats = rstats.json() with open('./json/broadcast_content_'+str(broadcasts_id)+'.json', 'w') as f: json.dump(broadcast_content, f) with open('./json/broadcast_stats_'+str(broadcasts_id)+'.json', 'w') as f: json.dump(broadcast_stats, f)
Exporter les données sous la forme de fichiers JSON
C’est maintenant le temps d’exporter toutes ces données sous la forme de fichiers JSON.
with open('./json/account.json', 'w') as f: json.dump(account, f) with open('./json/forms.json', 'w') as f: json.dump(forms, f) with open('./json/subscribers.json', 'w') as f: json.dump(subscribers, f) with open('./json/tags.json', 'w') as f: json.dump(tags, f) with open('./json/tag_subs.json', 'w') as f: json.dump(tag_subs, f) with open('./json/sequences.json', 'w') as f: json.dump(sequences, f) with open('./json/sequences_subs.json', 'w') as f: json.dump(sequences_subs, f) with open('./json/broadcasts.json', 'w') as f: json.dump(broadcasts, f)
Conclusion
Nous avons maintenant exporté la majorité des données pouvant être actuellement exportées depuis l’API de Convertkit.
Cette technique peut servir à faire une sauvegarde locale de notre contenu ou de nos abonnés, ou elle peut aussi servir à enrichir un autre système tel qu’un CRM.