Passer au contenu principal

Formulaires et cas : CommCare et intégration basée sur les événements

C'est rapide, mais je viens de passer un appel passionnant avec une organisation qui va mettre en place des jobs pour déplacer des données dans Salesforce à partir de CommCare et j'ai réalisé que bien que cela soit l'une de nos exigences d'intégration les plus courantes, nous n'avons pas fait un article des «astuces» pour ce type de projet. Jusqu'à présent.

Alors voilà. Bien qu'il ne s'agisse en aucun cas d'un modèle de planification de projet exhaustif, voici quelques éléments à garder à l'esprit si vous envisagez de mettre en œuvre vous-même une intégration CommCare à Salesforce.

La plupart des gens utilisent le "Transfert de données" dans CommCare

Tout d'abord, la plupart des gens utilisent la fonction « Transmission de données » de CommCare pour envoyer des soumissions de formulaires et des changements de cas (création, mise à jour, fermeture, etc.) à OpenFn en temps réel. Vous pouvez en savoir plus à ce sujet ici mais la principale considération à ce stade de planification est quand vous effectuerez les opérations —créer(...), update(...), upsert(...), query(...), (massif(...), etc.—dans Salesforce et à quelles données vous aurez accès.

Chaque fois qu'une soumission de formulaire arrive dans CommCare, nous obtenons une copie de cette soumission chez OpenFn et pouvons utiliser ces données pour créer ou modifier certains enregistrements dans Salesforce.

De même, chaque fois qu'un cas est mis à jour (ou créé ou fermé), nous obtiendrons une copie du cas avec toutes les "propriétés" du cas et nous pouvons utiliser ces données pour faire quelque chose dans Salesforce.

Si vous utilisez "Transfert de formulaire", le trigger que vous créez dans OpenFn pourrait ressembler à ceci {"form":{"@name":"ART Adherence Self-Reporting Tool"}} et il déclencherait votre job à chaque fois qu'une soumission "ART Adherence Self-Reporting Tool" est arrivée de CommCare, en donnant accès à toutes les données à l'intérieur de cette soumission.

Travailler avec les données en provenance de CommCare

En supposant que vous utilisez la gestion de cas, les données qui arrivent de CommCare ressembleront à ceci :

