diff --git a/authors.yaml b/authors.yaml index 23ed60f3..614e68bb 100644 --- a/authors.yaml +++ b/authors.yaml @@ -122,3 +122,8 @@ aa-openai: name: "Allison August" website: "https://www.linkedin.com/in/allisonaugust/" avatar: "https://avatars.githubusercontent.com/u/172655668?v=4" + +alwestmo-openai: + name: "Anthony Westmoreland" + website: "https://www.linkedin.com/in/westmorelandanthony/" + avatar: "https://avatars2.githubusercontent.com/u/175844346" \ No newline at end of file diff --git a/examples/chatgpt/gpt_actions_library/gpt_action_gmail.ipynb b/examples/chatgpt/gpt_actions_library/gpt_action_gmail.ipynb new file mode 100644 index 00000000..0198bbbb --- /dev/null +++ b/examples/chatgpt/gpt_actions_library/gpt_action_gmail.ipynb @@ -0,0 +1,616 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GPT Action Library: Gmail" + ] + }, + { + "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 Building a GPT Action from Scratch](https://platform.openai.com/docs/actions/getting-started)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This GPT Action provides an overview of how to connect to Google Gmail, Google’s Private & Secure Email for Personal or Business. This Action is connected to the Google Gmail APIs that can read, send, list, and draft emails in the authorized account. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Value + Example Business Use Cases" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Value**: The Gmail GPT will serve as a powerful tool to streamline communication processes, improve customer engagement, and optimize resource allocation.\n", + "\n", + "**Example Use Cases**: \n", + "- Manage internal communications by summarizing lengthy emails and drafting responses based on previous email threads.\n", + "- Support agents can provide customers with instant responses adhering to a company’s communication guidelines, tone, and style.\n", + "- Reference other GPTs , such as a data analsys GPT, and then ask for a draft/send of the consolidated analysis through email communication." + ] + }, + { + "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://mail.google.com/mail/u/0/#inbox\n", + "- Application API Documentation: https://developers.google.com/gmail/api/guides" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Application Prerequisites" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before you get started, make sure you’ve a Google Cloud account and that the Gmail API is enabled:\n", + "- Set up a Google Cloud project\n", + "- Enable Gmail API from Google API Library\n", + "- If application’s “Publishing Status” is “Testing”, ensure users are added to your application" + ] + }, + { + "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**\n", + "Act as an email assistant designed to enhance user interaction with emails in various ways. This GPT can assist with productivity by summarizing emails/threads, identifying next steps/follow-ups, drafting or sending pre-written responses, and programmatically interacting with third-party tools (e.g., Notion to-dos, Slack channel summaries, data extraction for responses). This GPT has full scope access to the GMAIL OAuth 2.0 API, capable of reading, composing, sending, and permanently deleting emails from Gmail.\n", + "\n", + "**Instructions**\n", + "- Always conclude an email by signing off with logged in user's name, unless otherwise stated.\n", + "- Verify that the email data is correctly encoded in the required format (e.g., base64 for the message body).\n", + "- Email Encoding Process: 1\\ Construct the email message in RFC 2822 format. 2\\ Base64 encode the email message. 3\\Send the encoded message using the API.\n", + "- If not specified, sign all emails with the user name.\n", + "- API Usage: After answering the user's question, do not call the Google API again until another question is asked.\n", + "- All emails created, draft or sent, should be in plain text.\n", + "- Ensure that the email format is clean and is formatted as if someone sent the email from their own inbox. Once a draft is created or email sent, display a message to the user confirming that the draft is ready or the email is sent.\n", + "- Check that the \"to\" email address is valid and in the correct format. It should be in the format \"recipient@example.com\". \n", + "- Only provide summaries of existing emails; do not fabricate email content.\n", + "- Professionalism: Behave professionally, providing clear and concise responses.\n", + "- Clarification: Ask for clarification when needed to ensure accuracy and completeness in fulfilling user requests.\n", + "- Privacy and Security: Respect user privacy and handle all data securely.\n" + ] + }, + { + "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": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "yaml" + } + }, + "outputs": [], + "source": [ + "openapi: 3.1.0\n", + "info:\n", + " title: Gmail Email API\n", + " version: 1.0.0\n", + " description: API to read, write, and send emails in a Gmail account.\n", + "servers:\n", + " - url: https://gmail.googleapis.com\n", + "paths:\n", + " /gmail/v1/users/{userId}/messages:\n", + " get:\n", + " summary: List All Emails\n", + " description: Lists all the emails in the user's mailbox.\n", + " operationId: listAllEmails\n", + " parameters:\n", + " - name: userId\n", + " in: path\n", + " required: true\n", + " schema:\n", + " type: string\n", + " description: The user's email address. Use \"me\" to indicate the authenticated user.\n", + " - name: q\n", + " in: query\n", + " schema:\n", + " type: string\n", + " description: Query string to filter messages (optional).\n", + " - name: pageToken\n", + " in: query\n", + " schema:\n", + " type: string\n", + " description: Token to retrieve a specific page of results in the list.\n", + " - name: maxResults\n", + " in: query\n", + " schema:\n", + " type: integer\n", + " description: Maximum number of messages to return.\n", + " responses:\n", + " '200':\n", + " description: Successful response\n", + " content:\n", + " application/json:\n", + " schema:\n", + " $ref: '#/components/schemas/MessageList'\n", + " '400':\n", + " description: Bad Request\n", + " '401':\n", + " description: Unauthorized\n", + " '403':\n", + " description: Forbidden\n", + " '404':\n", + " description: Not Found\n", + " '500':\n", + " description: Internal Server Error\n", + " /gmail/v1/users/{userId}/messages/send:\n", + " post:\n", + " summary: Send Email\n", + " description: Sends a new email.\n", + " operationId: sendEmail\n", + " parameters:\n", + " - name: userId\n", + " in: path\n", + " required: true\n", + " schema:\n", + " type: string\n", + " description: The user's email address. Use \"me\" to indicate the authenticated user.\n", + " requestBody:\n", + " required: true\n", + " content:\n", + " application/json:\n", + " schema:\n", + " $ref: '#/components/schemas/Message'\n", + " responses:\n", + " '200':\n", + " description: Email sent successfully\n", + " content:\n", + " application/json:\n", + " schema:\n", + " $ref: '#/components/schemas/Message'\n", + " '400':\n", + " description: Bad Request\n", + " '401':\n", + " description: Unauthorized\n", + " '403':\n", + " description: Forbidden\n", + " '500':\n", + " description: Internal Server Error\n", + " /gmail/v1/users/{userId}/messages/{id}:\n", + " get:\n", + " summary: Read Email\n", + " description: Gets the full email content including headers and body.\n", + " operationId: readEmail\n", + " parameters:\n", + " - name: userId\n", + " in: path\n", + " required: true\n", + " schema:\n", + " type: string\n", + " description: The user's email address. Use \"me\" to indicate the authenticated user.\n", + " - name: id\n", + " in: path\n", + " required: true\n", + " schema:\n", + " type: string\n", + " description: The ID of the email to retrieve.\n", + " responses:\n", + " '200':\n", + " description: Successful response\n", + " content:\n", + " application/json:\n", + " schema:\n", + " $ref: '#/components/schemas/FullMessage'\n", + " '400':\n", + " description: Bad Request\n", + " '401':\n", + " description: Unauthorized\n", + " '403':\n", + " description: Forbidden\n", + " '404':\n", + " description: Not Found\n", + " '500':\n", + " description: Internal Server Error\n", + " /gmail/v1/users/{userId}/messages/{id}/metadata:\n", + " get:\n", + " summary: Get Email Metadata\n", + " description: Gets the metadata of an email, including subject line.\n", + " operationId: getEmailMetadata\n", + " parameters:\n", + " - name: userId\n", + " in: path\n", + " required: true\n", + " schema:\n", + " type: string\n", + " description: The user's email address. Use \"me\" to indicate the authenticated user.\n", + " - name: id\n", + " in: path\n", + " required: true\n", + " schema:\n", + " type: string\n", + " description: The ID of the email to retrieve metadata for.\n", + " responses:\n", + " '200':\n", + " description: Successful response\n", + " content:\n", + " application/json:\n", + " schema:\n", + " $ref: '#/components/schemas/MessageMetadata'\n", + " '400':\n", + " description: Bad Request\n", + " '401':\n", + " description: Unauthorized\n", + " '403':\n", + " description: Forbidden\n", + " '404':\n", + " description: Not Found\n", + " '500':\n", + " description: Internal Server Error\n", + " /gmail/v1/users/{userId}/drafts:\n", + " post:\n", + " summary: Create Draft\n", + " description: Creates a new email draft.\n", + " operationId: createDraft\n", + " parameters:\n", + " - name: userId\n", + " in: path\n", + " required: true\n", + " schema:\n", + " type: string\n", + " description: The user's email address. Use \"me\" to indicate the authenticated user.\n", + " requestBody:\n", + " required: true\n", + " content:\n", + " application/json:\n", + " schema:\n", + " $ref: '#/components/schemas/Draft'\n", + " responses:\n", + " '200':\n", + " description: Draft created successfully\n", + " content:\n", + " application/json:\n", + " schema:\n", + " $ref: '#/components/schemas/Draft'\n", + " '400':\n", + " description: Bad Request\n", + " '401':\n", + " description: Unauthorized\n", + " '403':\n", + " description: Forbidden\n", + " '500':\n", + " description: Internal Server Error\n", + "components:\n", + " schemas:\n", + " MessageList:\n", + " type: object\n", + " properties:\n", + " messages:\n", + " type: array\n", + " items:\n", + " $ref: '#/components/schemas/Message'\n", + " nextPageToken:\n", + " type: string\n", + " Message:\n", + " type: object\n", + " properties:\n", + " id:\n", + " type: string\n", + " threadId:\n", + " type: string\n", + " labelIds:\n", + " type: array\n", + " items:\n", + " type: string\n", + " snippet:\n", + " type: string\n", + " raw:\n", + " type: string\n", + " format: byte\n", + " description: The entire email message in an RFC 2822 formatted and base64url encoded string.\n", + " FullMessage:\n", + " type: object\n", + " properties:\n", + " id:\n", + " type: string\n", + " threadId:\n", + " type: string\n", + " labelIds:\n", + " type: array\n", + " items:\n", + " type: string\n", + " snippet:\n", + " type: string\n", + " payload:\n", + " type: object\n", + " properties:\n", + " headers:\n", + " type: array\n", + " items:\n", + " type: object\n", + " properties:\n", + " name:\n", + " type: string\n", + " value:\n", + " type: string\n", + " parts:\n", + " type: array\n", + " items:\n", + " type: object\n", + " properties:\n", + " mimeType:\n", + " type: string\n", + " body:\n", + " type: object\n", + " properties:\n", + " data:\n", + " type: string\n", + " MessageMetadata:\n", + " type: object\n", + " properties:\n", + " id:\n", + " type: string\n", + " threadId:\n", + " type: string\n", + " labelIds:\n", + " type: array\n", + " items:\n", + " type: string\n", + " snippet:\n", + " type: string\n", + " headers:\n", + " type: array\n", + " items:\n", + " type: object\n", + " properties:\n", + " name:\n", + " type: string\n", + " value:\n", + " type: string\n", + " EmailDraft:\n", + " type: object\n", + " properties:\n", + " to:\n", + " type: array\n", + " items:\n", + " type: string\n", + " cc:\n", + " type: array\n", + " items:\n", + " type: string\n", + " bcc:\n", + " type: array\n", + " items:\n", + " type: string\n", + " subject:\n", + " type: string\n", + " body:\n", + " type: object\n", + " properties:\n", + " mimeType:\n", + " type: string\n", + " enum: [text/plain, text/html]\n", + " content:\n", + " type: string\n", + " Draft:\n", + " type: object\n", + " properties:\n", + " id:\n", + " type: string\n", + " message:\n", + " $ref: '#/components/schemas/Message'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Authentication Instructions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below are instructions on setting up authentication with this 3rd party application. 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": [ + "### Pre-Action Steps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before you set up authentication in ChatGPT, please take the following steps in the application.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Go to the Google Cloud Console\n", + "- Navigate to API & Services > Credentials" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![gptactions_BigQuery_auth.png](../../../images/gptactions_Gmail_enableAPIs.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![gptactions_BigQuery_auth.png](../../../images/gptactions_Gmail_gmailApiTile.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Create new OAuth credentials (or use an existing one)\n", + "\n", + "![gptactions_BigQuery_auth.png](../../../images/gptactions_Gmail_apikey.png)\n", + "\n", + "- Locate your OAuth Client ID & Client Secret and store both values securely (see screenshot below)\n", + "\n", + "![gptactions_BigQuery_auth.png](../../../images/gptactions_Gmail_clientidsecret.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**: use Client ID from steps above \n", + "- **Client Secret**: use Client Secret from steps above\n", + "- **Authorization URL**: https://accounts.google.com/o/oauth2/auth\n", + "- **Token URL**: https://oauth2.googleapis.com/token \n", + "- **Scope**: https://mail.google.com/\n", + "- **Token**: Default (POST)" + ] + }, + { + "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\n", + "- In the “Authorized redirect URIs” (see screenshot above), add your callback URL \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### FAQ & Troubleshooting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- *Callback URL Error:* If you get a callback URL error in ChatGPT, pay close attention to the screenshot above. You need to add the callback URL directly into GCP for the action to authenticate correctly\n", + "- *Schema calls the wrong project or dataset:* If ChatGPT calls the wrong project or dataset, consider updating your instructions to make it more explicit either (a) which project / dataset should be called or (b) to require the user provide those exact details before it runs the query" + ] + }, + { + "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_Gmail_apikey.png b/images/gptactions_Gmail_apikey.png new file mode 100644 index 00000000..33d355be Binary files /dev/null and b/images/gptactions_Gmail_apikey.png differ diff --git a/images/gptactions_Gmail_clientidsecret.png b/images/gptactions_Gmail_clientidsecret.png new file mode 100644 index 00000000..86c4fd28 Binary files /dev/null and b/images/gptactions_Gmail_clientidsecret.png differ diff --git a/images/gptactions_Gmail_enableAPIs.png b/images/gptactions_Gmail_enableAPIs.png new file mode 100644 index 00000000..eea4877f Binary files /dev/null and b/images/gptactions_Gmail_enableAPIs.png differ diff --git a/images/gptactions_Gmail_gmailApiTile.png b/images/gptactions_Gmail_gmailApiTile.png new file mode 100644 index 00000000..92e32881 Binary files /dev/null and b/images/gptactions_Gmail_gmailApiTile.png differ diff --git a/registry.yaml b/registry.yaml index ea5ede29..86bdfe12 100644 --- a/registry.yaml +++ b/registry.yaml @@ -1416,4 +1416,12 @@ tags: - gpt-actions-library - chatgpt - \ No newline at end of file + +- title: GPT Actions library - Gmail + path: examples/chatgpt/gpt_actions_library/gpt_action_gmail.ipynb + date: 2024-07-24 + authors: + - alwestmo-openai + tags: + - gpt-actions-library + - chatgpt \ No newline at end of file