Esta é a URL principal de consumo REST: /api/CRMGT/QueryXML
Com este conector, você pode efetuar todo CRUD de operações. Portanto, segue abaixo o uso prático deste recurso, usando Javascript/JQuery.
Para obter o Token de acesso (OAuth)
function getToken() { var param = { "orgName": "CRMGT1", "clientId": "+n8c++NABWZrkldVUaf0XYH2T2lG5xvUhZEVxFz46/4=__5@_", "clientSecret": "7RclDz1Ilbp3jyOuXJNnyfaK3bW+MIt5fU0BL1f46to=__0@_" }; $.ajax({ type: 'GET', url: 'https://crm-gt.com:82/api/CRMGT/GetToken', data: param, dataType: 'json', async: false, beforeSend: function(xmlHttpRequest) { xmlHttpRequest.withCredentials = true; }, success: function (data, textStatus, jqXHR) { token = data.token; }, error: function (jqXHR, textStatus, errorThrown) { debugger; } }); }
Considerações importantes sobre o token.
- Ele expira a cada 3 horas.
- O [clientId] e o [clientSecret] são criados por Organização. O administrador da organização cria estas chaves e as disponibiliza para obtenção do Token.
Para Renovar o Token de acesso (OAuth)
function renewToken() { var param = { 'orgName': 'CRMGT1', 'clientId': '73ySJQsDnHDYugLRRYmtATjCxVmcNo2/Alz8RG9D+VQ=__5|@_11|4_13|._', 'clientSecret': 'EPkMdqQcm0XgDxpn4lDcKKpEz0WPDQhgbXN6Nkl0JWw=' }; $.ajax({ type: 'GET', url: 'https://crm-gt.com:82/api/CRMGT/RenewToken', data: param, dataType: 'json', async: false, beforeSend: function (xmlHttpRequest) { xmlHttpRequest.withCredentials = true; }, success: function (data, textStatus, jqXHR) { if (data == null) { return 0; } else { token = data.token; } }, error: function (jqXHR, textStatus, errorThrown) { console.log(errorThrown); } }); }
Como saber se o token de acesso expirou? Ao executar o endpoint /GetToken, o sistema retorna um atributo informando que o tempo expirou ("expires_in" : "0").
Para os métodos de CREATE e UPDATE, no momento da configuração da tag [fields/field] atributo [TYPE], informe os tipos correspondentes aos do [SQL SERVER].
Segue os principais:
bit |
char |
nchar |
varchar |
nvarchar |
datetime |
datetime2 |
bit |
int |
decimal |
float |
text |
uniqueidentifier |
Se precisar adicionar um campo do tipo [valor ou moeda], informe [decimal], e assim por diante.
Para efetuar um SELECT
function selectRecords() { var xmlSELECT = "<select>" + "<organization name='CRMGT1' />" + "<table name='User' alias='tb1' />" + "<fields>" + " <field name='tb1.UserId' label='ID' />" + " <field name='tb1.Name' />" + " <field name='tb1.Email' />" + " <field name='tb2.Name' />" + " <field name='tb3.Name' />" + "</fields>" + "<join isLeftJoin='false' name='Status' alias='tb2' fieldFrom='statuscode' fieldTo='statuscode'>" + " <filter type='and'>" + " <condition field='tb2.name' operator='=' value='Ativo' />" + " </filter>" + "</join>" + "<join isLeftJoin='true' name='salesorder' alias='tb3' fieldFrom='userid' fieldTo='ownerid'>" + " <filter type='and'>" + " <condition field='tb3.name' operator='like' value='%ped%' />" + " </filter>" + "</join>" + "<filter type='and'>" + " <condition field='tb1.name' operator='like' value='%usr%' />" + "</filter>" + "<order>" + " <field name='tb1.Name ASC'/>" + " <field name='tb1.Email DESC'/>" + "</order>" + "</select>"; var param = { "Type": "GET", "xmlContent": xmlSELECT }; $.ajax({ type: 'POST', url: "https://crm-gt.com:82/api/CRMGT/QueryXML", data: param, dataType: 'json', contentType: "application/x-www-form-urlencoded; charset=utf-8", beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Bearer " + token); }, success: function (data, textStatus, jqXHR) { if (textStatus == "success") { // JSON que representa os [registros] retornados var json = JSON.parse(data.Result); } }, error: function (jqXHR, textStatus, errorThrown) { debugger; } }); }
Se precisar retornar todos os campos, deixe a tag [fields] vazia **
<fields />
Se precisar buscar dados NULOS (ou não nulos), utilize:
<condition field='tb1.name' operator='NULL' />
<condition field='tb1.name' operator='NOTNULL' />
Para efetuar um CREATE
function createRecord() { var xmlINSERT = "<insert>" + "<organization name='CRMGT1' />" + "<table name='account' isNN='false' setInternalFields='true' setWorkflowTrigger='false' />" + "<records>" + " <record>" + " <fields>" + " <field name='accountid' type='uniqueidentifier' value='NEWID' />" + " <field name='name' type='varchar' value='Create sample 1...' />" + " <field name='AccountNumber' type='varchar' value='1' />" + " <field name='ownerid' type='uniqueidentifier' lookuptable='user' lookupsearchfield='name' value='system' />" + " </fields>" + " </record>" + " <record>" + " <fields>" + " <field name='accountid' type='uniqueidentifier' value='NEWID' />" + " <field name='name' type='varchar' value='Create sample 2...' />" + " <field name='AccountNumber' type='varchar' value='2' />" + " </fields>" + " </record>" + "</records>" + "</insert>"; var param = { "Type": "SET", "xmlContent": xmlINSERT }; $.ajax({ type: 'POST', url: "https://crm-gt.com:82/api/CRMGT/QueryXML", data: param, dataType: 'json', contentType: "application/x-www-form-urlencoded; charset=utf-8", beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Bearer " + token); }, success: function (data, textStatus, jqXHR) { }, error: function (jqXHR, textStatus, errorThrown) { } }); }
Se precisar definir uma regra antes da criação dos registros, você pode adicionar a seguinte tag [rules] depois da tag [table]:
<rules> <rule action="insert_ignoreifexists" actionoperator="AND"> <fields> <field name="protocol" type="VarChar" /> <field name="incidentNumber" type="Int" /> <field name="ownerid" type="UniqueIdentifier" lookuptable="user" lookupsearchfield="name" /> <field name="modifiedon" type="datetime" hourformat="HH:mm" /> </fields> </rule> </rules>
Desta forma, através da regra [insert_ignoreifexists] você não permite a inclusão do registro se os campos especificados na tag [fields] existirem na tabela.
Mas se você quiser [atualizar] o registro se ele for encontrado, use a regra [insert_updateifexists]. Para esta regra, o update será realizado usando na cláusula [where] a [chave primária] da tabela.
Para campos do tipo [lookup] na regra você pode usar os atributos [lookuptable] e [lookupsearchfield] somente se o campo especificado na regra, no exemplo acima o [ownerid], tiver no XML de INSERT o conteúdo diferente de um GUID.
[lookuptable] - deve contér o nome da tabela que você deseja procurar o valor (no exemplo temos a tabela User)
[lookupsearchfield] - deve contér o nome do campo (da tabela [lookuptable]) para procurar o valor especificado no XML de INSERT.
Regras para campos do tipo [DateTime] vc pode especificar o formato da Hora para ser comparada.
Adicione o atributo [hourformat] com os seguintes conteúdos válidos:
HH:mm
HH:mm:ss
Formato de Campo Data
Sempre que passar um valor de data, passar no seguinte formato:
yyyyMMddTHHmmssZ
Exemplo: 20230616T095600Z
Se precisar [atualizar] o campo no CRM com valor Nulo:
<field name='dtFieldName' type='datetime' value='NULL' />
Se precisar [atualizar] o campo no CRM com a data [corrente]:
<field name='dtFieldName' type='datetime' value='GETDATE' />
Formato de Campo Decimal
Sempre que passar um valor decimal, usar o formato americano, somente com o separador de centavos:
Ex: 1234.56
Para efetuar um UPDATE
function updateRecord() { var xmlUPDATE = "<update>" + " <organization name='CRMGT1' />" + " <table name='account' setWorkflowTrigger='false' />" + " <set>" + " <field name='name' type='varchar' value='UPDATED - Create sample 1...' setWorkflowFieldTrigger='false' />" + " <field name='modifiedOn' type='datetime' value='GETDATE' />" + " </set>" + " <filter type='and'>" + " <condition field='name' operator='=' value='Create sample 1...' />" + " </filter>" + "</update>"; var param = { "Type": "SET", "xmlContent": xmlUPDATE }; $.ajax({ type: 'POST', url: "https://crm-gt.com:82/api/CRMGT/QueryXML", data: param, dataType: 'json', contentType: "application/x-www-form-urlencoded; charset=utf-8", beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Bearer " + token); }, success: function (data, textStatus, jqXHR) { }, error: function (jqXHR, textStatus, errorThrown) { } }); }
Para efetuar um DELETE
function deleteRecord() { var xmlDELETE = "<delete>" + " <organization name='CRMGT1' />" + " <table name='account' setWorkflowTrigger='false' />" + " <filter type='and'>" + " <condition field='name' operator='like' value='%Create sample%' />" + " </filter>" + "</delete>"; var param = { "Type": "SET", "xmlContent": xmlDELETE }; $.ajax({ type: 'POST', url: "https://crm-gt.com:82/api/CRMGT/QueryXML", data: param, dataType: 'json', contentType: "application/x-www-form-urlencoded; charset=utf-8", beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Bearer " + token); }, success: function (data, textStatus, jqXHR) { }, error: function (jqXHR, textStatus, errorThrown) { } }); }
Para executar uma [QUERY EXEC]
function executeQE() { var xmlQE = "<queryexec>" + " <organization name='CRMGT1' />" + " <queryexecid value='buscarocorrencia' />" + " <paramset>" + " <param name='@_id_' type='uniqueidentifier' value='62a9a715-8574-4813-a69f-e732c76313e0' />" + " </paramset>" + "<filter type='and'>" + " <condition field='inc.StatusCode' operator='=' value='1' />" + "</filter>" + "</queryexec>"; var param = { "Type": "QueryExec", "xmlContent": xmlQE }; $.ajax({ type: 'POST', url: "https://crm-gt.com:82/api/CRMGT/QueryXML", data: param, dataType: 'json', contentType: "application/x-www-form-urlencoded; charset=utf-8", beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Bearer " + token); }, success: function (data, textStatus, jqXHR) { }, error: function (jqXHR, textStatus, errorThrown) { } }); }
Obs: As tags <paramset> e <filter> são [opcionais]. Elas são úteis quando precisar passar mais parâmetros de filtro para a Query Exec criada no sistema ou para substituir o valor das macros do sistema (@_id_ por exemplo).