{
"__query_params": {
"app_id": "some-long-id"
},
"app_id": "some-long-id",
"archived": false,
"attachments": {
"1621866020043.jpg": {
"content_type": "image/jpeg",
"length": 16423,
"url": "https://www.commcarehq.org/a/your-project/api/form/attachment/some-uuid/1621866020043.jpg"
},
"form.xml": {
"content_type": "text/xml",
"length": 2727,
"url": "https://www.commcarehq.org/a/your-project/api/form/attachment/some-uuid/form.xml"
}
},
"build_id": "0ec83881cd0e420dad5c24ed3a5452fe",
"domain": "your-project",
"edited_by_user_id": null,
"edited_on": null,
"form": {
"#type": "data",
"@name": "ART Adherence Self-Reporting Tool",
"@uiVersion": "1",
"@version": "2783",
"@xmlns": "http://openrosa.org/formdesigner/59E1207B-969F-402D-9EEE-675504036F78",
"administrative": {
"coach_verification": "vérifier_ici",
"visit_notes": "",
"vist_notes_to_save": ""
},
"case": {
"@case_id": "1ec51ee9-5aef-4bd2-b7eb-7599856251bc",
"@date_modified": "2021-05-24T14:20:28.693000Z",
"@user_id": "332e893dcd1b413686621bd80aae0cd3",
"@xmlns": "http://commcarehq.org/case/transaction/v2",
"update": {
"consent_received": "oui",
"home_visit_notes": ""
}
},
"meta": {
"@xmlns": "http://openrosa.org/jr/xforms",
"appVersion": "CommCare Android, version \"2.51.2\"(463994). App v2798. CommCare Version 2.51.2. Build 463994, built on: 2021-03-17",
"app_build_version": 2798,
"commcare_version": "2.51.2",
"deviceID": "commcare_a39f55a5-c744-4e33-8e01-d17e7698894f",
"drift": "0",
"geo_point": null,
"instanceID": "130c68c5-7d17-4086-8a85-27d7d7da2216",
"timeEnd": "2021-05-24T14:20:28.693000Z",
"timeStart": "2021-05-24T14:18:46.856000Z",
"userID": "332e893dcd1b413686621bd80aae0cd3",
"username": "some-chw"
},
"participant_information": {
"participant_id": "007",
"name": "taylor downs",
"gender": "masculin",
"guardian_information": {
"guardians_name": "Fake Data",
"guardians_phone_number": "8675309",
"guardians_signature": "1621866020043.jpg",
"relationship_to_participant": "father"
},
"current_medications": [
{ "name": "generic-1", "actif": vrai },
{ "name": "fakelyn-notrealiol", "actif": faux },
{ "name": "sasstra-zenica", "actif": faux},
{ "name": "ibuprofen", "active": vrai }
]
},
"tested_for_hiv_status_tested_for_hiv": "OK",
"visit_information": {
"consent_given": "oui",
"date_consent_given": "2021-05-23",
"visit_date": "2021-05-23"
}
},
"id": "130c68c5-7d17-4086-8a85-27d7d7da2216",
"indexed_on": "2021-05-24T14:20:39.045971",
"initial_processing_complete": vrai,
"is_phone_submission": vrai,
"metadata": {
"appVersion": "CommCare Android, version \"2.51.2\"(463994). App v2798. CommCare Version 2.51.2. "app_build_version": 2798,
"commcare_version": "2.51.2",
"deviceID": "commcare_a39f55a5-c744-4e33-8e01-d17e7698894f",
"drift": "0",
"geo_point": null,
"instanceID": "130c68c5-7d17-4086-8a85-27d7d7da2216",
"location": null,
"timeEnd": "2021-05-24T14:20:28.693000Z",
"timeStart": "2021-05-24T14:18:46.856000Z",
"userID": "332e893dcd1b413686621bd80aae0cd3",
"username": "some-chw"
},
"problem": null,
"received_on": "2021-05-24T14:20:37.976363Z",
"resource_uri": "",
"server_modified_on": "2021-05-24T14:20:38.111789Z",
"type": "data",
"uiversion": "1",
"version": "2783"
}

Il s'agit d'un gros bloc de JSON- le corps du message qui est reçu à OpenFn lorsque ce formulaire particulier ("ART Adherence Self-Reporting Tool") est soumis dans CommCare - sera remis à la tâche pour commencer le traitement. La question est : que devons-nous faire ?

Lors de la configuration d'une implémentation en libre-service sur OpenFn, la chose la plus importante que vous puissiez faire en ce moment est d'énumérer soigneusement le processus de saisie de données que vous aimeriez qu'un vrai humain suive. Vous pouvez le traduire ultérieurement en script de travail.

Vous devrez écrire ceci pour votre propre cas, mais dans cet exemple fictif, voici le processus de saisie des données.

Les instructions pour notre employé

:::astuce

Dès le début, remarquez que nous sommes incroyablement explicites avec ces instructions ! Nous utilisons le "API Name" (au lieu de simplement le "libellé", qui peut être ambigu) de chaque champ que nous voulons remplir dans Salesforce et nous utilisons le "chemin" spécifique aux données que nous voulons que cette personne entre depuis CommCare.

Pourquoi sommes-nous si spécifiques ? Parce que, finalement, un ordinateur devra interpréter cela — et sont d'une ambiguïté incroyable !

