Frappe Framework
Étendre les automatisations
emit met en file les flux Custom Event et reprend un WaitForEvent. Une action non transactionnelle n’est jamais rejouée depuis le début.
Trois extensions
Une application étend les flux de trois façons, toutes dans hooks.py : émettre un événement, ajouter une action, ajouter une relation que le schéma n’exprime pas. Les étapes qui les consomment sont dans Étapes et actions.
Émettre
emit(event, doc, payload, correlation_key) depuis frappe.automation_engine. Le nom est préfixé par l’app, par exemple crm.deal_won. doc est le document. Les flux Custom Event qui ont un Document Type tournent dessus. payload est un dict sérialisable en JSON, lu comme payload dans les gabarits et context["payload"] dans les conditions. correlation_key reprend un WaitForEvent de même événement et même clé.
emit met en file chaque flux Custom Event activé pour cet événement, et reprend les attentes si la clé est donnée. Il renvoie queued et resumed. Les runs partent après le commit. Deux appels pour le même enregistrement avant ce commit n’en font qu’un. Un payload au-dessus de Event Payload Limit, 64 Ko par défaut dans Automation Settings, est refusé.
Reprise : le flux a envoyé un e-mail puis attend crm.email_replied avec la clé {{ doc.name }}. À la réponse, l’app émet le même nom, doc=lead, un payload communication, et correlation_key=lead.name. La suite lit context["event"]["payload"].
Sans Allow Unregistered Events, seuls les événements enregistrés passent. automation_events mélange des noms et des dictionnaires. L’exemple crm.email_replied a un label, une description, et un subject : doctype_key reference_doctype, name_key reference_name, doctypes CRM Lead et CRM Deal. Le sujet dit de quel enregistrement il s’agit, lu dans le payload. Un flux sur CRM Lead vise alors le lead du payload, même si le code tenait une Communication. Si le type est fixe, "doctype": "CRM Lead" remplace doctype_key.
Actions
Sous-classer AutomationAction, action_type unique à ne plus changer après publication, label, description, params_schema (fieldname, label, fieldtype, options, reqd). requires_document à False si l’action peut tourner sans document, par exemple un flux planifié. applicable_doctypes et supported_trigger_types limitent, None signifie tous. transactional à False si un rollback ne peut pas défaire l’effet, HTTP ou message : le moteur ne rejoue alors jamais le run depuis le début.
validate à l’enregistrement et avant chaque exécution. AutomationParamError porte un fieldname. execute renvoie une courte chaîne pour le journal, ou un dict avec detail et le reste lu via context["steps"][step_key]. output_doctype permet à Output Alias de viser l’enregistrement créé.
L’exemple PostToChannel a channel et message obligatoires, transactional = False, rend le message avec render_value, appelle post_message sans le définir dans la page, et renvoie « Posted to … ». Le hook : automation_actions = ["my_app.automation.PostToChannel"].
L’action tourne comme l’utilisateur Run As. Pas de frappe.db.commit(). Pour mettre en pause depuis l’action : StopAutomation("reason", resume_after=seconds).
Relations
Lien, lien dynamique et lien de table enfant existent déjà, dans les deux sens. Un provider ne sert que pour le reste, par exemple un e-mail. get_definitions renvoie, pour Communication seulement, sender_lead vers CRM Lead, cardinality one. resolve cherche un CRM Lead dont email vaut source_doc.sender. Hook : automation_relationships. automation_relationship_ignore cache des DocTypes, par exemple un journal, des relations dérivées.
Seule une cardinalité one peut être l’alias cible d’une étape. many sert aux conditions sur les enregistrements liés. Surcharger query() filtre en SQL. Un name identique à une relation dérivée la remplace, pour la renommer. Chaque référence est vérifiée : elle existe, et l’utilisateur peut la lire.
Couper
is_enabled() dit si les automatisations tournent. skip_automations() autour de doc.save() empêche tout flux pour cet enregistrement.
Point d’attention
action_type ne se renomme pas après coup. Un payload de plus de 64 Ko est rejeté, sauf si Automation Settings a changé la limite.
