本页面为开发者提供构建特定应用GPT Action的说明与指南。在继续之前,请确保您已熟悉以下信息:
本指南详细介绍了如何将chatGPT与Box.com账户连接,GPT需要执行两个操作才能从Box获取数据。GPT将直接与Box API交互,但需要中间件(如Azure函数)来正确格式化Box的响应以下载和读取文件内容。azure函数操作对最终用户是透明的,意味着用户无需显式调用该操作。
- 操作1:Box API操作 - 利用Box API从Box查询数据
- 操作2:Azure函数 - 格式化来自Box的响应,使chatGPT能够直接从Box下载文件
价值与示例商业应用场景
现有Box客户可以利用这些指南查询文件详情、文件内容及相关元数据。这支持通过OpenAI对Box中存储的任何内容进行分析,例如可视化数据集和跨多个文件夹及文件创建摘要。该GPT可以访问Box中的文件夹、文件及业务流程数据(如元数据)。此外,Box管理员可使用此GPT操作查看审计追踪和运行状况检查。
应用信息
应用密钥链接
在开始之前,请查看Box和Azure提供的这些链接:
盒子操作
- 应用网站: https://app.box.com
- 应用API文档:https://developer.box.com/reference/
Azure 函数
应用前提条件
在开始之前,请确保您已在Box环境中完成以下步骤:
- 这需要一个Box开发者账户才能开始使用:https://developer.box.com/
- 按照Box开发者网站的指引,创建一个使用OAuth 2.0认证类型的自定义应用:https://developer.box.com/guides/getting-started/first-application/
- Navigate to Configuration tab for the following values
- OAuth 2.0 凭证(客户端ID / 客户端密钥)在配置chatGPT时需要同时提供这两个值
- OAuth 2.0 重定向URI:您将在下方的chatGPT操作配置中填写此值
- 应用范围 (读取Box中的所有文件和文件夹, 管理企业属性)
请保持此窗口开启,Redirect URIs需要从gpt配置中填写。

