简介
本页面为开发者提供构建中间件以将GPT Action连接到特定应用程序的说明与指南。在继续之前,请确保您已熟悉以下信息:
这个特定的GPT操作概述了如何构建一个能从Salesforce和Gong检索信息的GPT。这将包括创建多个自定义操作,这些操作在现有的操作指南中已有记录。我们将在下一节重点介绍这些操作指南。
价值与示例商业应用场景
价值: 用户现在可以利用ChatGPT的能力来:
- 连接到Salesforce
- 搜索客户账户
- 从之前的通话记录中检索Gong转录文本
示例用例:
一位销售代表正在为即将到来的客户会议做准备。通过此集成,他们可以快速从Salesforce检索相关客户详细信息,访问最近的Gong通话记录,并获取围绕MEDPICC或SPICED等成熟销售方法论构建的AI生成摘要和洞察。这使销售代表能在几分钟内清晰、可操作地了解客户当前状态和后续步骤。
应用信息
在这个示例中,我们将连接Salesforce和Gong(通过中间件)。我们将参考现有的操作手册来获取Salesforce的基本设置和认证说明,以及创建中间件的指南。
Salesforce GPT Action
请参考我们关于为Salesforce设置GPT Action的指南。在该指南中需要特别注意的两项设置是:
- Application Information - 这部分涵盖了需要熟悉的Salesforce相关核心概念
- Authentication Instructions - 这部分内容涵盖在Salesforce中创建Connected App以及在Salesforce和ChatGPT两端配置OAuth
中间件GPT操作
请参考我们关于创建中间件的任何一本指南:
应用前提条件
除了上述指南中的先决条件外,请确保您拥有Gong API密钥的访问权限
应用设置
部署无服务器函数
该无服务器函数将接收一个callIds数组,从Gong获取转录文本,并清理发送给ChatGPT的响应。以下是它在Azure Functions(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
}
};
}
}
});
以下是您需要在package.json文件中包含的依赖项
"dependencies": {
"@azure/functions": "^4.0.0",
"axios": "^1.7.7"
}ChatGPT 步骤
自定义GPT指令
创建自定义GPT后,请将以下文本复制到指令面板中。有问题吗?查看入门示例详细了解此步骤的操作方法。
# 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 = '<AccountId>'
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: <Title of Call>, <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.在上面的示例中,将(3)中的查询替换为从您的自定义Salesforce对象中检索Gong通话ID。
你现在需要创建两个独立的操作 - 一个用于连接Salesforce,另一个用于连接调用Gong API的中间件
Salesforce自定义操作的OpenAPI模式
创建自定义GPT后,在操作面板中复制以下文本。有问题吗?查看入门示例了解此步骤的详细操作方式。
以下是连接到Salesforce的示例。您需要在此部分插入您的URL。
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: trueSalesforce自定义操作的身份验证说明
请按照GPT Actions库 - Salesforce中显示的步骤操作
连接至Gong的中间件OpenAPI架构
在这个示例中,我们正在为调用Gong API的Azure函数进行设置。请将url替换为您自己的中间件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.是否有您希望我们优先考虑的集成方案?我们的集成是否存在错误?请在GitHub上提交PR或问题,我们会尽快查看。