Bonne journée à tous! Je pense que cet article sera intéressant pour tous ceux qui utilisent Notion, mais pour une raison quelconque, je ne pourrais pas y accéder complètement.
Préhistoire
Je développe
mon projet . Sur la page de destination après avoir saisi l'e-mail, un lien vers une enquête sociale basée sur Google Forms est émis. Les réponses sont enregistrées sur la plaque signalétique de Google Drive.
Le problème est que tout ce que je
porte avec moi, je le garde dans Notion. C'est ringard plus pratique. Géré par copier-coller, alors qu'il y avait peu de critiques. Ensuite, il y en avait plus - et il fallait trouver quelque chose. Peu importe ce qui s'est passé - bienvenue au chat.
Le problème
Google Forms enregistre les réponses uniquement sur la plaque signalétique, c'est-à-dire qu'il n'y a pas d'autre recette ici. Par conséquent, j'avais un plan: écoutons via IFTTT les mises à jour des tablettes, envoyons de nouvelles données au webhook, les traitons d'une manière ou d'une autre et les téléchargeons sur Notion.
Pour ceux qui ne connaissent pas IFTTT: c'est un service qui vous permet de faire des enchaînements d'actions. Dites, "le message est venu par télégrammes" - "nous l'exportons sur VKontakte".
Le plan a commencé à échouer: Notion n'a pas d'API officielle. Mais quelqu'un l'a inversé et a créé
une API non officielle .
Le plan final était le suivant:- Nous faisons l'applet dans IFTTT: «Une ligne a été ajoutée à la tablette - envoyez-la au serveur
- Nous faisons directement le serveur qui reçoit les données et les envoie à Notion
Le deuxième problème est apparu lorsqu'il s'est avéré que IFTTT avait rompu l'intégration avec Google Sheets et que l'applet ne fonctionnait donc pas.

Par conséquent, j'ai dû changer le plan: nous pompons le csv'shku avec Google Sheets, l'analysons sur le serveur et jetons tout nouveau dans Notion. IFTTT est utilisé comme déclencheur pour l'ensemble du processus.
Partie 1. CSV avec Google Sheets
Cette partie est peut-être la plus simple. Nous ouvrons la table pour la visualisation (afin que vous n'ayez pas à vous soucier des cookies). Ensuite, prenez et copiez le lien pour exporter CSV. Pour ce faire, appuyez simplement sur Ctrl sur le clavier et tapez Ctrl + Maj + J (c'est-à-dire, ouvrez la console du développeur), accédez à l'onglet Réseau. Cliquez ensuite sur Fichier - Télécharger - CSV. Nous voyons la demande et copions le lien.
Partie 2. Écrire un serveur
Puisque nous avons une bibliothèque Python, nous allons écrire dans Django.
Maintenant, un peu sur la structure de ma table en particulier. Une table dans Notion, contrairement à une table dans Google Sheets, a une colonne "Référence". Il s'agit d'un lien vers une autre table (dans mon cas, une description des fonctions que les utilisateurs ont appréciées). Le reste est généralement clair: juste des colonnes avec juste des données.
Nous allons à Notion, nous connaissons déjà Ctrl + Shift + J ouvrez la console, allez à Application - Cookies, copiez token_v2 et appelez-le TOKEN. Ensuite, nous allons à la page dont nous avons besoin avec la plaque et copions le lien vers elle. Appelez NOTION. Si vous avez également Relation, accédez à la page avec Relation, copiez le lien et appelez, par exemple, NOTION_FUNCTIONS
Ensuite, écrivez le code suivant (notion de pré-importation):
def index(request): if request.method == "POST": client = NotionClient(token_v2=TOKEN) database = client.get_collection_view(NOTION) current_rows = database.default_query().execute() database_functions = client.get_collection_view(NOTION_FUNCTIONS) current_rows_functions = database_functions.default_query().execute()
Nous y connectons NotionClient, nous disons „Bases de données? Donnez-en deux! »Et nous obtenons directement les données de ces deux plaques (par défaut demande, mais c'est possible avec le tri, pour plus de détails, voir la documentation de la bibliothèque).
Ensuite, nous devons faire ce qui suit: demander un CSV à Google et l'analyser. Nous le ferons pandas'om.
result = requests.get(SHEET).content pandas_result = pd.read_csv(io.StringIO(result.decode('utf-8'))) timestamps = pandas_result[[" "]].values ages = pandas_result[[" "]].values sexes = pandas_result[[" "]].values cities = pandas_result[[" "]].values socials = pandas_result[[" ( )"]].values agreements = pandas_result[[" , - ."]].values control_usages = pandas_result[[" "]].values health_usages = pandas_result[[" "]].values prices = pandas_result[[" . :)"]].values mentions = pandas_result[[", , "]].values
Ensuite, nous devons parcourir toutes les données de cette plaque et vérifier si elles sont ajoutées à Notion ou pas encore. Pour ce faire, nous avons demandé des données aux plaques.
def checkTimestamp(rows, timestamp): for i in range(0, len(rows)): row = rows[i] if row.name == timestamp: return True return False
Séparément, il convient de mentionner «row.name», car un lecteur attentif demandera probablement: qu'est-ce que c'est?
Il s'agit du nom de la colonne dans Notion (où les temps d'enregistrement sont stockés). Je n'ai pas réussi à ajouter des noms russes, j'ai donc changé tous les noms en anglais et je les ai ajoutés.