:::

  1. Chaque fois qu'un message est reçu avec {"form":{"@name":"ART Adherence Self-Reporting Tool"}} dans le corps (c'est notre trigger)
  2. Connectez-vous à Salesforce et créez un nouveau participant avec le participant_id que vous trouvez dans la sectionform. articipant_information comme leur Participant_Code__c. (Si quelqu'un existe déjà dans Salesforce avec ce code, puis mettre à jour l'enregistrement existant.)
  3. Remplissez les champs suivants dans Salesforce en fonction des données de CommCare dans ce message :
    • Nom__c avec les données de form.participant_information.name
    • Sex__c avec les données de form.participant_information.gender
    • CommCare_Case_ID__c avec les données de form.case.@case_id
  4. Après avoir créé (ou mis à jour) ce participant dans Salesforce, créer un enregistrement de la visite avec l' instanceID à partir de la section métadonnées en tant que identifiant unique Visit_Code__c. (Une fois encore, s'il y a déjà une visite avec cet ID, veuillez mettre à jour l'enregistrement existant.)
  5. Remplissez les champs suivants pour la visite avec les données de CommCare"
    • Date__c avec form.visit_information.visit_date.
    • Consented__c avec form.visit_information.consent_given.
    • Toujours définir Test_Status__c à vrai, indépendamment de ce qui se trouve dans le message de CommCare.
    • Et connectez cet enregistrement avec la Community_Health_Worker par son nom d'utilisateur dans form.metadata.username.
  6. Enfin, ajoutez un dossier pour chaque médicament listé dans le formulaire form.participant_information.current_medications — correspondant à un ID unique formé par une combinaison du nom du médicament et du participant_id afin que nous puissions mettre à jour les dossiers de médicaments existants s'ils sont présents.
  7. Remplissez les champs suivants pour le médicament :
    • Generic_Name__c avec nom
    • Status__c avec actif
    • Et associez cet enregistrement avec le participant que vous avez créé ou mis à jour à l'étape 2 via le champ participant_id.

Ouf... c'est ça la tâche. C'est juste un exemple fictif et les choses pourraient être plus simples, ou beaucoup plus compliquées que cela, mais il est important de se rappeler que si vous pouvez atteindre ce niveau de précision et granularité dans votre processus de saisie de données, un outil comme OpenFn peut automatiser cela pour vous dans un éclat.

Traduire ceci dans un projet OpenFn

Si vous diffusez des données depuis CommCare et que vous avez votre système Salesforce tous mis en place pour que cette personne de saisie de données puisse compléter les étapes ci-dessus (tous les objets et champs sont-ils créés ? les bons champs sont-ils marqués comme "uniques" et définis à être utiliser comme "external id" dans la section administration de Salesforce ? avez-vous activé le transfert de données dans CommCare ?) alors il est temps de les transformer en un projet OpenFn !

:::astuce

Un plugin rapide : Saviez-vous qu'il y a un forum de la communauté OpenFn où vous pouvez poster des trucs comme les "étapes" ci-dessus et obtenir de l'aide des autres utilisateurs et du personnel d'OpenFn pour convertir convertir ces étapes en un vrai travail OpenFn ?

Eh bien, vous savez ! Allez voir sur community.openfn.org

:::

Créer un identifiant Salesforce

Nous n'avons pas besoin d'un mot de passe CommCare, car il nous enverra des données. Créez un identifiant Salesforce qui permettra au travailleur OpenFn de se connecter à votre système Salesforce.

En savoir plus sur les credentialsici.

Créer un trigger filtre de message

  • Sélectionnez Message Filter pour le type ``
  • Entrez {"form":{"@name":"ART Adherence Self-Reporting Tool"}} pour les critères d'inclusion ``

En savoir plus sur les triggersici.

Créer un job

  • Donnez-en un nom
  • Sélectionnez le trigger que vous venez de créer
  • Sélectionnez l'adaptateur salesforce
  • Sélectionnez le credential que vous venez de créer

Et convertissez les instructions ci-dessus en "opérations" en utilisant l'aide en ligne fournie par l'adaptateur Salesforce :

// Utilisez upsert pour créer ou mettre à jour un participant en fonction de son code de participant.
upsert(
'Participant__c',
'Participant_Code__c',
fields(
field(
'Participant_Code__c',
dataValue('form.participant_information.participant_id')
),
field('Name__c', dataValue('form.participant_information.name')),
field('Sex__c', dataValue('form.participant_information.gender')),
field('CommCare_Case_ID__c', dataValue('form.case[@case_id]'))
)
);

