SIL и Salesforce

В этой статье я расскажу о том, как можно работать с Salesforce из SIL.

SIL это язык программирования для автоматизации действий в Atlassian Jira и Confluence. Вы можете больше почитать про SIL вот здесь.

Существует 3 опции по работе с Salesforce из SIL:

  1. Использовать плагин Power Salesforce Connector.
  2. Написать свои функции на SIL.
  3. Написать свое расширение для SIL.

В этой статье мы рассмотрим первые две опции. Про то, как создавать свои расширения для SIL, можно почитать вот тут.

Но прежде чем переходить к коду необходимо настроить Salesforce.

Настройка Salesforce

Мы будем использовать Salesforce Rest API для работы с Salesforce, поэтому сначала нам нужно настроить подключаемое приложение(connected app).

Для того, чтобы настроить подключаемое приложение, перейдем шестеренка -> Setup:

Выберем App -> App Manager:

Нажмем на кнопку New Connected App:

Выберем опцию, чтобы активировать OAuth (Enable OAuth settings). Установим Full Access, нажмем на кнопку Add и затем на кнопку Save.

На следующей странице под настройками OAuth мы увидим Consumer Key и опцию для открытия Consumer Secret. Запомним эти два параметра. Они нам понадобятся для установки соединения с Salesforce.

Кроме того, необходимо сгенерировать секретный ключ пользователя (user secret token). Для этого зайдем в User Settings → Reset My Security Token. Новый секретный ключ пользователя будет выслан нам на почту:

Теперь у нас есть все необходимое, чтобы работать с Salesforce из SIL.

Power Salesforce Connector

Power Salesforce connector позволяет Вам работать с такими объектами в Salesforce как Account и Opportunity, кроме того Вы можете получать результаты запросов на языке SOQL. Все доступные в плагине SIL функции Вы можете найти вот здесь.

Преимущество использования плагина состоит в том, что Вам не нужно писать свои SIL функции для работы с Salesforce и разбираться в тонкостях Salesforce Rest API. Это позволит Вам сконцентрироваться на бизнес задачах, а не на технических задачах.

Но безусловно у плагина есть и ряд недостатков:

  • Salesforce Rest API намного богаче, чем работа с Account, Opportunity и получение результатов SOQL запросов. Если Вам потребуются функции, которых нет в плагине, Вам придется написать свои SIL функции.
  • Для получения результатов по Account и Opportunity используются встроенные в плагин структуры. Все структуры содержат доступные из коробки поля, но в Salesforce можно создавать и свои поля. У Вас не получится работать с созданными Вами полями в Salesforce.
  • Сам плагин бесплатный, но он не будет работать, если у Вас не установлен один из следующих платных плагинов: Power ScriptsPower ActionsPower Custom Fields ProDatabase Custom FieldsRights DNAKIWIUser Group Picker.

Итак, допустим мы решили использовать Power Salesforce connector.

Сначала нам нужно установить этот плагин с Atlassian Marketplace, а затем создать подключение к Salesforce из Atlassian Jira ( шестеренка -> manage apps -> SFDC Connection Configuration):

Нажмем кнопку Add connection:

Заполним обязательные поля и нажмем на кнопку Save.

Теперь мы можем писать код на SIL.

Для начала выберем Opportunity из Salesforce.

Зайдем в SIL Manager, создадим новый файл и напишем следующий код:

SFDCConnection sfdcConnection = connectToSalesforce("My SFDC Connection");
SFDCOpportunity opp = sfdcGetOpportunity(sfdcConnection, "0064F00000NKA7CQAX");
runnerLog(opp);

Как видно, для получения данных по Opportunity мы написали только 2 строчки кода. В первой строчке мы подключаемся к Salesforce (я назвал мое подключение My SFDC Connection). Во второй строчке мы получаем данные из Salesforce, используя Opportunity Id.

Для того, чтобы изменить какое-то поле в Opportunity, напишем вот такой код:

SFDCConnection sfdcConnection = connectToSalesforce("My SFDC Connection");
SFDCOpportunity opp;
opp.Description = "My new description";
sfdcUpdateOpportunity(sfdcConnection, "0064F00000NKA7CQAX", opp);

Как видно, код достаточно простой, и кроме того в документации по плагину есть примеры на каждую функцию, реализованную в плагине. Примеры можно посмотреть вот здесь.

Но что если Вам не подходит Power Salesforce Connector? В этом случае мы можем создавать свои SIL функции.

Создание своих SIL функций