Et maintenant, le code pour vérifier les données et ajouter une ligne à l'étiquette Notion:
for i in range(0, len(timestamps)): if not checkTimestamp(current_rows, timestamps[i]): row = database.collection.add_row() health_usage = health_usages[i][0] control_usage = control_usages[i][0] ticks = health_usage + "," + control_usage row.title = timestamps[i][0] row.age = ages[i][0] row.sex = sexes[i][0] row.social_network = checkEmptiness(socials[i][0]) row.can_we_write_you = checkEmptiness(agreements[i][0]) row.city = checkEmptiness(cities[i][0]) row.controlling_examples = checkEmptiness(control_usages[i][0]) row.health_examples = checkEmptiness(health_usages[i][0]) row.cost = checkEmptiness(prices[i][0]) row.noticements = checkEmptiness(mentions[i][0]) row.castdev_relation = findIds(current_rows_functions, ticks)
checkEmptiness est une fonction qui vérifie si un élément nul lui a été transmis. Notion a en quelque sorte travaillé à contrecœur quand je lui ai donné zéro champs, donc ça vaut le coup d'écrire.
Passons maintenant à l'analyse des relations, car dans la documentation officielle je n'en ai pas vu. Pour créer un lien vers une ligne d'une autre base de données, vous devez la prendre (de cette ligne) et la transférer. Par conséquent, si un tableau de liens vers des chaînes d'une autre plaque est implicite, vous devez prendre un tableau de leurs identifiants. J'ai personnellement ajouté Relations par nom de fonction.
def findIds(current_rows, titles): print("titles", titles) print("current rows", current_rows) array = [] for a in range(0, len(current_rows)): if current_rows[a].name in titles: array.append(current_rows[a].id) print("Ids", array) return array
À la fin, après avoir créé les lignes, nous ajoutons la réponse pour qu'à l'autre bout ils sachent que la demande est arrivée.
return HttpResponse("Hello, habr.")
Taschemta avec le serveur le plus important est terminé, allez sur IFTTT.
Partie 3. IFTTT
Accédez à l'
onglet de création d'applet . Nous sélectionnons le déclencheur (dans notre cas, il s'agit de la date et de l'heure), réglé sur «toutes les heures». Nous sélectionnons le Webhook déclenché (c'est-à-dire «cela»), indiquons notre (jusqu'à présent) adresse locale afin de le tester. Eh bien, c'est tout. Testez.
Partie 4. Heroku
Vous pensiez à quoi nous jouions avec ce déclencheur de l'IFTTT - ce n'est pas à payer. Heroku propose un tarif gratuit pour l'hébergement de nos produits. L'essentiel est que le service dorme au moins 6 heures. Et il dormira certainement, car nous l'appelons au travail toutes les heures, et non toutes les minutes.

De plus, nous faisons ce qui suit. Accédez à Heroku pour
créer un nouveau projet . Ensuite, installez
leur client sur leur système d'exploitation. Et puis nous faisons tout selon les instructions qui sont apparues après la création de l'application.
Après avoir tout téléchargé sur heroku, accédez à notre applet et modifiez l'URL en une nouvelle.
Maintenant, la liste doit être mise à jour toutes les heures. Hypothétiquement, IFTTT peut donner une erreur que vous avez une sorte de longue demande, mais ce n'est pas si important.
Mettre à jour
Cela s'est avéré important. Lorsque l'IFTTT intercepte les erreurs persistantes, il commence à ignorer les applets.
Pour résoudre ce problème, il suffit de démarrer un nouveau fil pour tout cela, donnant immédiatement la réponse.
if request.method == "POST": thread = Thread(target=run_notion_import) thread.start() return HttpResponse("Hello, habr.")
Une autre idée que j'ai oublié d'exprimer dans l'article est de vérifier la nullité en utilisant la méthode standard des pandas.
Autrement dit, votre chèque ressemblera à ceci:
if not pd.isna(health_usages[i][0]): row.health_examples = health_usages[i][0]