中间件信息:Action 2所需
确保在您的Azure环境中完成以下步骤:
- 可创建 Azure Function Apps 和 Azure Entra 应用注册的 Azure 门户
- 本指南中有一个详细章节,介绍了部署和设计所需函数的相关内容,该函数用于封装Box的响应以便查看文件内容。如果没有此函数,GPT将只能查询文件的相关数据而无法获取文件内容。请务必在创建第一个操作后阅读此章节。
ChatGPT 步骤
自定义GPT指令
创建自定义GPT后,请将以下文本复制到指令面板中。有问题吗?查看入门示例详细了解此步骤的操作方法。
**context**
This GPT will connect to your Box.com account to search files and folders, providing accurate and helpful responses based on the user's queries. It will assist with finding, organizing, and retrieving information stored in Box.com. Ensure secure and private handling of any accessed data. Avoid performing any actions that could modify or delete files unless explicitly instructed. Prioritize clarity and efficiency in responses. Use simple language for ease of understanding. Ask for clarification if a request is ambiguous or if additional details are needed to perform a search. Maintain a professional and friendly tone, ensuring users feel comfortable and supported.
Please use this website for instructions using the box API : https://developer.box.com/reference/ each endpoint can be found from this reference documentation
Users can search with the Box search endpoint or Box metadata search endpoint
**instructions**
When retrieving file information from Box provide as much details as possible and format into a table when more than one file is returned, include the modified date, created date and any other headers you might find valuable
Provide insights to files and suggest patterns for users, gives example queries and suggestions when appropriate
When a user wants to compare files retrieve the file for the user with out asking操作 1 : Box API 操作
创建自定义GPT后,您需要设置2个操作。将以下文本复制到第一个操作面板中,这将用于Box操作。有疑问吗?查看入门示例了解此步骤的详细运作方式。
{
"openapi": "3.1.0",
"info": {
"title": "Box.com API",
"description": "API for Box.com services",
"version": "v1.0.0"
},
"servers": [
{
"url": "https://api.box.com/2.0"
}
],
"paths": {
"/folders/{folder_id}": {
"get": {
"summary": "Get Folder Items",
"operationId": "getFolderItems",
"parameters": [
{
"name": "folder_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "The ID of the folder"
}
],
"responses": {
"200": {
"description": "A list of items in the folder",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FolderItems"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:folders"
]
}
]
}
},
"/files/{file_id}": {
"get": {
"summary": "Get File Information",
"operationId": "getFileInfo",
"parameters": [
{
"name": "file_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "The ID of the file"
}
],
"responses": {
"200": {
"description": "File information",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FileInfo"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:files"
]
}
]
}
},
"/folders": {
"get": {
"summary": "List All Folders",
"operationId": "listAllFolders",
"responses": {
"200": {
"description": "A list of all folders",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FoldersList"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:folders"
]
}
]
}
},
"/events": {
"get": {
"summary": "Get User Events",
"operationId": "getUserEvents",
"parameters": [
{
"name": "stream_type",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"description": "The type of stream"
}
],
"responses": {
"200": {
"description": "User events",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserEvents"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:events"
]
}
]
}
},
"/admin_events": {
"get": {
"summary": "Get Admin Events",
"operationId": "getAdminEvents",
"responses": {
"200": {
"description": "Admin events",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AdminEvents"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:events"
]
}
]
}
},
"/search": {
"get": {
"summary": "Search",
"operationId": "search",
"parameters": [
{
"name": "query",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"description": "Search query"
}
],
"responses": {
"200": {
"description": "Search results",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchResults"
}
}
}
}
},
"security": [
{
"OAuth2": [
"search:items"
]
}
]
}
},
"/metadata_templates": {
"get": {
"summary": "Get Metadata Templates",
"operationId": "getMetadataTemplates",
"responses": {
"200": {
"description": "Metadata templates",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MetadataTemplates"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:metadata_templates"
]
}
]
}
},
"/metadata_templates/enterprise": {
"get": {
"summary": "Get Enterprise Metadata Templates",
"operationId": "getEnterpriseMetadataTemplates",
"responses": {
"200": {
"description": "Enterprise metadata templates",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MetadataTemplates"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:metadata_templates"
]
}
]
}
},
"/files/{file_id}/metadata": {
"get": {
"summary": "Get All Metadata for a File",
"operationId": "getAllMetadataForFile",
"parameters": [
{
"name": "file_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "The ID of the file"
}
],
"responses": {
"200": {
"description": "All metadata instances for the file",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MetadataInstances"
}
}
}
}
},
"security": [
{
"OAuth2": [
"read:metadata"
]
}
]
}
}
},
"components": {
"schemas": {
"FolderItems": {
"type": "object",
"properties": {
"total_count": {
"type": "integer",
"description": "The total number of items in the folder"
},
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of the item (e.g., file, folder)"
},
"id": {
"type": "string",
"description": "The ID of the item"
},
"name": {
"type": "string",
"description": "The name of the item"
}
}
}
}
}
},
"FileInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The ID of the file"
},
"name": {
"type": "string",
"description": "The name of the file"
},
"size": {
"type": "integer",
"description": "The size of the file in bytes"
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "The creation time of the file"
},
"modified_at": {
"type": "string",
"format": "date-time",
"description": "The last modification time of the file"
}
}
},
"FoldersList": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The ID of the folder"
},
"name": {
"type": "string",
"description": "The name of the folder"
}
}
}
},
"UserEvents": {
"type": "object",
"properties": {
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"event_id": {
"type": "string",
"description": "The ID of the event"
},
"event_type": {
"type": "string",
"description": "The type of the event"
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "The time the event occurred"
}
}
}
}
}
},
"AdminEvents": {
"type": "object",
"properties": {
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"event_id": {
"type": "string",
"description": "The ID of the event"
},
"event_type": {
"type": "string",
"description": "The type of the event"
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "The time the event occurred"
}
}
}
}
}
},
"SearchResults": {
"type": "object",
"properties": {
"total_count": {
"type": "integer",
"description": "The total number of search results"
},
"entries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of the item (e.g., file, folder)"
},
"id": {
"type": "string",
"description": "The ID of the item"
},
"name": {
"type": "string",
"description": "The name of the item"
}
}
}
}
}
},
"MetadataTemplates": {
"type": "array",
"items": {
"type": "object",
"properties": {
"templateKey": {
"type": "string",
"description": "The key of the metadata template"
},
"displayName": {
"type": "string",
"description": "The display name of the metadata template"
},
"scope": {
"type": "string",
"description": "The scope of the metadata template"
}
}
}
},
"MetadataInstances": {
"type": "array",
"items": {
"type": "object",
"properties": {
"templateKey": {
"type": "string",
"description": "The key of the metadata template"
},
"type": {
"type": "string",
"description": "The type of the metadata instance"
},
"attributes": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Attributes of the metadata instance"
}
}
}
}
},
"securitySchemes": {
"OAuth2": {
"type": "oauth2",
"flows": {
"authorizationCode": {
"authorizationUrl": "https://account.box.com/api/oauth2/authorize",
"tokenUrl": "https://api.box.com/oauth2/token",
"scopes": {
"read:folders": "Read folders",
"read:files": "Read files",
"search:items": "Search items",
"read:metadata": "Read metadata",
"read:metadata_templates": "Read metadata templates",
"read:events": "Read events"
}
}
}
}
}
}
}注意:上述架构并未包含所有可能的API端点,请务必根据Box开发者文档编辑架构以生成适当的操作
认证说明
以下是设置与这个第三方应用程序进行身份验证的说明。有问题吗?查看入门示例以更详细地了解此步骤的工作原理。
在ChatGPT中
在ChatGPT中,点击"认证"并选择OAuth