// Ensuite, insérez une visite en utilisant le code de visite.
upsert(
'Visit__c',
'Visit_Code__c',
fields(
field('Visit_Code__c', dataValue('metadata.instanceID')),
field('Date__c', dataValue('form.visit_information.visit_date')),
field('Consented__c', dataValue('form.visit_information.consent_given')),
// Always set status to true
field('Test_Status__c', true),
//Et lié cette visite au participant que nous venons de créer par son "code"
relationship(
'Participant__r',
'Participant_Code__c',
dataValue('form.participant_information.participant_id')
)
)
);

// Et enfin pour CHAQUE médiation répertoriée, créez un dossier de médicament avec un statut
each(
merge(
dataPath('form.participant_information.current_medications[*]'),
fields(
field('pID', dataValue('form.participant_information.participant_id'))
)
),
upsert(
'Medication_Tx__c',
'Medication_Tx_ID__c',
fields(
field(Medication_Tx_ID__c, state => {
// Ici, à l'intérieur du tableau des médicaments, nous avons "scoped" l'état de sorte que
// state.data, pour chaque élément du tableau, ressemble à ceci :
// { pID: 007, name: "sasstra-zenica", active: false }

// Nous concaténerons l'identifiant du participant avec le nom du médicament.
return state.data.pID + state.data.name;
}),
field('Generic_Name__c', dataValue('name')),
field('Status__c', dataValue('status')),
relationship('Participant__r', 'Participant_Code__c', dataValue('pID'))
)
)
);

Maintenant, chaque fois que cette tâche est exécutée (ce qui est à chaque fois qu'un formulaire CommCare est soumis) votre travailleur OpenFn mettra à jour un Participant, upsert une Visiteet exploite une liste complète de Médicaments en Salesforce.

Et ensuite

Eh bien, dans notre petit exemple, vous allumeriez la tâche "allumée" (en la mettant sur les messages entrants de CommCare) et laissez-la fonctionner. Chaque fois qu'il y avait un échec (peut-être votre administrateur Salesforce a ajouté un nouveau champ requis sur l'objet personnaliséMédication) vous recevrez un e-mail et vous devrez revenir à OpenFn pour mettre à jour votre job, y compris ce nouveau champ.

Si vous êtes en train de concevoir vos systèmes CommCare et Salesforce en ce moment, ce va-et-vient sera assez courant. Gardez à l'esprit que vous voulez autant de simplicité que possible dans ces systèmes utilisateurs finaux... eh bien parce que les humains interagissent avec eux tous les jours !

Tant que vos processus sont bien définis, OpenFn peut gérer un peu de complexité (nettoyage de données, transformation, flux logiques complexes, etc.). mais vous ne devriez jamais faire de sacrifices à l'expérience utilisateur dans CommCare et Salesforce—c'est un moyen rapide de perdre l'adoption.

Donc, idéalement, vous avez conçu vos flux de travail dans CommCare et Salesforce pour rendre vos utilisateurs heureux et obtenir les informations dont ils ont besoin pour bien faire leur travail et puis vous revenez sur OpenFn et énoncez nos instructions de saisie de données comme nous l'avons fait ci-dessus.

Une dernière idée

Les deux ressources les plus importantes que vous avez à votre disposition si vous définissez tout cela seul sont :

  1. ce site (docs.openfn.org), et
  2. le forum (community.openfn.org)

Read through the "What is an integration", "OpenFn Concepts", and "Build" sections if you're a thorough, background-first kind of learner. Si vous avez envie d'extraits et d'exemples de code de travail, accédez directement à laJob Library pour voir comment les autres utilisateurs d'OpenFn créent leurs jobs.

Dans tous les cas, tenez la communauté au courant de vos progrès dans le forum. Vous trouverez beaucoup de gens serviables prêts à vous aider dans votre parcours d'intégration.