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 C#.
Busca do Token de acesso (OAuth)
var url = "https://crm-gt.com/api/CRMGT/GetToken"; url += "?orgName=CRMGT1"; url += "&clientId=+n8c++NABWZrkldVUaf0XYH2T2lG5xvUhZEVxFz46/4=__5@_"; url += "&clientSecret=7RclDz1Ilbp3jyOuXJNnyfaK3bW+MIt5fU0BL1f46to=__0@_"; var jToken = GetString(url); var token = JsonConvert.DeserializeObject<JObject>(jToken).SelectToken("token").ToString();
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)
var url = "https://crm-gt.com/api/CRMGT/RenewToken"; url += "?orgName=CRMGT1"; url += "&clientId=+n8c++NABWZrkldVUaf0XYH2T2lG5xvUhZEVxFz46/4=__5@_"; url += "&clientSecret=7RclDz1Ilbp3jyOuXJNnyfaK3bW+MIt5fU0BL1f46to=__0@_"; var jToken = GetString(url); var token = JsonConvert.DeserializeObject<JObject>(jToken).SelectToken("token").ToString();
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:
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
1 - Monte o "SELECT" através de uma instrução XML:
string xmlSELECT = @" <select> <organization name='{0}' /> <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>";
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' />
O XML acima é a representação do SELECT-SQL abaixo:
SELECT tb1.UserId, tb1.Name, tb1.Email, tb2.Name, tb3.Name FROM [User] tb1 JOIN [Status] tb2 ON tb1.statuscode = tb2.statuscode AND tb2.name = 'Ativo' LEFT JOIN [salesorder] tb3 ON TB1.UserId = tb3.ownerid AND tb3.name like '%ped%' WHERE tb1.Name like '%usr%' ORDER BY tb1.Name ASC, tb1.Email DESC
2 - Passe como parâmetro a informação de [Organização], conforme a sequência abaixo.
var xmlF = string.Format(xmlSELECT, "CRMGT1");
3 - Execute a instrução, chamando a Web Api:
var header = new Dictionary<string, object>(); header.Add("Authorization", $"Bearer {token}"); var content = new Dictionary<string, object>(); content.Add("Type", "GET"); content.Add("Caller", "My Function Caller Name"); content.Add("xmlContent", xmlF); var result = ExecutePostAsync("https://crm-gt.com/api/CRMGT/QueryXML", content, header);
Segue abaixo métodos [GetString] e [ExecutePostAsync] que efetuam chamadas HTTP:
public static String GetString(String url) { var urlContents = ""; try { using (HttpClient client = new HttpClient()) { urlContents = client.GetStringAsync(new Uri(url)).Result; } } catch (Exception ex) { } return urlContents; }
public static string ExecutePostAsync(string url, Dictionary<string, object> content, Dictionary<string, object> headerList = null) { string result = ""; try { using (HttpClient client = new HttpClient()) { if (headerList != null) { foreach (var item in headerList) { client.DefaultRequestHeaders.Add(item.Key, item.Value.ToString()); } } if (content != null) { var multiPartContent = new MultipartFormDataContent(); foreach (var item in content) { multiPartContent.Add(new StringContent(item.Value.ToString()), string.Format("\"{0}\"", item.Key)); } var request = new HttpRequestMessage(HttpMethod.Post, url); request.Content = multiPartContent; result = client.SendAsync(request).Result.Content.ReadAsStringAsync().Result; } } } catch (Exception ex) { } return result; }
Para efetuar um CREATE
1 - Monte o "CREATE" através de uma instrução XML:
string xmlINSERT = @" <insert> <organization name='{0}' /> <table name='{1}' isNN='false' setInternalFields='true' setWorkflowTrigger='false' /> <records> <record> <fields> <field name='statuscode' type='int' value='998' /> <field name='name' type='varchar' value='test1...' /> <field name='ownerid' type='uniqueidentifier' lookuptable='user' lookupsearchfield='name' value='system' /> </fields> </record> <record> <fields> <field name='statuscode' type='int' value='999' /> <field name='name' type='varchar' value='test2...' /> <field name='ownerid' type='uniqueidentifier' value='9EC0ABA8-2947-4857-9698-1C43BBBFAB5B' /> </fields> </record> </records> </insert>";
2 - Passe como parâmetro as informações de [Organização] e [tabela], conforme a sequência abaixo.
var xmlF = string.Format(xmlINSERT, "CRMGT1", "lead");
3 - Execute a instrução, chamando a Web Api:
var header = new Dictionary<string, object>(); header.Add("Authorization", $"Bearer {token}"); var content = new Dictionary<string, object>(); content.Add("Type", "SET"); content.Add("Caller", "My Function Caller Name"); content.Add("xmlContent", xmlF); var result = ExecutePostAsync("https://crm-gt.com/api/CRMGT/QueryXML", content, header);
Para inserir dados em uma tabela N-N, adicione o atributo [isNN='true'] na tag xml [table], conforme exemplificado abaixo:
string xmlINSERT = @" <insert> <organization name='{0}' /> <table name='{1}' isNN='true' /> <records> <record> <fields> <field name='pricelist_productid' type='uniqueidentifier' value='NEWID' /> <field name='pricelistid' type='uniqueidentifier' value='3BEF33F8-A159-4F77-964D-B820B8414E59' /> <field name='productid' type='uniqueidentifier' value='B091A317-4FF7-42BE-AD86-D77C22059E49' /> </fields> </record> <record> <fields> <field name='pricelist_productid' type='uniqueidentifier' value='NEWID' /> <field name='pricelistid' type='uniqueidentifier' value='3BEF33F8-A159-4F77-964D-B820B8414E59' /> <field name='productid' type='uniqueidentifier' value='6922B778-B4FF-4564-A992-E40A020C599F' /> </fields> </record> </records> </insert>";
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
1 - Monte o "UPDATE" através de uma instrução XML:
string xmlUPDATE = @" <update> <organization name='{0}' /> <table name='{1}' setWorkflowTrigger='false' /> <set> <field name='name' type='varchar' value='TEST UPD...' setWorkflowFieldTrigger='false' /> <field name='modifiedOn' type='datetime' value='GETDATE' /> </set> <filter type='and'> <condition field='name' operator='=' value='TEST' /> </filter> </update>";
2 - Passe como parâmetro as informações de [Organização] e [tabela], conforme a sequência abaixo.
var xmlF = string.Format(xmlUPDATE, "CRMGT1", "Status");
3 - Execute a instrução, chamando a Web Api:
var header = new Dictionary<string, object>(); header.Add("Authorization", $"Bearer {token}"); var content = new Dictionary<string, object>(); content.Add("Type", "SET"); content.Add("Caller", "My Function Caller Name"); content.Add("xmlContent", xmlF); var result = ExecutePostAsync("https://crm-gt.com/api/CRMGT/QueryXML", content, header);
Para efetuar um DELETE
1 - Monte o "DELETE" através de uma instrução XML:
string xmlDELETE = @" <delete> <organization name='{0}' /> <table name='{1}' setWorkflowTrigger='false' /> <filter type='and'> <condition field='name' operator='=' value='TEST...' /> </filter> </delete>";
2 - Passe como parâmetro as informações de [Organização] e [tabela], conforme a sequência abaixo.
var xmlF = string.Format(xmlDELETE, "CRMGT1", "Status");
3 - Execute a instrução, chamado a Web Api:
var header = new Dictionary<string, object>(); header.Add("Authorization", $"Bearer {token}"); var content = new Dictionary<string, object>(); content.Add("Type", "SET"); content.Add("Caller", "My Function Caller Name"); content.Add("xmlContent", xmlF); var result = ExecutePostAsync("https://crm-gt.com/api/CRMGT/QueryXML", content, header);
Para executar uma [QUERY EXEC]
1 - Monte a "QUERY EXEC" através de uma instrução XML:
string xmlQE = @" <queryexec> <organization name='{0}' /> <queryexecid value='{1}' /> <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>";
2 - Passe como parâmetro as informações de [Organização] e [ID da query exec], conforme a sequência abaixo.
var xmlF = string.Format(xmlQE, "CRMGT1", "buscarocorrencias");
3 - Execute a instrução, chamado a Web Api:
var header = new Dictionary<string, object>(); header.Add("Authorization", $"Bearer {token}"); var content = new Dictionary<string, object>(); content.Add("Type", "QueryExec"); content.Add("Caller", "My Function Caller Name"); content.Add("xmlContent", xmlF); var result = ExecutePostAsync("https://crm-gt.com/api/CRMGT/QueryXML", content, header);
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).
Nenhum comentário:
Postar um comentário
<< Ao enviar um comentário, favor clicar na opção [Enviar por e-mail comentários de acompanhamento para gtezini@gmail.com] >>