<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bruno Julião</title>
    <description>The latest articles on DEV Community by Bruno Julião (@brunojuliao).</description>
    <link>https://dev.to/brunojuliao</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F332389%2F0ab74a67-3c26-4d4c-ac84-cc7c27997d08.jpg</url>
      <title>DEV Community: Bruno Julião</title>
      <link>https://dev.to/brunojuliao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brunojuliao"/>
    <language>en</language>
    <item>
      <title>Adventures in Zendesk and Jira REST APIs</title>
      <dc:creator>Bruno Julião</dc:creator>
      <pubDate>Thu, 20 Feb 2020 19:10:17 +0000</pubDate>
      <link>https://dev.to/brunojuliao/adventures-in-zendesk-and-jira-rest-apis-3e13</link>
      <guid>https://dev.to/brunojuliao/adventures-in-zendesk-and-jira-rest-apis-3e13</guid>
      <description>&lt;p&gt;We migrated from Jira's cloud version to on-premises. This forced me to update some of our code as the endpoint changed, the custom fields and also authentication.&lt;/p&gt;

&lt;p&gt;On Jira's cloud, our C# tool uses "Atlassian.Net SDK" (&lt;a href="https://bitbucket.org/farmas/atlassian.net-sdk/src/master/"&gt;https://bitbucket.org/farmas/atlassian.net-sdk/src/master/&lt;/a&gt;), which I recommend. To access its api, you are required to create a token (&lt;a href="https://id.atlassian.com/manage/api-tokens"&gt;https://id.atlassian.com/manage/api-tokens&lt;/a&gt;). The authentication is as simple as using your username and the token as password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;jira&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Jira&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateRestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jiraUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Done. You have access to everything. At least everything I needed.&lt;br&gt;
Although, as I said, we changed to on-premises. The auth is a little different. We have a specific user only for programmatic access. This user is not in our domain. Instead of using a token, I use only the user's password. Same line than before. The difference is just password's content. Probably an application was also created and the user assigned to it, although I can't confirm as I don't have access.&lt;/p&gt;

&lt;p&gt;One tip, if you already have some code querying/using Jira, pay special attention to the custom fields. For example, in Python, the object returned has them in this fashion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jira&lt;/span&gt;

&lt;span class="n"&gt;cf_team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jira&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JIRA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;#Query using a custom field. Usually cf[123]
&lt;/span&gt;&lt;span class="n"&gt;issues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search_issues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cf[{cf_team}] = 'My Team'"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cf_team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cf_team&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;#Regular property usage
&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customfield_123&lt;/span&gt;

&lt;span class="c1"&gt;#More flexible
&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'fields'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'customfield_{cf_team}'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cf_team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cf_team&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That "123" is the field's id. The lib used is this: &lt;a href="https://pypi.org/project/jira/"&gt;https://pypi.org/project/jira/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you might have noticed, it's easy when moving from one installation to the other have the IDs changing. The code above have ways to work around and keep the code easier to maintain. You can have all the cfs somewhere else and just use/reference it. If the IDs change, you need to change only a single place. I admit it's not usual to move often Jira instalations. A simple search/replace could've fixed it. True.&lt;/p&gt;

&lt;p&gt;Alright. Enough Jira. What about Zendesk?&lt;/p&gt;

&lt;p&gt;On Zendeskt side, I only have a Python sample. Although, I haven't used any Zendesk specific lib. Just regular HTTP requests using the requests lib. It's as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;subdomain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mycompany"&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user@domain.com"&lt;/span&gt;
&lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"xyz"&lt;/span&gt;
&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'https://{subdomain}.zendesk.com/api/v2/tickets/{id}.json'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subdomain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subdomain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'Accept'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'{username}/token'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ticket_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'ticket'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Zendesk's API: &lt;a href="https://developer.zendesk.com/rest_api/docs/zendesk-apis/resources"&gt;https://developer.zendesk.com/rest_api/docs/zendesk-apis/resources&lt;/a&gt;&lt;br&gt;
Types of authentication: &lt;a href="https://developer.zendesk.com/rest_api/docs/support/requests"&gt;https://developer.zendesk.com/rest_api/docs/support/requests&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Observe that "/token" appended to the username. In the docs they say &lt;em&gt;{enduser_email_address}/token:{api_token}&lt;/em&gt; . In the Authorization (HTTP) header, usually it's &lt;em&gt;Authorization: Basic {user_plus_token_base64encoded}&lt;/em&gt; (assuming your are using the Basic authentication). You can find several references about basic auth saying the content to be encoded is just &lt;em&gt;username:password&lt;/em&gt; (where password can be a token). It took me a good amount of time to notice and properly append the &lt;em&gt;/token&lt;/em&gt; to the username... Silly, right?&lt;/p&gt;

&lt;p&gt;I hope the content shared here help :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>csharp</category>
      <category>zendesk</category>
      <category>jira</category>
    </item>
  </channel>
</rss>
