GPT 操作库:Salesforce + Gong
简介
本页面为开发者提供了构建连接到特定应用程序的 GPT 操作的说明和指南。在继续之前,请确保您已熟悉以下信息:
此特定的 GPT 操作概述了如何构建一个从 Salesforce 和 Gong 检索信息的 GPT。这将包括创建多个自定义操作,这些操作已在现有的 cookbook 中进行了记录。我们将在下一节中重点介绍这些 cookbook。
价值 + 示例业务用例
价值:用户现在可以利用 ChatGPT 的功能来:
- 连接到 Salesforce
- 搜索客户账户
- 从 Gong 检索先前的通话记录
示例用例:
一位销售代表正在为即将举行的客户会议做准备。通过此集成,他们可以快速从 Salesforce 中检索相关的账户详细信息,访问最近的 Gong 通话记录,并获得围绕经过验证的销售方法(如 MEDPICC 或 SPICED)构建的 AI 生成的摘要和见解。这使代表能够清晰、可操作地了解客户的当前状态和后续步骤——所有这些都在几分钟内完成。
应用程序信息
在此示例中,我们将连接到 Salesforce 和 Gong(通过中间件)。我们将引用现有的 cookbook 来获取 Salesforce 的基本设置和身份验证说明,以及创建中间件。
Salesforce GPT 操作
请参阅我们关于为 Salesforce 设置 GPT 操作的 cookbook。在该 cookbook 中需要注意的两个设置是:
- 应用程序信息 - 这涵盖了 Salesforce 中需要熟悉的必要概念
- 身份验证说明 - 这涵盖了在 Salesforce 中创建已连接的应用程序以及配置 OAuth(在 Salesforce 和 ChatGPT 上)
中间件 GPT 操作
请参阅我们关于创建中间件的任何一个 cookbook:
应用程序先决条件
除了上述 cookbook 中的先决条件外,请确保您能够访问 Gong API 密钥。
应用程序设置
部署无服务器函数
此无服务器函数将接受一个 callIds
数组,从 Gong 获取记录,并清理发送到 ChatGPT 的响应。以下是 Azure Functions(Javascript)上的示例:
const { app } = require('@azure/functions');
const axios = require('axios');
// 替换为您的 Gong API 令牌
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: "请在 'callIds' 数组中提供通话 ID。"
};
}
// 获取通话记录
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;
// 获取详细的通话信息
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;
// 创建一个包含元数据和说话者详细信息的通话 ID 映射
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;
});
});
// 将记录数据转换为内容并包含元数据
transcriptData.callTranscripts.forEach(call => {
const meta = callMetaMap[call.callId];
if (!meta) {
throw new Error(`未找到 callId ${call.callId} 的元数据。`);
}
let content = '';
call.transcript.forEach(segment => {
const speakerName = meta.speakers[segment.speakerId] || "未知说话者";
// 将说话者的所有句子合并为一个段落
const sentences = segment.sentences.map(sentence => sentence.text).join(' ');
content += `${speakerName}: ${sentences}\n\n`; // 在说话者回合之间添加换行符
});
// 将元数据和内容添加到通话对象
call.title = meta.title;
call.started = meta.started;
call.duration = meta.duration;
call.url = meta.url;
call.content = content;
delete call.transcript;
});
// 返回修改后的记录数据
return {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(transcriptData)
};
} catch (error) {
context.log('[ERROR]', "处理请求时出错:", error);
return {
status: error.response?.status || 500,
body: {
message: "获取或处理通话数据时出错。",
details: error.response?.data || error.message
}
};
}
}
});
以下是您将在 package.json
文件中包含的依赖项:
"dependencies": {
"@azure/functions": "^4.0.0",
"axios": "^1.7.7"
}
ChatGPT 步骤
自定义 GPT 说明
创建自定义 GPT 后,请将以下文本复制到“说明”面板中。有疑问吗?请查看 入门示例,了解此步骤的详细信息。
# 触发器
用户输入他们想准备的账户名称
# 步骤
1. 检索账户名称 - 调用 `executeSOSLSearch` 自定义操作,使用 SOSL 搜索具有该名称的 Salesforce 账户。检索最多 5 个账户。查询应如下所示 - `FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name) LIMIT 5`
2. 以此格式显示账户 - `账户名称 - salesforceID`。询问用户他们感兴趣的账户。
3. 获取账户的 Gong 通话 ID - 对于已确认的账户,调用 `executeSOQLQuery` 以获取所有 Gong 通话 ID。它应如下所示 - `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. 将 callIds 传递给 `getTranscriptsByCallIds `
# 触发器
用户说“总结通话”
# 步骤
使用通话记录并提供以下输出
## 账户名称
打印出账户名称
## 通话详情
> 请在此表格格式中列出您检索了通话记录的通话,以及它们的日期和与会者:
>> 表头:<通话标题>, <日期>, <与会者>, <Gong URL>
## 推荐的会议焦点领域:
> 分析通话记录以识别主题、挑战和机遇。基于此,生成一份关于下次会议推荐焦点领域的列表。这些应是可操作的,并且针对客户的需求。解释为什么每一项都应该是会议的焦点。
对于以下每一项见解,请指定您从中获取见解的通话和日期:
### 指标
客户试图实现的量化结果。这些可能是成本降低、收入增加、用户增长、效率提升等。查找提到的 KPI 或成功指标。
### 经济买家
确定是否提到了真正的经济决策者或是否涉及他们。这包括职位、姓名或关于预算所有权或最终决策权的提示。
### 决策标准
客户将用于评估解决方案的关键因素是什么?这些可能包括价格、性能、支持、集成、易用性等。
### 决策流程
描述客户计划如何做出购买决定:阶段、涉及的利益相关者、批准流程、时间表。
### 文件流程
捕获任何提及的与法律、采购、合规或合同相关的步骤和时间表。
### 识别痛点
突出客户面临的核心业务挑战,最好用他们自己的话来说。了解是什么驱动了紧迫性。
### 拥护者
内部是否有人在倡导我们的解决方案?提及姓名、角色或表明支持的举止(例如,“我正在内部推动此事”)。
### (可选)竞争
提及讨论过的任何竞争对手、内部构建或替代解决方案。
在上面的示例中,请替换查询(3)以从您的自定义 Salesforce 对象中检索 Gong 通话 ID。
您现在将创建 2 个单独的操作 - 一个用于连接到 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: true
Salesforce 自定义操作的身份验证说明
请遵循 GPT 操作库 - Salesforce 中显示的步骤。
连接到 Gong 的中间件的 OpenAPI 架构
在此示例中,我们将为调用 Gong API 的 Azure Function 进行设置。请将 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 或 issue,我们会进行查看。