From fc24b1c2b14bbf6ff4849f26c8e2f88bf2e59280 Mon Sep 17 00:00:00 2001 From: Girish D Date: Thu, 10 Apr 2025 05:23:31 -0700 Subject: [PATCH] Gpt action salesforce gong (#1761) Co-authored-by: pap --- .../gpt_action_salesforce_gong.md | 446 ++++++++++++++++++ registry.yaml | 10 + 2 files changed, 456 insertions(+) create mode 100644 examples/chatgpt/gpt_actions_library/gpt_action_salesforce_gong.md diff --git a/examples/chatgpt/gpt_actions_library/gpt_action_salesforce_gong.md b/examples/chatgpt/gpt_actions_library/gpt_action_salesforce_gong.md new file mode 100644 index 0000000..faf3827 --- /dev/null +++ b/examples/chatgpt/gpt_actions_library/gpt_action_salesforce_gong.md @@ -0,0 +1,446 @@ +# GPT Action Library: Salesforce + Gong + +## Introduction + +This page provides an instruction & guide for developers building middleware to connect a GPT Action to a specific application. Before you proceed, make sure to first familiarize yourself with the following information: + +- [Introduction to GPT Actions](https://platform.openai.com/docs/actions) +- [Introduction to GPT Actions Library](https://platform.openai.com/docs/actions/actions-library) +- [Example of Building a GPT Action from Scratch](https://platform.openai.com/docs/actions/getting-started) + +This particular GPT Action provides an overview of how to build a GPT that retrieves information from Salesforce and Gong. This will include creating multiple custom actions which are documented in existing cookbooks. We will highlight these cookbooks in the next section. + +### Value + Example Business Use Cases + +**Value**: Users can now leverage ChatGPT's capabilities to: + +- Connect to Salesforce +- Search for customer accounts +- Retrieve Gong transcripts from previous calls + +**Example Use Cases**: + +A sales rep is preparing for an upcoming customer meeting. Using this integration, they can quickly retrieve relevant account details from Salesforce, access recent Gong call transcripts, and receive AI-generated summaries and insights structured around proven sales methodologies like MEDPICC or SPICED. This empowers the rep with a clear, actionable understanding of the customer's current state and next steps — all in minutes + +## Application Information +In this example, we are connecting to Salesforce and Gong (via a middleware). We are going to refer to existing cookbooks for basic setup and authentication instructions for Salesforce and creating a middleware. + +### Salesforce GPT Action + +Refer to our cookbook on setting up a GPT Action for Salesforce. The two settings to pay attention to in that cookbook are: + +- [Application Information](https://cookbook.openai.com/examples/chatgpt/gpt_actions_library/gpt_action_salesforce#application-information) - this covers the necessary concepts to be familiar with in Salesforce +- [Authentication Instructions](https://cookbook.openai.com/examples/chatgpt/gpt_actions_library/gpt_action_salesforce#authentication-instructions) - this covers creating a Connected App in Salesforce and configuring OAuth (on both Salesforce and ChatGPT) + +### Middleware GPT Action +Refer to any one of our cookbooks on creating a middleware: + +- [GPT Actions library (Middleware) - AWS](https://cookbook.openai.com/examples/chatgpt/gpt_actions_library/gpt_middleware_aws_function) +- [GPT Actions library (Middleware) - Azure Functions](https://cookbook.openai.com/examples/chatgpt/gpt_actions_library/gpt_middleware_azure_function) +- [GPT Actions library (Middleware) - Google Cloud Function](https://cookbook.openai.com/examples/chatgpt/gpt_actions_library/gpt_middleware_google_cloud_function) + +### Application Prerequisites + +In addition to the prerequisites in the cookbooks above, please ensure that you have access to a Gong API key + +## Application Setup + +### Deploying a serverless function + +This serverless function will accept an array of `callIds`, fetch the transcripts from Gong and clean up the response that it sends to ChatGPT. Here is an example of what it looks like on Azure Functions (Javascript) + +```javascript +const { app } = require('@azure/functions'); +const axios = require('axios'); + +// Replace with your Gong API token +const GONG_API_BASE_URL = "https://api.gong.io/v2"; +const GONG_API_KEY = process.env.GONG_API_KEY; + +app.http('callTranscripts', { + methods: ['POST'], + authLevel: 'function', + handler: async (request, context) => { + try { + const body = await request.json(); + const callIds = body.callIds; + + if (!Array.isArray(callIds) || callIds.length === 0) { + return { + status: 400, + body: "Please provide call IDs in the 'callIds' array." + }; + } + + // Fetch call transcripts + const transcriptPayload = { filter: { callIds } }; + const transcriptResponse = await axios.post(`${GONG_API_BASE_URL}/calls/transcript`, transcriptPayload, { + headers: { + 'Authorization': `Basic ${GONG_API_KEY}`, + 'Content-Type': 'application/json' + } + }); + + const transcriptData = transcriptResponse.data; + + // Fetch extensive call details + const extensivePayload = { + filter: { callIds }, + contentSelector: { + exposedFields: { parties: true } + } + }; + + const extensiveResponse = await axios.post(`${GONG_API_BASE_URL}/calls/extensive`, extensivePayload, { + headers: { + 'Authorization': `Basic ${GONG_API_KEY}`, + 'Content-Type': 'application/json' + } + }); + + const extensiveData = extensiveResponse.data; + + // Create a map of call IDs to metadata and speaker details + const callMetaMap = {}; + extensiveData.calls.forEach(call => { + callMetaMap[call.metaData.id] = { + title: call.metaData.title, + started: call.metaData.started, + duration: call.metaData.duration, + url: call.metaData.url, + speakers: {} + }; + + call.parties.forEach(party => { + callMetaMap[call.metaData.id].speakers[party.speakerId] = party.name; + }); + }); + + // Transform transcript data into content and include metadata + transcriptData.callTranscripts.forEach(call => { + const meta = callMetaMap[call.callId]; + if (!meta) { + throw new Error(`Metadata for callId ${call.callId} not found.`); + } + + let content = ''; + call.transcript.forEach(segment => { + const speakerName = meta.speakers[segment.speakerId] || "Unknown Speaker"; + + // Combine all sentences for the speaker into a paragraph + const sentences = segment.sentences.map(sentence => sentence.text).join(' '); + content += `${speakerName}: ${sentences}\n\n`; // Add a newline between speaker turns + }); + + // Add metadata and content to the call object + call.title = meta.title; + call.started = meta.started; + call.duration = meta.duration; + call.url = meta.url; + call.content = content; + + delete call.transcript; + }); + + // Return the modified transcript data + return { + status: 200, + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(transcriptData) + }; + } catch (error) { + context.log('[ERROR]', "Error processing request:", error); + + return { + status: error.response?.status || 500, + body: { + message: "An error occurred while fetching or processing call data.", + details: error.response?.data || error.message + } + }; + } + } +}); + +``` + +Here are the dependencies that you would include in your `package.json` file + +```javascript +"dependencies": { + "@azure/functions": "^4.0.0", + "axios": "^1.7.7" + } +``` + +## ChatGPT Steps + +### Custom GPT Instructions + +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. + +``` +# Trigger +User enters the name of an account that they want to prepare for + +# Steps +1. Retrieve Account Names - Make a call to the `executeSOSLSearch` custom action searching for a Salesforce Account with that name (SOSL). Retrieve up to 5 accounts. This is what the query should look like - `FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name) LIMIT 5` + +2. Show the accounts in this format - `Account Name - salesforceID`. Ask the user to confirm which account they are interested in. + +3. Get Gong Call IDs for the account - For the confirmed account, make a call to `executeSOQLQuery` to get all the Gong Call IDs. It should look like this - `SELECT XXX, YYY, ZZZ +FROM Gong__Gong_Call__c +WHERE Gong__Primary_Account__c = '' +ORDER BY Gong__Call_Start__c DESC +LIMIT 2 +` + +4. Pass in the callIds to `getTranscriptsByCallIds ` + +# Trigger +User says "Summarize call" + +# Steps + +Use both the transcripts and provide the following output + +## Account Name +Print out the account name + +## Details of calls +>Please list the calls for which you retrieved the transcripts along with their dates and attendees in this table format: +>>Headers: , <Date>, <Attendees>, <Gong URL> + +## Recommended Meeting Focus Areas: +>Analyze the transcripts to identify themes, challenges, and opportunities. Based on this, generate a list of recommended focus areas for the next meeting. These should be actionable and specific to the client’s needs. Explain **why** each item should be a meeting focus. + +For each of the following insights, specify **which call and date** you sourced the insight from: + +### Metrics +Quantifiable outcomes the customer is trying to achieve. These could be cost reduction, increased revenue, user growth, efficiency gains, etc. Look for KPIs or success measures mentioned. + +### Economic Buyer +Identify if the true economic decision-maker was mentioned or involved. This includes titles, names, or hints at budget ownership or final authority. + +### Decision Criteria +What are the key factors the customer will use to evaluate solutions? These could include price, performance, support, integrations, ease of use, etc. + +### Decision Process +Describe how the customer plans to make the buying decision: stages, stakeholders involved, approval processes, timelines. + +### Paper Process +Any mention of legal, procurement, compliance, or contract-related steps and timelines should be captured here. + +### Identify Pain +Highlight the core business challenges the customer is facing, ideally in their own words. Understand what’s driving urgency. + +### Champion +Is there someone internally who is championing our solution? Mention names, roles, or behaviors that indicate advocacy (e.g., “I’m pushing this internally”). + +### (Optional) Competition +Mention any competing vendors, internal builds, or alternative solutions discussed. +``` +In the above example, replace the query in (3) to retrieves the Gong Call IDs from your custom Salesforce object. + +You will now create 2 separate actions - one to connect to Salesforce and the other to connect to the middleware that calls the Gong APIs + +### OpenAPI Schema for Salesforce custom action + +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. + +Below is an example of what connecting to Salesforce might look like. You'll need to insert your URL in this section. + +```javascript +openapi: 3.1.0 +info: + title: Salesforce API + version: 1.0.0 + description: API for accessing Salesforce sObjects and executing queries. +servers: + - url: https://<subdomain>.my.salesforce.com/services/data/v59.0 + description: Salesforce API server +paths: + /query: + get: + summary: Execute a SOQL Query + description: Executes a given SOQL query and returns the results. + operationId: executeSOQLQuery + parameters: + - name: q + in: query + description: The SOQL query string to be executed. + required: true + schema: + type: string + responses: + '200': + description: Query executed successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/QueryResult' + + /search: + get: + summary: Execute a SOSL Search + description: Executes a SOSL search based on the given query and returns matching records. + operationId: executeSOSLSearch + parameters: + - name: q + in: query + description: The SOSL search string (e.g., 'FIND {Acme}'). + required: true + schema: + type: string + responses: + '200': + description: Search executed successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/SearchResult' + +components: + schemas: + QueryResult: + type: object + description: Result of a SOQL query. + properties: + totalSize: + type: integer + description: The total number of records matching the query. + done: + type: boolean + description: Indicates if the query result includes all records. + records: + type: array + description: The list of records returned by the query. + items: + $ref: '#/components/schemas/SObject' + + SearchResult: + type: object + description: Result of a SOSL search. + properties: + searchRecords: + type: array + description: The list of records matching the search query. + items: + $ref: '#/components/schemas/SObject' + + SObject: + type: object + description: A Salesforce sObject, which represents a database table record. + properties: + attributes: + type: object + description: Metadata about the sObject, such as type and URL. + properties: + type: + type: string + description: The sObject type. + url: + type: string + description: The URL of the record. + Id: + type: string + description: The unique identifier for the sObject. + additionalProperties: true +``` + +### Authentication instructions for Salesforce custom actions +Please follow the steps shown in [GPT Actions library - Salesforce](https://cookbook.openai.com/examples/chatgpt/gpt_actions_library/gpt_action_salesforce#in-chatgpt) + +### OpenAPI Schema for the middleware that connects to Gong +In this example, we are setting this up for an Azure Function that calls the Gong APIs. Replace `url` with your own Middleware URL + +``` +openapi: 3.1.0 +info: + title: Call Transcripts API + description: API to retrieve call transcripts and associated metadata by specific call IDs. + version: 1.0.1 +servers: + - url: https://<subdomain>.azurewebsites.net/api + description: Production server +paths: + /callTranscripts: + post: + operationId: getTranscriptsByCallIds + x-openai-isConsequential: false + summary: Retrieve call transcripts by call IDs + description: Fetches specific call transcripts based on the provided call IDs in the request body. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + callIds: + type: array + description: List of call IDs for which transcripts need to be fetched. + items: + type: string + required: + - callIds + responses: + '200': + description: A successful response containing the requested call transcripts and metadata. + content: + application/json: + schema: + type: object + properties: + requestId: + type: string + description: Unique request identifier. + records: + type: object + description: Metadata about the pagination. + properties: + totalRecords: + type: integer + description: Total number of records available. + currentPageSize: + type: integer + description: Number of records in the current page. + currentPageNumber: + type: integer + description: The current page number. + callTranscripts: + type: array + description: List of call transcripts. + items: + type: object + properties: + callId: + type: string + description: Unique identifier for the call. + title: + type: string + description: Title of the call or meeting. + started: + type: string + format: date-time + description: Timestamp when the call started. + duration: + type: integer + description: Duration of the call in seconds. + url: + type: string + format: uri + description: URL to access the call recording or details. + content: + type: string + description: Transcript content of the call. + '400': + description: Invalid request. Possibly due to missing or invalid `callIds` parameter. + '401': + description: Unauthorized access due to invalid or missing API key. + '500': + description: Internal server error. +``` + + +*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.* diff --git a/registry.yaml b/registry.yaml index 5659818..70a0cdd 100644 --- a/registry.yaml +++ b/registry.yaml @@ -1895,3 +1895,13 @@ - audio - speech +- title: GPT Actions library - Salesforce & Gong + path: examples/chatgpt/gpt_actions_library/gpt_action_salesforce_gong.md + date: 2025-04-07 + authors: + - girishd + tags: + - chatgpt + - gpt-actions-library + - chatgpt-productivity +