{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# GPT Action Library: Jira" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This page provides an instruction & guide for developers building a GPT Action for a specific application. Before you proceed, make sure to first familiarize yourself with the following information: \n", "- [Introduction to GPT Actions](https://platform.openai.com/docs/actions)\n", "- [Introduction to GPT Actions Library](https://platform.openai.com/docs/actions/actions-library)\n", "- [Example of Buliding a GPT Action from Scratch](https://platform.openai.com/docs/actions/getting-started)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This particular GPT Action provides an overview of how to connect to Jira, Atlassian's tool for project and ticket management. This action assumes a user’s context and allows them to read and write to issues in a given project." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Value + Example Business Use Cases" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Value**: Users can now leverage ChatGPT's natural language capability to connect directly to Jira Cloud\n", "\n", "**Example Use Cases**: \n", "- A user can load up recent issues for a particular project and use ChatGPT to provide solutions\n", "- A user can create and alter issues and sub-tasks and assign to specific users by instructing ChatGPT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Application Information" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Application Key Links" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check out these links from the application before you get started:\n", "- Application Website: https://.atlassian.net/jira\n", "- Application API Documentation: https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/\n", "- Application OAuth 2.0 Documentation: https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Application Prerequisites" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before you get started, make sure you go through the following steps in your application environment:\n", "- Ensure you have the access and permissions to create an application in the [Atlassian Cloud Developer Console](https://developer.atlassian.com/console/myapps/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ChatGPT Steps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Custom GPT Instructions " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you've created a Custom GPT, copy the text below in the Instructions panel. Have questions? Check out [Getting Started Example](https://platform.openai.com/docs/actions/getting-started) to see how this step works in more detail." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [ "**Context**: you are specialized GPT designed to create and edit issues through API connections to Jira Cloud. This GPT can create, read, and edit project issues based on user instructions.\n", "\n", "**Instructions**:\n", "- When asked to perform a task, use the available actions via the api.atlassian.com API.\n", "- When asked to create an issue, use the user's input to synthesize a summary and description and file the issue in JIRA.\n", "- When asked to create a subtask, assume the project key and parent issue key of the currently discussed issue. Clarify with if this context is not available.\n", "- When asked to assign an issue or task to the user, first use jql to query the current user's profile and use this account as the assignee. \n", "- Ask for clarification when needed to ensure accuracy and completeness in fulfilling user requests." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### OpenAPI Schema " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you've created a Custom GPT, copy the text below in the Actions panel. Have questions? Check out [Getting Started Example](https://platform.openai.com/docs/actions/getting-started) to see how this step works in more detail." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*NOTE: Replace the placeholder in url with your cloud environment's unique ID. You can find this value by visiting https://.atlassian.net/_edge/tenant_info*\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "yaml" } }, "outputs": [], "source": [ "openapi: 3.1.0\n", "info:\n", " title: Jira API\n", " description: API for interacting with Jira issues and sub-tasks.\n", " version: 1.0.0\n", "servers:\n", " - url: https://api.atlassian.com/ex/jira//rest/api/3\n", " description: Jira Cloud API\n", "components:\n", " securitySchemes:\n", " OAuth2:\n", " type: oauth2\n", " flows:\n", " authorizationCode:\n", " authorizationUrl: https://auth.atlassian.com/authorize\n", " tokenUrl: https://auth.atlassian.com/oauth/token\n", " scopes:\n", " read:jira-user: Read Jira user information\n", " read:jira-work: Read Jira work data\n", " write:jira-work: Write Jira work data\n", " schemas:\n", " Issue:\n", " type: object\n", " properties:\n", " id:\n", " type: string\n", " key:\n", " type: string\n", " fields:\n", " type: object\n", " properties:\n", " summary:\n", " type: string\n", " description:\n", " type: string\n", " issuetype:\n", " type: object\n", " properties:\n", " name:\n", " type: string\n", "paths:\n", " /search:\n", " get:\n", " operationId: getIssues\n", " summary: Retrieve a list of issues\n", " parameters:\n", " - name: jql\n", " in: query\n", " required: false\n", " schema:\n", " type: string\n", " - name: startAt\n", " in: query\n", " required: false\n", " schema:\n", " type: integer\n", " - name: maxResults\n", " in: query\n", " required: false\n", " schema:\n", " type: integer\n", " responses:\n", " '200':\n", " description: A list of issues\n", " content:\n", " application/json:\n", " schema:\n", " type: object\n", " properties:\n", " issues:\n", " type: array\n", " items:\n", " $ref: '#/components/schemas/Issue'\n", " /issue:\n", " post:\n", " operationId: createIssue\n", " summary: Create a new issue\n", " requestBody:\n", " required: true\n", " content:\n", " application/json:\n", " schema:\n", " type: object\n", " properties:\n", " fields:\n", " type: object\n", " properties:\n", " project:\n", " type: object\n", " properties:\n", " key:\n", " type: string\n", " summary:\n", " type: string\n", " description:\n", " type: string\n", " issuetype:\n", " type: object\n", " properties:\n", " name:\n", " type: string\n", " responses:\n", " '201':\n", " description: Issue created successfully\n", " content:\n", " application/json:\n", " schema:\n", " $ref: '#/components/schemas/Issue'\n", " /issue/{issueIdOrKey}:\n", " get:\n", " operationId: getIssue\n", " summary: Retrieve a specific issue\n", " parameters:\n", " - name: issueIdOrKey\n", " in: path\n", " required: true\n", " schema:\n", " type: string\n", " responses:\n", " '200':\n", " description: Issue details\n", " content:\n", " application/json:\n", " schema:\n", " $ref: '#/components/schemas/Issue'\n", " put:\n", " operationId: updateIssue\n", " summary: Update an existing issue\n", " parameters:\n", " - name: issueIdOrKey\n", " in: path\n", " required: true\n", " schema:\n", " type: string\n", " requestBody:\n", " required: true\n", " content:\n", " application/json:\n", " schema:\n", " type: object\n", " properties:\n", " fields:\n", " type: object\n", " properties:\n", " summary:\n", " type: string\n", " description:\n", " type: string\n", " issuetype:\n", " type: object\n", " properties:\n", " name:\n", " type: string\n", " responses:\n", " '204':\n", " description: Issue updated successfully\n", " /issue:\n", " post:\n", " operationId: createSubTask\n", " summary: Create a sub-task for an issue\n", " requestBody:\n", " required: true\n", " content:\n", " application/json:\n", " schema:\n", " type: object\n", " properties:\n", " fields:\n", " type: object\n", " properties:\n", " project:\n", " type: object\n", " properties:\n", " key:\n", " type: string\n", " parent:\n", " type: object\n", " properties:\n", " key:\n", " type: string\n", " summary:\n", " type: string\n", " description:\n", " type: string\n", " issuetype:\n", " type: object\n", " properties:\n", " name:\n", " type: string\n", " responses:\n", " '201':\n", " description: Sub-task created successfully\n", " content:\n", " application/json:\n", " schema:\n", " $ref: '#/components/schemas/Issue'\n", "security:\n", " - OAuth2:\n", " - read:jira-user\n", " - read:jira-work\n", " - write:jira-work\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Authentication Instructions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Below are instructions on setting up authentication with Jira. Have questions? Check out [Getting Started Example](https://platform.openai.com/docs/actions/getting-started) to see how this step works in more detail.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Jira Steps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. Create an Application: The first step is to create a new application in Jira for the integration with ChatGPT. This can be done by visiting the [Atlassian Developer Console](https://developer.atlassian.com/console/myapps/), Clicking **Create** and selecting **OAuth 2.0 Integration**. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_devconsole.png](../../../images/gptactions_jira_devconsole.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From here, simply enter the name of your integration and click **Create**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_newapplication.png](../../../images/gptactions_jira_newapplication.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2. Define Permissions: Next we need to provide the required permissions to our application. Within the new application, open the **Permissions** menu from the sidebar, locate **Jira API** and click **Add** and then **Configure**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_permissions.png](../../../images/gptactions_jira_permissions.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Required permissions will vary depending on the intended functionality of the GPT. In this scenario we wish to read and write to Jira issues, so select the following scopes under **Jira platform REST API** by clicking **Edit Scopes**:\n", "\n", "- read:jira-work\n", "- write:jira-work\n", "- read:jira-user\n", "\n", "Once selected, click **Save**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_scopes.png](../../../images/gptactions_jira_scopes.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3. Configure Placeholder Callback URL: In order to complete the following step and obtain a **Client ID** and **Secret** for enabling secure authentication between ChatGPT and Jira, we first need to add a placeholder callback URL. We can achieve this by clicking on **Authorization** in the sidebar, and **Configure** next to **OAuth 2.0 (3LO)**. From here simply enter a placeholder URL and click **Save Changes**.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_placeholder.png](../../../images/gptactions_jira_placeholder.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "4. Application Client ID/Secret: The next step is to locate the **Client ID** and **Secret** for enabling secure authentication between ChatGPT and Jira. We can find these values by clicking on **Settings** in the sidebar and scrolling down to **Authentication Details**. \n", "\n", " Keep this page open as we will require these values in the next stage of configuration!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_clientsecret.png](../../../images/gptactions_jira_clientsecret.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### In ChatGPT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In ChatGPT, click on \"Authentication\" and choose **\"OAuth\"**. Enter in the information below. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- **Client ID**: The **Client ID** from **Step 3** of Jira Configuration\n", "- **Client Secret**: The **Secret** from **Step 3** of Jira Configuration\n", "- **Authorization URL**: https://auth.atlassian.com/authorize\n", "- **Token URL**: https://auth.atlassian.com/oauth/token\n", "- **Scope**: read:jira-work write:jira-work read:jira-user \n", "- **Token Exchange Method**: Default (POST Request)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Post-Action Steps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you've set up authentication in ChatGPT, follow the steps below in the application to finalize the Action. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Copy the callback URL from the GPT Action" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_redirect.png](../../../images/gptactions_jira_redirect.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- In your application in the Atlassian Developer Console, navigate to the **Authorization** sidebar tab, next to **OAuth 2.0 (3L0)** click **Configure**, and add your callback URL under **Callback URL**\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![gptactions_jira_callback.png](../../../images/gptactions_jira_callback.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### FAQ & Troubleshooting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- **Callback URL Error**: If you get a callback URL error in ChatGPT, double check the Callback URL value as it can occasionally change depending on any alterations made to the authentication\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Are there integrations that you’d like us to prioritize? Are there errors in our integrations? File a PR or issue in our github, and we’ll take a look.*\n" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 2 }