Salesforce REST API: authentification

python, api
Publié le 11/05/2017 | Jérémy Grèze

La REST API de Salesforce.com permet d’interagir avec l'ensemble des données du CRM (accounts, contacts, opportunities...). Néanmoins, il est nécessaire de s’authentifier au préalable, c'est-à-dire d'obtenir un (access token).

Un access token est valable seulement pendant quelques heures. Il faudra donc automatiser l'obtention ce token.

La documentation indique 3 protocoles OAuth différents pour s'authentifier: Web Server OAuth, User-Agent OAuth et Username-Password OAuth.

Le premier et le deuxième dans une certaine mesure offrent l'avantage de retourner également (en plus du access token) un refresh token qui permet d'obtenir un nouveau access token. J'utiliserais dans cet exemple le troisième protocole.

Créer une application

Dans tous les cas, il faut créer une "Connected App" sur l'instance Salesforce (prod ou sandbox).

Dans la configuration ("Setup"), rechercher et ouvrir la partie "App Manager". Créer une nouvelle app ("New Connected App"). Choisir un nom et entrer les divers champs obligatoires. Il faut cocher l'option "Enable OAuth Settings". Rendre tous les scopes disponibles dans "Selected OAuth Scopes". Remplir "http://localhost/" pour le "Callback URL". Sauvegarder.

Au final, il faut obtenir le "Consumer Key" et le "Consumer Secret". Bien noter ces deux valeurs pour la suite.

S'authentifier avec le Username-Password OAuth Flow de Salesforce

A l'aide de son login, password et security token, utiliser ce script Python pour obtenir l'access token.

import requests
params = {
    "grant_type": "password",
    "client_id": "XXX.YYY", # Consumer Key
    "client_secret": "0000000000000000", # Consumer Secret
    "username": "my@email.com", # The email you use to login
    "password": "MyPasswordMySecurityToken" # Concat your password and your security token
}
r = requests.post("https://login.salesforce.com/services/oauth2/token", params=params)
access_token = r.json().get("access_token")
instance_url = r.json().get("instance_url")
print("Access Token:", access_token)
print("Instance URL", instance_url)

Requêter l'API REST Salesforce

Une fois l'authentification validée, on peut requêter l'API REST Salesforce pour faire des extractions de données (leads, opportunités, etc.) ou même mettre à jour ou créer des données.

import requests
import base64

def sf_api_call(action, parameters = {}, method = 'get', data = {}):
    """
    Helper function to make calls to Salesforce REST API.
    """
    headers = {
        'Content-type': 'application/json',
        'Accept-Encoding': 'gzip',
        'Authorization': 'Bearer %s' % access_token
    }
    if method == 'get':
        r = requests.request(method, instance_url+action, headers=headers, params=parameters, timeout=30)
    elif method == 'post':
        r = requests.request(method, instance_url+action, headers=headers, data=data, params=parameters, timeout=10)
    else:
        # other methods not implemented in this example
        raise ValueError('Method should be get or post.')
    print('Debug: API %s call: %s' % (method, r.url) )
    if ((r.status_code == 200 and method == 'get') or (r.status_code == 201 and method == 'post')):
        return r.json()
    else:
        raise Exception('API error when calling %s : %s' % (r.url, r.content))

Un exemple tout simple: récupérons les prochaines opportunités qui vont "closer" avec une requête SOQL (Salesforce Object Query Language).

print(json.dumps(sf_api_call('/services/data/v39.0/query/', {
    'q': 'SELECT Account.Name, Name, CloseDate from Opportunity where IsClosed = False order by CloseDate ASC LIMIT 10'
}), indent=2))

Le résultat est un JSON facilement exploitable.

Voila!