OAuth 连接
- 客户端ID - 来自您之前创建的Box自定义应用的值
- 客户端密钥 - 来自您之前创建的Box自定义应用的值
- 授权URL - : https://account.box.com/api/oauth2/authorize?response_type=code&client_id=[client ID from above]&redirect_uri=[暂时使用类似chat.openai.com/aip//oauth/callback的占位符,稍后在ChatGPT中创建Action时再更新]
- 令牌URL : https:api.box.com/oauth2/token
You need to save the configuration and navigate back to the gpt Configuration tab to copy the Callback URL, edit the configuration for the Box action Authorization URL and format the URL as https://account.box.com/api/oauth2/authorize?response_type=code&client_id=[client_ID]&redirect_uri=[callBack URL]
后续操作步骤
更新Box.com自定义应用
- 从gpt复制回调URL,并在Box.com中添加OAuth 2.0重定向URI

操作2 : Azure Function
既然我们已经创建了GPT并完成了对Box.com的认证,现在可以创建azure函数来处理响应格式,使GPT能够从Box下载文件。
有关部署Azure函数的更多详细信息,请遵循此Azure Cookbook指南。下方您将找到可添加到函数中的示例代码。
这段代码旨在提供方向性指导 - 虽然它应该可以直接使用,但其设计初衷是让您根据需求进行定制。
数据流

现在您已经创建了azure函数,请添加以下示例代码:
function_app.py
import azure.functions as func
from boxsdk import Client, JWTAuth
import requests
import base64
import json
import jwt
import logging
app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
@app.route(route="box_retrieval")
def box_retrieval(req: func.HttpRequest) -> func.HttpResponse:
logger.info('Starting box_retrieval function')
file_ids = req.params.get('file_ids')
auth_header = req.headers.get('Authorization')
if not file_ids or not auth_header:
logger.error('Missing file_ids or Authorization header')
return func.HttpResponse(
"Missing file_id or Authorization header.",
status_code=400
)
file_ids = file_ids.split(",") # Assuming file_ids are passed as a comma-separated string
if len(file_ids) == 0 or len(file_ids) > 10:
logger.error('file_ids list is empty or contains more than 10 IDs')
return func.HttpResponse(
"file_ids list is empty or contains more than 10 IDs.",
status_code=400
)
try:
# Decode JWT to extract the email
token = auth_header.split(" ")[1]
decoded_token = jwt.decode(token, options={"verify_signature": False})
upn = decoded_token['upn']
user_email = get_user_mapping(upn)
logger.info(f'User email extracted: {user_email}')
config = JWTAuth.from_settings_file('jwt_config.json')
sdk = Client(config)
logger.info('Authenticated with Box API')
# Use the user email to get the user ID
users = sdk.users(filter_term=user_email)
user = next(users)
user_id = user.id
logger.info(f'User ID obtained: {user_id}')
openai_file_responses = []
for file_id in file_ids:
# Perform as_user call to get the file representation
my_file = sdk.as_user(user).file(file_id).get()
file_url = my_file.get_download_url()
openai_file_responses.append(file_url)
response_body = json.dumps({'openaiFileResponse': openai_file_responses})
return func.HttpResponse(
response_body,
status_code=200,
mimetype="application/json"
)
except Exception as e:
return func.HttpResponse(
f"An error occurred: {str(e)}",
status_code=500
)
def get_user_mapping(upn):
# In our case, the user's authentication email into Azure AD is the same as their email in Box
# If that is not the case, map the email in Box to the email in Azure AD
return upnjwt_config.json.sample
{
"boxAppSettings": {
"clientID": "12345",
"clientSecret": "abcde",
"appAuth": {
"publicKeyID": "123",
"privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\nvwxyz==\n-----END ENCRYPTED PRIVATE KEY-----\n",
"passphrase": "lmnop"
}
},
"enterpriseID": "09876"
}requirements.txt
boxsdk[jwt]
azure-functions
requests
pyjwt请确保按照Azure指南的其余部分完成身份验证后的步骤及chatGPT配置:Azure Cookbook Guide
常见问题与故障排除
- Schema调用了错误的项目或数据集: 如果ChatGPT调用了错误的项目或数据集,建议更新您的指令,使其更明确地指出(a)应该调用哪个项目/数据集,或者(b)要求在运行查询前用户必须提供这些确切细节
- Box可能会在事件流中返回大量数据,这可能导致错误,
是否有您希望我们优先考虑的集成方案?我们的集成是否存在错误?请在GitHub上提交PR或问题,我们会尽快查看。