diff --git a/examples/chatgpt/gpt_actions_library/gpt_action_jira.ipynb b/examples/chatgpt/gpt_actions_library/gpt_action_jira.ipynb new file mode 100644 index 00000000..70ff5ae3 --- /dev/null +++ b/examples/chatgpt/gpt_actions_library/gpt_action_jira.ipynb @@ -0,0 +1,562 @@ +{ + "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. 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 +} diff --git a/images/gptactions_jira_callback.png b/images/gptactions_jira_callback.png new file mode 100644 index 00000000..43b1e8a8 Binary files /dev/null and b/images/gptactions_jira_callback.png differ diff --git a/images/gptactions_jira_clientsecret.png b/images/gptactions_jira_clientsecret.png new file mode 100644 index 00000000..19ae818f Binary files /dev/null and b/images/gptactions_jira_clientsecret.png differ diff --git a/images/gptactions_jira_devconsole.png b/images/gptactions_jira_devconsole.png new file mode 100644 index 00000000..0d2f17f5 Binary files /dev/null and b/images/gptactions_jira_devconsole.png differ diff --git a/images/gptactions_jira_newapplication.png b/images/gptactions_jira_newapplication.png new file mode 100644 index 00000000..ff701a52 Binary files /dev/null and b/images/gptactions_jira_newapplication.png differ diff --git a/images/gptactions_jira_permissions.png b/images/gptactions_jira_permissions.png new file mode 100644 index 00000000..f8cf9a1e Binary files /dev/null and b/images/gptactions_jira_permissions.png differ diff --git a/images/gptactions_jira_redirect.png b/images/gptactions_jira_redirect.png new file mode 100644 index 00000000..5ead62a4 Binary files /dev/null and b/images/gptactions_jira_redirect.png differ diff --git a/images/gptactions_jira_scopes.png b/images/gptactions_jira_scopes.png new file mode 100644 index 00000000..26b7a88f Binary files /dev/null and b/images/gptactions_jira_scopes.png differ diff --git a/registry.yaml b/registry.yaml index 86bdfe12..8962c7df 100644 --- a/registry.yaml +++ b/registry.yaml @@ -1422,6 +1422,15 @@ date: 2024-07-24 authors: - alwestmo-openai + tags: + - gpt-actions-library + - chatgpt + +- title: GPT Actions library - Jira + path: examples/chatgpt/gpt_actions_library/gpt_action_jira.ipynb + date: 2024-07-24 + authors: + - rupert-openai tags: - gpt-actions-library - chatgpt \ No newline at end of file