SlideShare a Scribd company logo
1 of 29
Webinar Tooling api
(07/05/2020)
1
Ceci ne s’applique pas pour tout ce que vous verrez par la suite :
L’intégralité de ce que vous verrez à été fait par un développeur
qui n’est pas un cascadeur,
Donc vous vous pouvez aussi le faire 
Aucune org salesforce n’a été blessée ou tuée durant l’ensemble
des phases de développement et de test
2
Qui suis-je ?
• Senior developpeur (specialiste Java)
• Consultant Salesforce / tech lead
• / formateur (dex450,dex602)
• Compétence : Paresse (expert)
3
Qui êtes-vous (37 réponses) ?
4
0
2
4
6
8
10
12
14
16
18
20
Administrator Developer Other
Your profile
0
5
10
15
20
25
30
No Yes
Do you know Tooling API ?
0
5
10
15
20
25
30
35
No Yes
Do you use Tooling API ?
Metadata API
(SOAP)
Api en bloc
Tooling API (Printemps 2013)
(SOAP/REST/SOQL)
Api granulaire
5
select CreatedById, CreatedBy.Name, CreatedDate, fullname, Id, LastModifiedById, LastModifiedBy.Name,
LastModifiedDate, ManageableState,
Description, ErrorDisplayField, ErrorMessage, ValidationName, Active
from ValidationRule where EntityDefinition.DeveloperName ='Case' and Id='03d3z000000QlbjAAC'
Information communes
Information supplémentaires
TOOLING API
1 seule API mais plusieurs usages différents possible
• Recherche en SOQL
• Activation du debug mode
• Exécution des tests et analyse couverture de
code
• Analyse de la structure des classes
• Débogage
• Création/Modification unitaire de config
• Exécution de code anonyme
• Création d’outil générique (génération de
package, etc …)
6
Fonction Recherche (1/3)
174 objets exploitables dont 1 objet pivot :
• EntityDefinition : la description de tous les objets salesforce ( si tooling API)
• champs : isSomething (isCustomSetting,isEverCreatable …) , prefix, DeveloperName,DurableId,
qualifiedApiName …
• DeveloperName : nom technique sans __xx
• qualifiedApiName : Nom technique avec __xx (si besoin)
• DurableId : l’id qui sera utilisé majoritairement dans les références au sein de la toolingApi.
Select * from FieldDefinition WHERE EntityDefinitionId ='Account'
7
Fonction Recherche (2/3)
• Ce qu’on peut et ne peut pas faire :
• Chercher un custom Label par rapport au contenu possible de la valeur :
select Category ,MasterLabel ,Name ,value from ExternalString where value like '%Test%'
• Chercher les validation rule qui correspondent à un message d’erreur :
select Id,Active,EntityDefinition.DeveloperName ,ErrorDisplayField,ErrorMessage,ValidationName from
ValidationRule where active=true and ErrorMessage like '%changement de statu%'
• Ce qu’on ne peut pas faire en standard :
certains champs ne peuvent etre requete si la requete ne ramène pas une occurrence unique :
fullName, metadata
select id, metadata,fullName from flow  KO
select metadata,fullName from flow where id = '3012o000000HJzSAAW'  OK
8
9
Methode pour executer une requetes SOQL via la tooling Api :
public static List<Map<String, Object>> getResult(String query){
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v47.0/tooling/query/?q='+EncodingUtil.urlEncode(query,'UTF-8'));
req.setMethod('GET');
HttpResponse res = (new Http()).send(req);
Map<String, Object> fieldMap = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
List<Object> recordsMap = (List<Object>)fieldMap.get('records');
List<Map<String, Object>> result = new List<Map<String, Object>> ();
for(Object anObj : recordsMap){
result.add((Map<String, Object>)anObj);
}
return result;
}
Execution d’une requete en apex :
System.debug(ToolingApiUtil.getResult('select Id,Category,Language,MasterLabel,Name,Value from ExternalString order by lastModifieddate desc limit 1’));
Log :
17:59:00:086 USER_DEBUG [16]|DEBUG|({Category=Alerts, Id=10125000001RKQlAAO, Language=en_US, MasterLabel=Feature Not Available,
Name=Feature_Not_Available, Value=This feature is currently unavailable.,
attributes={type=ExternalString, url=/services/data/v47.0/tooling/sobjects/ExternalString/10125000001RKQlAAO}})
Requete soql toolingApi en apex
Penser à cocher la case si vous faites une requête tooling et à la décocher sinon
Fonction Recherche (3/3)
L’objet : METADATADEPENDENCY (MetadataComponentId, MetadataComponentName,
RefMetadataComponentId, RefMetadataComponentName, RefMetadataComponentType)
Cet objet permet de déterminer les interdépendances entre les metadata Salesforce. On peut ainsi répondre aux
2 questions :
- De quoi ma metadata dépend :
SELECT MetadataComponentName, RefMetadataComponentType ,RefMetadataComponentName FROM MetadataComponentDependency WHERE MetadataComponentId = '01p25000001zNi5AAE'
- Ou est utilisé ma metadata :
SELECT MetadataComponentName, MetadataComponentType,RefMetadataComponentName FROM MetadataComponentDependency WHERE RefMetadataComponentId = ‘01ID0000000ugBdMAI'
Exemple d’utilisation :
- Ou est utilisé mon champs (apparu avec la spring 2020)
- Pouvoir déterminer les metadata nécessaires pour aliment une scratch org afin de faire des tests
Les requetes sont limités à 2000 records (summer 2020 ,1 000 000 de records en bulk api)
10
Savoir quels composants utilise mon objet (ici un objet)
12
Savoir quels composants utilise mon objet (ici une apexClass)
Fonction creation/update
• Création ou update de metadata
• Exemples d’utilisation :
• Modifier et forcer le recalcul d’un Rollup summary field
• Creation d’une application pour tester des formules
• Création de traceFlag automatisé
• Suppression en masse sans passer par un destructive package
• Etc ….
13
Methode pour Créer , Modifier, Supprimer un objet via la tooling Api :
public static void createObject(String type,Map<String,Object> param){
crud(type,param,null,'POST');
}
public static void updateObject(String type,Map<String,Object> param,String idObject){
crud(type,param,idObject,'PATCH');
}
public static void deleteObject(String type,String idObject){
crud(type,null,idObject,'DELETE');
}
public static void crud(String type,Map<String,Object> param,String idObject,String operation){
String endOperation='/';
if(idObject!=null){
endOperation+=idObject;
if(operation=='PATCH'){endOperation+=+'?_HttpMethod=PATCH';operation='POST';}
}
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v47.0/tooling/sobjects/'+type+endOperation);
req.setBody(JSON.serialize(param));
req.setMethod(operation);
system.debug((new Http()).send(req));
}
CRUD via la toolingApi en apex (1/2)
15
Creation d’un CustomLabel :
Map<String,Object> externalString = new Map<String,Object>();
externalString.put('Category','test');
externalString.put('MasterLabel','Master Label TA');
externalString.put('Name','NameToolingApi');
externalString.put('Value','value Tooling Api');
ToolingApiUtil.createObject('ExternalString',externalString,null);
Modification :
Map<String,Object> externalStringUpdate = new Map<String,Object>();
externalStringUpdate.put('Category’,new Category');
String idCustomLabel = (String)ToolingApiUtil.getResult('select Id,Category,Language,MasterLabel,Name,Value from ExternalString where Name='NameToolingApi'')[0].get('Id');
ToolingApiUtil.updateObject('ExternalString',externalStringUpdate,idCustomLabel);
Suppression :
String idCustomLabel = (String)ToolingApiUtil.getResult('select Id,Category,Language,MasterLabel,Name,Value from ExternalString where Name='NameToolingApi'')[0].get('Id');
ToolingApiUtil.deleteObject('ExternalString',idCustomLabel);
CRUD via la toolingApi en apex (2/2)
Fonction debug log
• L’objet DebugLevel :
• Choix du level pour (ApexCode,ApexProfiling,Callout, etc …)
• L’objet TraceFlag :
• Choix du debugLevel (DebugLevelId)
• Choix de l’entité à tracer (User, Classe,Apex Trigger,Automated Process)
• Date d’expiration de la trace (max 24h00)
Exemple d’utilisation :
- Modifier une trace pour pouvoir logger plus de 24h00 une action spécifique via un batch
- Pouvoir automatiquement tracer un utilisateur lorsqu’on utilise la fonction loginAs
- Pouvoir réécrire complétement l’interface des log à votre convenance
16
Monitorer les entités que l’on souhaite tracer
Fonction TestResult / Code coverage
• L’objet ApexCodeCoverage :
• ApexClassOrTriggerId
• TestMethodName
• NumLinesCovered
• NumLinesUncovered
• Coverage (detail de la couverture ligne par ligne)
Exemple d’utilisation :
- Rechercher avec précisions comment une classe est couverte en vue d’en faciliter le déploiement en l’absence
d’une classe de test correspondante
- Créer une interface de visualisation de la couverture plus flexible que la console
18
Couverture de classe dans un tableau triable
20
Couverture d’une classe par efficacité
Fonction execute anonymous/
execution des classes de test
• Pouvoir executer du code Apex à partir d’un simple appel
à un webservice
• Pour voir planifier l’execution de vos classes de test
Exemple d’utilisation :
- Création d’un écran d’execution qui n’affiche que les debug
- Création d’un écran pour afficher le resultat json retournée par une méthode
- Etc …
21
Utilisation executeAnonymous
Utilisation executeAnonymous pour les lwc (1/2)
Utilisation executeAnonymous pour les lwc (2/2)
Fonction debug
• ApexExecutionOverlayAction :
• ActionScriptType(None,SOQL,Apex) , isDumpingHead,Iteration,Line
• ApexExecutionOverlayResult :
• ApexResult, ClassName, HeapDump, OverlayResultLength,SoqlResult
• Utilisation :
• Permet d’executer du soql, un dump ou même du code apex à chaud
• WARNING : Executer du code apex  stop la transaction au moment de
l’execution. Le resultat n’est affiché que dans la log pas dans l’objet result
25
Utilisation du debugger avec un requête
Contenu du champs SoqlResult
après utilisation du debugger
[HeapDump className=‘UneClassApex' extents='{[2][TypeExtent collectionType='null' count='1' definition='{[0]}' extent='{[1][HeapAddress
address='0x44adb263' isStatic='true' size='20' symbols='{[1] UneClassApex.webServiceCfg,}' value='[MapValue [StateValue ] entry='{[4][MapEntry
keyDisplayValue='endPoint__c' value='[StringValue [StateValue ] value='https://testUrl/app/api/V1/']'],[MapEntry keyDisplayValue='token__c'
value='[StringValue [StateValue ] value='2hj5c64c1EPYChuGVyyLCngf3WX4WdWm']'],[MapEntry keyDisplayValue='timeout__c' value='[StringValue
[StateValue ] value='20000']'],[MapEntry keyDisplayValue='Id' value='[StringValue [StateValue ] value='m051l000000Cna2AAC']'],}']'],}' totalSize='20'
typeName='WebServiceConfig__mdt'],[TypeExtent collectionType='null' count='10' definition='{[1][AttributeDefinition name='stringValue'
type='char[]'],}' extent='{[10][HeapAddress address='0x601f9abb' isStatic='false' size='11' symbols='{[0]}' value='[StringValue [StateValue ]
value='endPoint__c']'],[HeapAddress address='0x3c808888' isStatic='false' size='47' symbols='{[0]}' value='[StringValue [StateValue ]
value='https://testUrl/app/api/V1/']'],[HeapAddress address='0x4ac7be54' isStatic='false' size='8' symbols='{[0]}' value='[StringValue [StateValue ]
value='token__c']'],[HeapAddress address='0x174632c1' isStatic='false' size='32' symbols='{[0]}' value='[StringValue [StateValue ]
value='2hj5c64c1EPYChuGVyyLCngf3WX4WdWm']'],[HeapAddress address='0xb90a8d0' isStatic='false' size='10' symbols='{[0]}' value='[StringValue
[StateValue ] value='timeout__c']'],[HeapAddress address='0x6171129b' isStatic='false' size='2' symbols='{[0]}' value='[StringValue [StateValue ]
value='Id']'],[HeapAddress address='0x44ae98d5' isStatic='false' size='18' symbols='{[0]}' value='[StringValue [StateValue ]
value='m051l000000Cna2AAC']'],[HeapAddress address='0x50d9d984' isStatic='false' size='7' symbols='{[0]}' value='[StringValue [StateValue ]
value='2327872']'],[HeapAddress address='0x3ce399a9' isStatic='false' size='34' symbols='{[1]data,}' value='[StringValue [StateValue ]
value=objet/2327872/test']'],[HeapAddress address='0x208a5888' isStatic='false' size='3' symbols='{[1]operation,}' value='[StringValue [StateValue ]
value='GET']'],}' totalSize='172' typeName='String'],}'
heapDumpDate='java.util.GregorianCalendar[time=1578559862723,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneI
nfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2020,
MONTH=0,WEEK_OF_YEAR=2,WEEK_OF_MONTH=2,DAY_OF_MONTH=9,DAY_OF_YEAR=9,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0
,HOUR=8,HOUR_OF_DAY=8,MINUTE=51,SECOND=2,MILLISECOND=723,ZONE_OFFSET=0,DST_OFFSET=0]' namespace='none']
Exemple d’un headDump obtenu via le debugger salesforce
Coktail party
• Génération autonome de package
• Tooling Api
• Partner Api
• External code
• Un peu de folie
Création automatique
du package avec pour critère :
- date première modification
- date dernière modification
- Filtre par utilisateur ou non
28
Quelques liens utiles
L’ensemble des objets manipulables via la tooling Api :
https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/reference_objects_list.htm
Un site qui explique les différents types utilisable pour la metadatadependency:
https://github.com/afawcett/dependencies-sample)
Slack : https://join.slack.com/t/communityfrance/shared_invite/zt-e10uch11-W4rfrk4KrgSZR4tG0vd4PQ
Si vous avez des questions , vous pouvez m’écrire à :
fabrice.challier@littlechaman.com

More Related Content

Similar to Salesforce Tooling API

La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !Paris Salesforce Developer Group
 
ALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - SpecflowALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - SpecflowMathias Kluba
 
Formation tests decembre2010
Formation tests decembre2010Formation tests decembre2010
Formation tests decembre2010Fou Cha
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
Formation Efficy CRM - Technical training
Formation Efficy CRM - Technical trainingFormation Efficy CRM - Technical training
Formation Efficy CRM - Technical trainingEfficy CRM
 
Ma stack d'outils agiles, tout un programme !
Ma stack d'outils agiles, tout un programme !Ma stack d'outils agiles, tout un programme !
Ma stack d'outils agiles, tout un programme !Cédric Leblond
 
Cocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitairesCocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitairesCocoaHeads France
 
Asp Au Service Des Mv Ps
Asp Au Service Des Mv PsAsp Au Service Des Mv Ps
Asp Au Service Des Mv PsGregory Renard
 
Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...
Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...
Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...iProspect France
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScriptKristen Le Liboux
 
Azure Camp 9 Décembre - slides session développeurs webmedia
Azure Camp 9 Décembre - slides session développeurs webmediaAzure Camp 9 Décembre - slides session développeurs webmedia
Azure Camp 9 Décembre - slides session développeurs webmediaMicrosoft
 
Comment écrire du code testable ?
Comment écrire du code testable ?Comment écrire du code testable ?
Comment écrire du code testable ?Fou Cha
 
Utilisation de ZK avec Java - Retour d’expérience
Utilisation de ZK avec Java - Retour d’expérienceUtilisation de ZK avec Java - Retour d’expérience
Utilisation de ZK avec Java - Retour d’expériencelouschwartz
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Jean-Michel Doudoux
 
Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...
Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...
Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...CERTyou Formation
 
Deuxième partie.pptx
Deuxième partie.pptxDeuxième partie.pptx
Deuxième partie.pptxSafaeLhr1
 
Presentation Spring, Spring MVC
Presentation Spring, Spring MVCPresentation Spring, Spring MVC
Presentation Spring, Spring MVCNathaniel Richand
 
Design Pattern introduction
Design Pattern introductionDesign Pattern introduction
Design Pattern introductionneuros
 

Similar to Salesforce Tooling API (20)

La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
La Tooling API, est-ce pour moi ? Bien sûr, viens voir pourquoi !
 
ALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - SpecflowALT.Net Juin 2012 - Specflow
ALT.Net Juin 2012 - Specflow
 
Formation tests decembre2010
Formation tests decembre2010Formation tests decembre2010
Formation tests decembre2010
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
Formation Efficy CRM - Technical training
Formation Efficy CRM - Technical trainingFormation Efficy CRM - Technical training
Formation Efficy CRM - Technical training
 
Ma stack d'outils agiles, tout un programme !
Ma stack d'outils agiles, tout un programme !Ma stack d'outils agiles, tout un programme !
Ma stack d'outils agiles, tout un programme !
 
Cocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitairesCocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitaires
 
Asp Au Service Des Mv Ps
Asp Au Service Des Mv PsAsp Au Service Des Mv Ps
Asp Au Service Des Mv Ps
 
Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...
Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...
Google Spreadsheet, astuces et fonctions cachées pour ne plus vous en passer ...
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
 
Azure Camp 9 Décembre - slides session développeurs webmedia
Azure Camp 9 Décembre - slides session développeurs webmediaAzure Camp 9 Décembre - slides session développeurs webmedia
Azure Camp 9 Décembre - slides session développeurs webmedia
 
Cerberus Testing
Cerberus TestingCerberus Testing
Cerberus Testing
 
Comment écrire du code testable ?
Comment écrire du code testable ?Comment écrire du code testable ?
Comment écrire du code testable ?
 
Utilisation de ZK avec Java - Retour d’expérience
Utilisation de ZK avec Java - Retour d’expérienceUtilisation de ZK avec Java - Retour d’expérience
Utilisation de ZK avec Java - Retour d’expérience
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016
 
Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...
Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...
Dt215 g formation-utilisation-d-optim-test-data-management-et-masquage-des-do...
 
Deuxième partie.pptx
Deuxième partie.pptxDeuxième partie.pptx
Deuxième partie.pptx
 
Presentation Spring, Spring MVC
Presentation Spring, Spring MVCPresentation Spring, Spring MVC
Presentation Spring, Spring MVC
 
Design Pattern introduction
Design Pattern introductionDesign Pattern introduction
Design Pattern introduction
 
Introduction à Symfony
Introduction à SymfonyIntroduction à Symfony
Introduction à Symfony
 

More from Thierry TROUIN ☁

AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsThierry TROUIN ☁
 
Comment Challenger les ApexDebugLog et comment améliorer leur analyse
Comment Challenger les ApexDebugLog et comment améliorer leur analyseComment Challenger les ApexDebugLog et comment améliorer leur analyse
Comment Challenger les ApexDebugLog et comment améliorer leur analyseThierry TROUIN ☁
 
Comment exploiter facilement une API avec les Flows
Comment exploiter facilement une API avec les FlowsComment exploiter facilement une API avec les Flows
Comment exploiter facilement une API avec les FlowsThierry TROUIN ☁
 
TunisUserGroup - Ecosysteme salesforce.pptx
TunisUserGroup -  Ecosysteme salesforce.pptxTunisUserGroup -  Ecosysteme salesforce.pptx
TunisUserGroup - Ecosysteme salesforce.pptxThierry TROUIN ☁
 
Controle de configuration ou fuite de donnees, comment mieux securiser SFDC
Controle de configuration ou fuite de donnees, comment mieux securiser SFDCControle de configuration ou fuite de donnees, comment mieux securiser SFDC
Controle de configuration ou fuite de donnees, comment mieux securiser SFDCThierry TROUIN ☁
 
Monia, l’IAssistante qui aide vos equipes a closer leurs Opportunites
Monia, l’IAssistante qui aide vos equipes a closer leurs OpportunitesMonia, l’IAssistante qui aide vos equipes a closer leurs Opportunites
Monia, l’IAssistante qui aide vos equipes a closer leurs OpportunitesThierry TROUIN ☁
 
Sales enablement, e-signature, closing & automations dans Salesforce
Sales enablement, e-signature, closing & automations dans SalesforceSales enablement, e-signature, closing & automations dans Salesforce
Sales enablement, e-signature, closing & automations dans SalesforceThierry TROUIN ☁
 
Les formulaires web dans salesforce
Les formulaires web dans salesforceLes formulaires web dans salesforce
Les formulaires web dans salesforceThierry TROUIN ☁
 
Découvrez les enquêtes de satisfaction dans Salesforce
Découvrez les enquêtes de satisfaction dans SalesforceDécouvrez les enquêtes de satisfaction dans Salesforce
Découvrez les enquêtes de satisfaction dans SalesforceThierry TROUIN ☁
 
Winter-23-French-Gathering+Dreamforce
Winter-23-French-Gathering+DreamforceWinter-23-French-Gathering+Dreamforce
Winter-23-French-Gathering+DreamforceThierry TROUIN ☁
 
Meetup Cameroun - Presentation SFDC
Meetup Cameroun - Presentation SFDCMeetup Cameroun - Presentation SFDC
Meetup Cameroun - Presentation SFDCThierry TROUIN ☁
 
Construire sa strategie de gestion des donnees Salesforce avec Odaseva
Construire sa strategie de gestion des donnees Salesforce avec OdasevaConstruire sa strategie de gestion des donnees Salesforce avec Odaseva
Construire sa strategie de gestion des donnees Salesforce avec OdasevaThierry TROUIN ☁
 
Data Quality : Presentation de ISV Ellisphere
Data Quality : Presentation de ISV EllisphereData Quality : Presentation de ISV Ellisphere
Data Quality : Presentation de ISV EllisphereThierry TROUIN ☁
 
Simplifiez vos journées avec sfdx-hardis et l’écosystème open-source
Simplifiez vos journées avec sfdx-hardis et l’écosystème open-sourceSimplifiez vos journées avec sfdx-hardis et l’écosystème open-source
Simplifiez vos journées avec sfdx-hardis et l’écosystème open-sourceThierry TROUIN ☁
 
Ameliorez vos parcours omnicanaux avec Marketing Cloud
Ameliorez vos parcours omnicanaux avec Marketing CloudAmeliorez vos parcours omnicanaux avec Marketing Cloud
Ameliorez vos parcours omnicanaux avec Marketing CloudThierry TROUIN ☁
 
Bien Démarrer avec Pardot: Comment délivrer un engagement client connecté
Bien Démarrer avec Pardot: Comment délivrer un engagement client connectéBien Démarrer avec Pardot: Comment délivrer un engagement client connecté
Bien Démarrer avec Pardot: Comment délivrer un engagement client connectéThierry TROUIN ☁
 
Ameliorez votre Marketing : Introduction aux solutions Marketing Cloud et Pardot
Ameliorez votre Marketing : Introduction aux solutions Marketing Cloud et PardotAmeliorez votre Marketing : Introduction aux solutions Marketing Cloud et Pardot
Ameliorez votre Marketing : Introduction aux solutions Marketing Cloud et PardotThierry TROUIN ☁
 
Debarrassez-vous de la dette technique dans votre organisation avec OrgCheck
Debarrassez-vous de la dette technique dans votre organisation avec OrgCheckDebarrassez-vous de la dette technique dans votre organisation avec OrgCheck
Debarrassez-vous de la dette technique dans votre organisation avec OrgCheckThierry TROUIN ☁
 

More from Thierry TROUIN ☁ (20)

AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with Flows
 
Comment Challenger les ApexDebugLog et comment améliorer leur analyse
Comment Challenger les ApexDebugLog et comment améliorer leur analyseComment Challenger les ApexDebugLog et comment améliorer leur analyse
Comment Challenger les ApexDebugLog et comment améliorer leur analyse
 
Comment exploiter facilement une API avec les Flows
Comment exploiter facilement une API avec les FlowsComment exploiter facilement une API avec les Flows
Comment exploiter facilement une API avec les Flows
 
TunisUserGroup - Ecosysteme salesforce.pptx
TunisUserGroup -  Ecosysteme salesforce.pptxTunisUserGroup -  Ecosysteme salesforce.pptx
TunisUserGroup - Ecosysteme salesforce.pptx
 
Controle de configuration ou fuite de donnees, comment mieux securiser SFDC
Controle de configuration ou fuite de donnees, comment mieux securiser SFDCControle de configuration ou fuite de donnees, comment mieux securiser SFDC
Controle de configuration ou fuite de donnees, comment mieux securiser SFDC
 
Monia, l’IAssistante qui aide vos equipes a closer leurs Opportunites
Monia, l’IAssistante qui aide vos equipes a closer leurs OpportunitesMonia, l’IAssistante qui aide vos equipes a closer leurs Opportunites
Monia, l’IAssistante qui aide vos equipes a closer leurs Opportunites
 
Sales enablement, e-signature, closing & automations dans Salesforce
Sales enablement, e-signature, closing & automations dans SalesforceSales enablement, e-signature, closing & automations dans Salesforce
Sales enablement, e-signature, closing & automations dans Salesforce
 
Les formulaires web dans salesforce
Les formulaires web dans salesforceLes formulaires web dans salesforce
Les formulaires web dans salesforce
 
Découvrez les enquêtes de satisfaction dans Salesforce
Découvrez les enquêtes de satisfaction dans SalesforceDécouvrez les enquêtes de satisfaction dans Salesforce
Découvrez les enquêtes de satisfaction dans Salesforce
 
Winter-23-French-Gathering+Dreamforce
Winter-23-French-Gathering+DreamforceWinter-23-French-Gathering+Dreamforce
Winter-23-French-Gathering+Dreamforce
 
Meetup Cameroun - Presentation SFDC
Meetup Cameroun - Presentation SFDCMeetup Cameroun - Presentation SFDC
Meetup Cameroun - Presentation SFDC
 
Construire sa strategie de gestion des donnees Salesforce avec Odaseva
Construire sa strategie de gestion des donnees Salesforce avec OdasevaConstruire sa strategie de gestion des donnees Salesforce avec Odaseva
Construire sa strategie de gestion des donnees Salesforce avec Odaseva
 
Summer-22-FG-Mai-2022
Summer-22-FG-Mai-2022Summer-22-FG-Mai-2022
Summer-22-FG-Mai-2022
 
Data Quality : Presentation de ISV Ellisphere
Data Quality : Presentation de ISV EllisphereData Quality : Presentation de ISV Ellisphere
Data Quality : Presentation de ISV Ellisphere
 
Simplifiez vos journées avec sfdx-hardis et l’écosystème open-source
Simplifiez vos journées avec sfdx-hardis et l’écosystème open-sourceSimplifiez vos journées avec sfdx-hardis et l’écosystème open-source
Simplifiez vos journées avec sfdx-hardis et l’écosystème open-source
 
Ameliorez vos parcours omnicanaux avec Marketing Cloud
Ameliorez vos parcours omnicanaux avec Marketing CloudAmeliorez vos parcours omnicanaux avec Marketing Cloud
Ameliorez vos parcours omnicanaux avec Marketing Cloud
 
Bien Démarrer avec Pardot: Comment délivrer un engagement client connecté
Bien Démarrer avec Pardot: Comment délivrer un engagement client connectéBien Démarrer avec Pardot: Comment délivrer un engagement client connecté
Bien Démarrer avec Pardot: Comment délivrer un engagement client connecté
 
Ameliorez votre Marketing : Introduction aux solutions Marketing Cloud et Pardot
Ameliorez votre Marketing : Introduction aux solutions Marketing Cloud et PardotAmeliorez votre Marketing : Introduction aux solutions Marketing Cloud et Pardot
Ameliorez votre Marketing : Introduction aux solutions Marketing Cloud et Pardot
 
Debarrassez-vous de la dette technique dans votre organisation avec OrgCheck
Debarrassez-vous de la dette technique dans votre organisation avec OrgCheckDebarrassez-vous de la dette technique dans votre organisation avec OrgCheck
Debarrassez-vous de la dette technique dans votre organisation avec OrgCheck
 
Release Winter 22 FR
Release Winter 22 FRRelease Winter 22 FR
Release Winter 22 FR
 

Salesforce Tooling API

  • 2. Ceci ne s’applique pas pour tout ce que vous verrez par la suite : L’intégralité de ce que vous verrez à été fait par un développeur qui n’est pas un cascadeur, Donc vous vous pouvez aussi le faire  Aucune org salesforce n’a été blessée ou tuée durant l’ensemble des phases de développement et de test 2
  • 3. Qui suis-je ? • Senior developpeur (specialiste Java) • Consultant Salesforce / tech lead • / formateur (dex450,dex602) • Compétence : Paresse (expert) 3
  • 4. Qui êtes-vous (37 réponses) ? 4 0 2 4 6 8 10 12 14 16 18 20 Administrator Developer Other Your profile 0 5 10 15 20 25 30 No Yes Do you know Tooling API ? 0 5 10 15 20 25 30 35 No Yes Do you use Tooling API ?
  • 5. Metadata API (SOAP) Api en bloc Tooling API (Printemps 2013) (SOAP/REST/SOQL) Api granulaire 5 select CreatedById, CreatedBy.Name, CreatedDate, fullname, Id, LastModifiedById, LastModifiedBy.Name, LastModifiedDate, ManageableState, Description, ErrorDisplayField, ErrorMessage, ValidationName, Active from ValidationRule where EntityDefinition.DeveloperName ='Case' and Id='03d3z000000QlbjAAC' Information communes Information supplémentaires
  • 6. TOOLING API 1 seule API mais plusieurs usages différents possible • Recherche en SOQL • Activation du debug mode • Exécution des tests et analyse couverture de code • Analyse de la structure des classes • Débogage • Création/Modification unitaire de config • Exécution de code anonyme • Création d’outil générique (génération de package, etc …) 6
  • 7. Fonction Recherche (1/3) 174 objets exploitables dont 1 objet pivot : • EntityDefinition : la description de tous les objets salesforce ( si tooling API) • champs : isSomething (isCustomSetting,isEverCreatable …) , prefix, DeveloperName,DurableId, qualifiedApiName … • DeveloperName : nom technique sans __xx • qualifiedApiName : Nom technique avec __xx (si besoin) • DurableId : l’id qui sera utilisé majoritairement dans les références au sein de la toolingApi. Select * from FieldDefinition WHERE EntityDefinitionId ='Account' 7
  • 8. Fonction Recherche (2/3) • Ce qu’on peut et ne peut pas faire : • Chercher un custom Label par rapport au contenu possible de la valeur : select Category ,MasterLabel ,Name ,value from ExternalString where value like '%Test%' • Chercher les validation rule qui correspondent à un message d’erreur : select Id,Active,EntityDefinition.DeveloperName ,ErrorDisplayField,ErrorMessage,ValidationName from ValidationRule where active=true and ErrorMessage like '%changement de statu%' • Ce qu’on ne peut pas faire en standard : certains champs ne peuvent etre requete si la requete ne ramène pas une occurrence unique : fullName, metadata select id, metadata,fullName from flow  KO select metadata,fullName from flow where id = '3012o000000HJzSAAW'  OK 8
  • 9. 9 Methode pour executer une requetes SOQL via la tooling Api : public static List<Map<String, Object>> getResult(String query){ HttpRequest req = new HttpRequest(); req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID()); req.setHeader('Content-Type', 'application/json'); req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v47.0/tooling/query/?q='+EncodingUtil.urlEncode(query,'UTF-8')); req.setMethod('GET'); HttpResponse res = (new Http()).send(req); Map<String, Object> fieldMap = (Map<String, Object>)JSON.deserializeUntyped(res.getBody()); List<Object> recordsMap = (List<Object>)fieldMap.get('records'); List<Map<String, Object>> result = new List<Map<String, Object>> (); for(Object anObj : recordsMap){ result.add((Map<String, Object>)anObj); } return result; } Execution d’une requete en apex : System.debug(ToolingApiUtil.getResult('select Id,Category,Language,MasterLabel,Name,Value from ExternalString order by lastModifieddate desc limit 1’)); Log : 17:59:00:086 USER_DEBUG [16]|DEBUG|({Category=Alerts, Id=10125000001RKQlAAO, Language=en_US, MasterLabel=Feature Not Available, Name=Feature_Not_Available, Value=This feature is currently unavailable., attributes={type=ExternalString, url=/services/data/v47.0/tooling/sobjects/ExternalString/10125000001RKQlAAO}}) Requete soql toolingApi en apex Penser à cocher la case si vous faites une requête tooling et à la décocher sinon
  • 10. Fonction Recherche (3/3) L’objet : METADATADEPENDENCY (MetadataComponentId, MetadataComponentName, RefMetadataComponentId, RefMetadataComponentName, RefMetadataComponentType) Cet objet permet de déterminer les interdépendances entre les metadata Salesforce. On peut ainsi répondre aux 2 questions : - De quoi ma metadata dépend : SELECT MetadataComponentName, RefMetadataComponentType ,RefMetadataComponentName FROM MetadataComponentDependency WHERE MetadataComponentId = '01p25000001zNi5AAE' - Ou est utilisé ma metadata : SELECT MetadataComponentName, MetadataComponentType,RefMetadataComponentName FROM MetadataComponentDependency WHERE RefMetadataComponentId = ‘01ID0000000ugBdMAI' Exemple d’utilisation : - Ou est utilisé mon champs (apparu avec la spring 2020) - Pouvoir déterminer les metadata nécessaires pour aliment une scratch org afin de faire des tests Les requetes sont limités à 2000 records (summer 2020 ,1 000 000 de records en bulk api) 10
  • 11. Savoir quels composants utilise mon objet (ici un objet)
  • 12. 12 Savoir quels composants utilise mon objet (ici une apexClass)
  • 13. Fonction creation/update • Création ou update de metadata • Exemples d’utilisation : • Modifier et forcer le recalcul d’un Rollup summary field • Creation d’une application pour tester des formules • Création de traceFlag automatisé • Suppression en masse sans passer par un destructive package • Etc …. 13
  • 14. Methode pour Créer , Modifier, Supprimer un objet via la tooling Api : public static void createObject(String type,Map<String,Object> param){ crud(type,param,null,'POST'); } public static void updateObject(String type,Map<String,Object> param,String idObject){ crud(type,param,idObject,'PATCH'); } public static void deleteObject(String type,String idObject){ crud(type,null,idObject,'DELETE'); } public static void crud(String type,Map<String,Object> param,String idObject,String operation){ String endOperation='/'; if(idObject!=null){ endOperation+=idObject; if(operation=='PATCH'){endOperation+=+'?_HttpMethod=PATCH';operation='POST';} } HttpRequest req = new HttpRequest(); req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID()); req.setHeader('Content-Type', 'application/json'); req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v47.0/tooling/sobjects/'+type+endOperation); req.setBody(JSON.serialize(param)); req.setMethod(operation); system.debug((new Http()).send(req)); } CRUD via la toolingApi en apex (1/2)
  • 15. 15 Creation d’un CustomLabel : Map<String,Object> externalString = new Map<String,Object>(); externalString.put('Category','test'); externalString.put('MasterLabel','Master Label TA'); externalString.put('Name','NameToolingApi'); externalString.put('Value','value Tooling Api'); ToolingApiUtil.createObject('ExternalString',externalString,null); Modification : Map<String,Object> externalStringUpdate = new Map<String,Object>(); externalStringUpdate.put('Category’,new Category'); String idCustomLabel = (String)ToolingApiUtil.getResult('select Id,Category,Language,MasterLabel,Name,Value from ExternalString where Name='NameToolingApi'')[0].get('Id'); ToolingApiUtil.updateObject('ExternalString',externalStringUpdate,idCustomLabel); Suppression : String idCustomLabel = (String)ToolingApiUtil.getResult('select Id,Category,Language,MasterLabel,Name,Value from ExternalString where Name='NameToolingApi'')[0].get('Id'); ToolingApiUtil.deleteObject('ExternalString',idCustomLabel); CRUD via la toolingApi en apex (2/2)
  • 16. Fonction debug log • L’objet DebugLevel : • Choix du level pour (ApexCode,ApexProfiling,Callout, etc …) • L’objet TraceFlag : • Choix du debugLevel (DebugLevelId) • Choix de l’entité à tracer (User, Classe,Apex Trigger,Automated Process) • Date d’expiration de la trace (max 24h00) Exemple d’utilisation : - Modifier une trace pour pouvoir logger plus de 24h00 une action spécifique via un batch - Pouvoir automatiquement tracer un utilisateur lorsqu’on utilise la fonction loginAs - Pouvoir réécrire complétement l’interface des log à votre convenance 16
  • 17. Monitorer les entités que l’on souhaite tracer
  • 18. Fonction TestResult / Code coverage • L’objet ApexCodeCoverage : • ApexClassOrTriggerId • TestMethodName • NumLinesCovered • NumLinesUncovered • Coverage (detail de la couverture ligne par ligne) Exemple d’utilisation : - Rechercher avec précisions comment une classe est couverte en vue d’en faciliter le déploiement en l’absence d’une classe de test correspondante - Créer une interface de visualisation de la couverture plus flexible que la console 18
  • 19. Couverture de classe dans un tableau triable
  • 20. 20 Couverture d’une classe par efficacité
  • 21. Fonction execute anonymous/ execution des classes de test • Pouvoir executer du code Apex à partir d’un simple appel à un webservice • Pour voir planifier l’execution de vos classes de test Exemple d’utilisation : - Création d’un écran d’execution qui n’affiche que les debug - Création d’un écran pour afficher le resultat json retournée par une méthode - Etc … 21
  • 25. Fonction debug • ApexExecutionOverlayAction : • ActionScriptType(None,SOQL,Apex) , isDumpingHead,Iteration,Line • ApexExecutionOverlayResult : • ApexResult, ClassName, HeapDump, OverlayResultLength,SoqlResult • Utilisation : • Permet d’executer du soql, un dump ou même du code apex à chaud • WARNING : Executer du code apex  stop la transaction au moment de l’execution. Le resultat n’est affiché que dans la log pas dans l’objet result 25
  • 26. Utilisation du debugger avec un requête Contenu du champs SoqlResult après utilisation du debugger
  • 27. [HeapDump className=‘UneClassApex' extents='{[2][TypeExtent collectionType='null' count='1' definition='{[0]}' extent='{[1][HeapAddress address='0x44adb263' isStatic='true' size='20' symbols='{[1] UneClassApex.webServiceCfg,}' value='[MapValue [StateValue ] entry='{[4][MapEntry keyDisplayValue='endPoint__c' value='[StringValue [StateValue ] value='https://testUrl/app/api/V1/']'],[MapEntry keyDisplayValue='token__c' value='[StringValue [StateValue ] value='2hj5c64c1EPYChuGVyyLCngf3WX4WdWm']'],[MapEntry keyDisplayValue='timeout__c' value='[StringValue [StateValue ] value='20000']'],[MapEntry keyDisplayValue='Id' value='[StringValue [StateValue ] value='m051l000000Cna2AAC']'],}']'],}' totalSize='20' typeName='WebServiceConfig__mdt'],[TypeExtent collectionType='null' count='10' definition='{[1][AttributeDefinition name='stringValue' type='char[]'],}' extent='{[10][HeapAddress address='0x601f9abb' isStatic='false' size='11' symbols='{[0]}' value='[StringValue [StateValue ] value='endPoint__c']'],[HeapAddress address='0x3c808888' isStatic='false' size='47' symbols='{[0]}' value='[StringValue [StateValue ] value='https://testUrl/app/api/V1/']'],[HeapAddress address='0x4ac7be54' isStatic='false' size='8' symbols='{[0]}' value='[StringValue [StateValue ] value='token__c']'],[HeapAddress address='0x174632c1' isStatic='false' size='32' symbols='{[0]}' value='[StringValue [StateValue ] value='2hj5c64c1EPYChuGVyyLCngf3WX4WdWm']'],[HeapAddress address='0xb90a8d0' isStatic='false' size='10' symbols='{[0]}' value='[StringValue [StateValue ] value='timeout__c']'],[HeapAddress address='0x6171129b' isStatic='false' size='2' symbols='{[0]}' value='[StringValue [StateValue ] value='Id']'],[HeapAddress address='0x44ae98d5' isStatic='false' size='18' symbols='{[0]}' value='[StringValue [StateValue ] value='m051l000000Cna2AAC']'],[HeapAddress address='0x50d9d984' isStatic='false' size='7' symbols='{[0]}' value='[StringValue [StateValue ] value='2327872']'],[HeapAddress address='0x3ce399a9' isStatic='false' size='34' symbols='{[1]data,}' value='[StringValue [StateValue ] value=objet/2327872/test']'],[HeapAddress address='0x208a5888' isStatic='false' size='3' symbols='{[1]operation,}' value='[StringValue [StateValue ] value='GET']'],}' totalSize='172' typeName='String'],}' heapDumpDate='java.util.GregorianCalendar[time=1578559862723,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneI nfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2020, MONTH=0,WEEK_OF_YEAR=2,WEEK_OF_MONTH=2,DAY_OF_MONTH=9,DAY_OF_YEAR=9,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0 ,HOUR=8,HOUR_OF_DAY=8,MINUTE=51,SECOND=2,MILLISECOND=723,ZONE_OFFSET=0,DST_OFFSET=0]' namespace='none'] Exemple d’un headDump obtenu via le debugger salesforce
  • 28. Coktail party • Génération autonome de package • Tooling Api • Partner Api • External code • Un peu de folie Création automatique du package avec pour critère : - date première modification - date dernière modification - Filtre par utilisateur ou non 28
  • 29. Quelques liens utiles L’ensemble des objets manipulables via la tooling Api : https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/reference_objects_list.htm Un site qui explique les différents types utilisable pour la metadatadependency: https://github.com/afawcett/dependencies-sample) Slack : https://join.slack.com/t/communityfrance/shared_invite/zt-e10uch11-W4rfrk4KrgSZR4tG0vd4PQ Si vous avez des questions , vous pouvez m’écrire à : fabrice.challier@littlechaman.com

Editor's Notes

  1. Penser à parler de rest vs soap (meme si c’est un peu technique pour des admin) Montrer que FileName n’existe pas mais qu’on a accès à d’autre champs --ToolingVsMetadata +workbench select CreatedById,CreatedBy.Name,CreatedDate,fullname,Id,LastModifiedById,LastModifiedBy.Name,LastModifiedDate,ManageableState,Description,ErrorDisplayField,ErrorMessage,ValidationName,Active from ValidationRule where EntityDefinition.DeveloperName ='Case'
  2. Cette table existe en standard comme en tooling api. Montrer un durableId un developerName et un qualifiedApiName pour un objet custom ->>ToolingApi_EntityDefinition + montrer dans dev console
  3. Chaque objet n’a de visibilité que sur certains type de dépendance ( plus d’infos : https://github.com/afawcett/dependencies-sample) exemples : Ou est utilisé mon CustomLabel ira chercher dans : ApexClass,ApexTrigger,VisualForce, Lightning Component Markup, Lightning Component Controller Ou est utilisé mon Flow ira chercher dans : ProcessBuilder,Apex,Lightning actions, lightning page, flow Etc …
  4. Login as Mehdi : 0014E0000128JmhQAE https://java-fun-4265-dev-ed--c.visualforce.com/apex/VFP_FormulaTest Ff tester : 500P0000008WunQIAS / Subject & CaseNumber / Subject & CaseNumber & '123’ / true
  5. Penser à insister sur le fait que les admin peuvent se focaliser sur le besoin « métier » et sur l’émergence d’une solution technique AP24MAJCase : très bon use case
  6. Case aCase = new Case(); insert aCase; system.debug(aCase.id); aCase.Id=null; update aCase; Full LWC383InfosSurLT.getInfos('5002o00002JMHXbAAP')
  7. fabrice fabrice challier / FormulaTesterUtil / 1 ou 2 /153 Soql : select testVR__c from Case where id ='500P0000008WunQIAS’
  8. Montrer le search avec Toronto