Первым делом создадим функцию подключения к Salesforce:

struct SFDCConnection {
    string access_token;
    string instance_url;
    string id;
    string token_type;
    string issued_at;
    string signature;
}

function connectToSalesforce(string consumer_key,
                      string consumer_secret,
                      string user_name,
                      string user_password) {
    HttpRequest request;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
    string dummyPayload;
    string url = "https://login.salesforce.com/services/oauth2/token";
    string url_string = "?grant_type=password&client_id=" + consumer_key+ 
                    "&client_secret=" + consumer_secret + 
                    "&username=" + user_name + 
                    "&password=" + user_password; 
    SFDCConnection connection = httpPost(url + url_string, request, dummyPayload);
    runnerLog(httpGetErrorMessage());
    return connection;
}

Сначала мы создали структуру на основе JSON, который возвращается из Salesforce при подключении. А затем использовали метод https://login.salesforce.com/services/oauth2/token для того, чтобы подключиться к Salesforce.

Теперь давайте создадим функцию по получению данных по Opportunity. Для этого мы используем метод /vXX.X/sobjects/SObjectName/id/:

struct Opportunity {
    string Id;
    string AccountId;
    string Name;
    string Description;
    string StageName;
    string OwnerId;
}

function getOppFromOppId(string access_token,
                string url,
                string oppId) {
    Opportunity result;
    HttpRequest request;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
    header = httpCreateHeader("Authorization", "Bearer " + access_token);
    request.headers += header;
    result = httpGet(url + "/services/data/v39.0/sobjects/Opportunity/" + oppId, request);
    return result;
}

Опять же мы определили структуру для данных по Opportunity, а потом вызвали Salesforce Rest API метод.

Теперь напишем код, который использует наши функции:

SFDCConnection connection = connectToSalesforce(consumer_key, consumer_secret, user_name, user_password);
Opportunity opp = getOppFromOppId(connection.access_token, connection.instance_url, "0064F00000NKA7CQAX");
runnerLog(opp);

У нас получились теже самые 2 строчки кода. Однако наш полный код выглядит вот так:

struct SFDCConnection {
    string access_token;
    string instance_url;
    string id;
    string token_type;
    string issued_at;
    string signature;
}

function connectToSalesforce(string consumer_key,
                      string consumer_secret,
                      string user_name,
                      string user_password) {
    HttpRequest request;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
    string dummyPayload;
    string url = "https://login.salesforce.com/services/oauth2/token";
    string url_string = "?grant_type=password&client_id=" + consumer_key+ 
                    "&client_secret=" + consumer_secret + 
                    "&username=" + user_name + 
                    "&password=" + user_password; 
    SFDCConnection connection = httpPost(url + url_string, request, dummyPayload);
    runnerLog(httpGetErrorMessage());
    return connection;
}

struct Opportunity {
    string Id;
    string Name;
    string Description;
    string StageName;
    string OwnerId;
}

function getOppFromOppId(string access_token,
                string url,
                string oppId) {
    Opportunity result;
    HttpRequest request;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
    header = httpCreateHeader("Authorization", "Bearer " + access_token);
    request.headers += header;
    result = httpGet(url + "/services/data/v39.0/sobjects/Opportunity/" + oppId, request);
    return result;
}

string consumer_key = "your consumer key";
string consumer_secret = "your consumer secret";  
string user_name = "your user name";
string user_password = "password and user secret token";

SFDCConnection connection = connectToSalesforce(consumer_key, consumer_secret, user_name, user_password);
Opportunity opp = getOppFromOppId(connection.access_token, connection.instance_url, "0064F00000NKA7CQAX");
runnerLog(opp);

Если Вы хотите, к примеру, обновить Opportunity, то Вам необходимо реализовать свою SIL функцию для этого, используя Salesforce Rest API.

Кроме того, как видно в нашем примере мы получали из Opportunity следующие поля: id, name, description, stagename и owner.

Допустим Вы хотите добавить поле accountid. Для этого Вам нужно изменить структуру следующим образом:

struct Opportunity {
    string Id;
    string Name;
    string Description;
    string StageName;
    string OwnerId;
    string AccountId;
}

Мы добавили поле AccountId в конец структуры.

Из примеров видно, что если Вы пишите свои SIL функции, то Вы можете реализовать вызов любого метода Salesforce Rest API, но для этого Вам нужно потратить значительно больше времени на написание своего кода. Но, с другой стороны, это бесплатно.

Leave a Reply

%d bloggers like this: