Utiliser l’API de ConvertKit avec Python

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

Obtenir les jetons de l'API de ConvertKit

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 json
  • os 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.

Boucles d'itération sur les formulaires et les pages de l'API de ConvertKit pour obtenir les abonnés

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.

Référence

Contenus que tu pourrais apprécier