@bpinternal/integration-hub
反应 UI 组件和可选的 Botpress 运行时钩用于构建集成枢纽体验.
使用此软件包的两种方式
仅UI(@bpinternal/integration-hub(中文(简体) )
您提供自己的数据并给自己的API打电话。 软件包会给你布局组件,卡片,网格,过滤器,以及设置向导外壳. 当您有非Botpress后端或想要完全控制数据获取时使用此功能 .
所需对等方 : react, (中文(简体) ), react-dom, (中文(简体) ), framer-motion, (中文(简体) ), @base-ui/react, (中文(简体) ), clsx, (中文(简体) ), tailwind-merge, (中文(简体) ), lucide-react
UI + Botpress 运行时间(@bpinternal/integration-hub/runtime(中文(简体) )
你通过一个 @botpress/client 实例和软件包处理获取集成,将数据映射到UI类型,以及执行安装/uninstall/enable/disable 突变。 当您的应用程序已经和 Botpress API 说话时使用此选项 .
其它同伴 : @botpress/client, (中文(简体) ), @tanstack/react-query
@botpress/client财务报告和审定财务报表@tanstack/react-query标记为可选的同伴依赖关系。 只有在从./runtime. 仅使用UI的消费者不需要安装.
快开始
安装
pnpm add @bpinternal/integration-hub react react-dom framer-motion @base-ui/react clsx tailwind-merge lucide-react
如果使用 Botpress 运行时间 :
pnpm add @botpress/client @tanstack/react-query
@bpinternal/integration-hub/runtime 包括内置配置窗体渲染器,由
@bpinternal/static-zui-form。 。 。 .
如果您的应用程序尚未提供 Radix 风格的设计标志, 请导入软件包倒置主题 :
import '@bpinternal/integration-hub/theme.css'
备选办法A:投放屏幕(快速)
一个处理一切的单一组件——取来,绘图,目录,细节视图,突变.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { BotpressIntegrationHub } from '@bpinternal/integration-hub/runtime'
const queryClient = new QueryClient()
export const IntegrationsPage = ({ client, workspaceId, botId }) => (
<QueryClientProvider client={queryClient}>
<BotpressIntegrationHub
client={client}
workspaceId={workspaceId}
botId={botId}
onInstall={(integration) => toast.success(`${integration.title} installed`)}
onUninstall={(integration) => toast.success(`${integration.title} removed`)}
onError={(error) => toast.error(error.message)}
/>
</QueryClientProvider>
)
默认, BotpressIntegrationHub 使用 Static ZUI Form 创建集成配置字段。 过
renderConfigurationForm 只有您想要推翻此默认行为时.
选项B:虎克+UI组件(更多控制)
使用钩子进行数据/mutes,但用包的UI组件来构成自己的布局.
import { useIntegrationHub, useIntegrationDetails } from '@bpinternal/integration-hub/runtime'
import {
IntegrationHubBody,
IntegrationGridCard,
IntegrationInstalledList,
IntegrationDetailsLayout,
IntegrationCapabilitiesCards
} from '@bpinternal/integration-hub'
export const IntegrationsPage = ({ client, workspaceId, botId }) => {
const [selectedId, setSelectedId] = useState(null)
const [search, setSearch] = useState('')
const hub = useIntegrationHub({ client, workspaceId, botId })
const details = useIntegrationDetails({ client, workspaceId, botId, integrationId: selectedId })
return (
<IntegrationHubBody
view="hub"
searchInput={search}
onSearchInputChange={setSearch}
hubIntegrations={hub.integrations}
sidebarIntegrations={hub.integrations}
installedIntegrations={hub.installedIntegrations}
isHubLoading={hub.isLoading}
renderIntegrationCard={(integration) => (
<IntegrationGridCard
name={integration.title ?? integration.name}
iconUrl={integration.iconUrl}
installed={integration.installed}
onClick={() => setSelectedId(integration.id)}
/>
)}
renderInstalledIntegrations={({ integrations, searchTerm, categoryOrder }) => (
<IntegrationInstalledList
integrations={integrations}
searchTerm={searchTerm}
categoryOrder={categoryOrder}
onSelectIntegration={(i) => setSelectedId(i.id)}
/>
)}
renderIntegrationDetails={() => (
<IntegrationDetailsLayout
title={details.definition?.title ?? ''}
iconUrl={details.definition?.iconUrl}
onBack={() => setSelectedId(null)}
onInstall={() => hub.install(selectedId)}
isInstalled={Boolean(details.installedState)}
isInstalling={hub.isInstalling}
>
<IntegrationCapabilitiesCards
actionCards={details.capabilities.actionCards}
eventCards={details.capabilities.eventCards}
/>
</IntegrationDetailsLayout>
)}
/>
)
}
选项 C: 只绘制地图( 绘制您自己的数据层)
转换纯函数 @botpress/client 类型。 无有回向无有钩. 如果您已经拥有自己的反应查询设置, 并且只是想停止复制映射逻辑, 请使用这些 .
import {
toHubItem,
toCapabilityCards,
toConnectionMethods,
getInstalledIntegrations,
filterAndSortIntegrations
} from '@bpinternal/integration-hub/runtime'
// In your own React Query hook:
const integrations = await client.listPublicIntegrations({ version: 'latest' })
const bot = await client.getBot({ id: botId })
const installed = getInstalledIntegrations(bot.integrations)
const installedByName = new Map(installed.map((i) => [i.name, i]))
const hubItems = integrations.map((summary) => toHubItem({ summary, installedByName }))
const filtered = filterAndSortIntegrations({ integrations: hubItems, searchTerm: 'slack' })
选项 D: 只使用 UI( 无 Botpress 客户端)
使用带有任何数据源的组件 。 你处理所有采集和传递数据作为道具.
import { IntegrationHubBody, IntegrationGridCard } from '@bpinternal/integration-hub'
const myIntegrations = [
{ id: '1', name: 'slack', title: 'Slack', description: 'Chat with Slack', iconUrl: '...' }
]
export const MyHub = () => (
<IntegrationHubBody
view="hub"
searchInput={search}
onSearchInputChange={setSearch}
hubIntegrations={myIntegrations}
sidebarIntegrations={myIntegrations}
installedIntegrations={[]}
renderIntegrationCard={(integration) => (
<IntegrationGridCard name={integration.title} iconUrl={integration.iconUrl} />
)}
renderInstalledIntegrations={() => <div>No installed integrations</div>}
renderIntegrationDetails={(id) => <div>Details for {id}</div>}
/>
)
API 参考
useIntegrationHub(options)
Hook能获取集成目录和bot状态,并提供突变功能.
选项 :
| 参数 | 类型 | 说明 |
|---|---|---|
client | Client | 一个配置 @botpress/client 实例 |
workspaceId | string | 工作空间标识 |
botId | string | 瓶口标识 |
categoryResolver? | (integration) => string | null | 覆盖默认类别映射 |
enabled? | boolean | 禁用获取( 默认) true(中文(简体) ) |
回返情况:
| 外地 | 类型 | 说明 |
|---|---|---|
integrations | BotpressIntegrationHubItem[] | 所有公共+私人融入 installed编号 :enabled编号 :hasUpdate 计算 |
installedIntegrations | BotpressIntegrationHubItem[] | 只安装在机器人上的集成 |
isLoading | boolean | 初始负载正在进行中 |
error | Error | null | 获取错误 |
install(id) | (id: string) => Promise<void> | 在机器人上安装集成 |
uninstall(id) | (id: string) => Promise<void> | 从机器人中删除集成 |
enable(id) | (id: string) => Promise<void> | 启用已安装的集成 |
disable(id) | (id: string) => Promise<void> | 禁用已安装的集成 |
upgrade(id) | (id: string) => Promise<void> | 将集成升级到最新版本 |
refresh() | () => void | 重新调试所有数据 |
isInstalling | boolean | 正在安装突变 |
isUninstalling | boolean | 未安装正在变换 |
isEnabling | boolean | 启用在进行中的突变 |
isDisabling | boolean | 禁用进行中的突变 |
isUpgrading | boolean | 正在升级突变 |
useIntegrationDetails(options)
获取单一集成的完整定义的钩子 被安装的状态 和能力.
选项 :
| 参数 | 类型 | 说明 |
|---|---|---|
client | Client | 一个配置 @botpress/client 实例 |
workspaceId | string | 工作空间标识 |
botId | string | 瓶口标识 |
integrationId | string | null | 集成到负载( null = 已禁用) |
enabled? | boolean | 禁用获取( 默认) true(中文(简体) ) |
回返情况:
| 外地 | 类型 | 说明 |
|---|---|---|
definition | Integration | null | 完全整合定义(动作、事件、频道、配置方案) |
installedState | BotpressInstalledIntegration | null | Bot 已安装状态( 启用、 配置、 WebhookUrl) 或未安装的无效状态 |
capabilities.actionCards | IntegrationCapabilityCardItem[] | 动作卡准备就绪 IntegrationCapabilitiesCards |
capabilities.eventCards | IntegrationCapabilityCardItem[] | 事件卡 |
capabilities.channelCards | IntegrationCapabilityCardItem[] | 频道卡 |
connectionMethods | IntegrationConnectionMethodOption[] | 可用的连接方法( OAuth, 命名为配置, 沙盒) |
selectedConnectionMethod | string | null | 当前活动连接方法 |
isLoading | boolean | 获取中 |
error | Error | null | 获取错误 |
saveConfig(config) | (config: Record<string, unknown>) => Promise<void> | 保存集成配置 |
toggleEnabled() | () => Promise<void> | 切换启用/ 损坏状态 |
setConnectionMethod(method) | (method: string | null) => Promise<void> | 切换连接方法 |
refresh() | () => void | 重选细节 |
isSavingConfig | boolean | 配置保存中 |
isTogglingEnabled | boolean | 切换正在进行中的突变 |
isSettingConnectionMethod | boolean | 连接方法正在变换中 |
BotpressIntegrationHub (由屏幕组成)
接线的滴入组件 useIntegrationHub + 键 useIntegrationDetails +所有UI组件. 内部管理视图/搜索/选择/tab状态.
所需的道具 : client, (中文(简体) ), workspaceId, (中文(简体) ), botId
可选覆盖 :
| Prop | 类型 | 说明 |
|---|---|---|
initialView | 'hub' | 'installed' | 开始视图( 默认) 'hub'(中文(简体) ) |
categories | IntegrationHubCategory[] | 覆盖默认类别 |
bannerSlides | IntegrationHubBannerSlide[] | 覆盖宣传横幅内容 |
bannerIconUrl | string | 屏蔽图像 URL |
filterMenuLabels | Partial<IntegrationHubFilterMenuLabels> | 覆盖过滤器菜单文本 |
categoryResolver | (integration) => string | null | 自定义类别映射 |
disableInstallation | boolean | 隐藏安装按钮 |
hasWriteAccess | boolean | 错误时禁用突变按钮 |
noResultsDocumentationLink | { href, label? } | 在空搜索结果中显示的链接 |
oauthTemplateData | Record<string, unknown> | 额外有效载荷合并为 client.runVrl 当生成 OAuth 授权 URL 时。 若为 env ,运行时间推断 production 页:1 *.cloud API URLs 和 (简体中文) preview 否则. |
渲染槽( 对于软件包不能拥有的东西):
| 槽 | 接受的道具 | 目的 |
|---|---|---|
renderConfigurationForm | { definition, installedState, selectedConnectionMethod, onSave, isSaving } | 覆盖默认的 Static ZUI 配置格式渲染器 . |
renderConnectionsContent | { definition, installedState, connectionMethods, selectedConnectionMethod, onConnectionMethodChange } | 覆盖默认运行时间连接 UI(OAuth/手动流量). |
renderDetailPanel | { definition, selectedCard, onClose } | 选择能力卡时将侧面板渲染(例如:schema取景器). |
回调 :
| 回电 | 类型 | 当它起火时 |
|---|---|---|
onInstall | (integration) => void | 成功安装后 |
onUninstall | (integration) => void | 成功卸载后 |
onEnable | (integration) => void | 成功启用后 |
onDisable | (integration) => void | 成功禁用后 |
onUpgrade | (integration) => void | 成功升级后 |
onError | (error: Error) => void | 任何突变错误 |
映射函数
纯函数( 无反应) 导出自 @bpinternal/integration-hub/runtime数字 :
| 函数 | 说明 |
|---|---|
toHubItem({ summary, installedByName, categoryResolver? }) | 转换 a @botpress/client 集成摘要 + 机器人状态 IntegrationHubItem |
toInstalledItem({ installedIntegration, summary?, categoryResolver? }) | 将机器人安装的集成项转换为 IntegrationHubItem |
toCapabilityCards(definition) | 从完全整合定义中提取动作、事件和频道到卡数组 |
toConnectionMethods(definition) | 从定义中提取可用的连接方法( OAuth, 命名为配置, 沙盒) |
getInstalledIntegrations(botIntegrations) | 转换原始 bot.integrations 映射到已输入数组 |
findInstalledIntegration({ installedIntegrations, integrationId, integrationName? }) | 以 ID 或名称查找特定的安装集成 |
filterAndSortIntegrations({ integrations, searchTerm, visibility?, verification?, sortMethod? }) | 通过搜索、能见度、校验状态和排序方法过滤和排序中枢项目 |
resolveCategory(integration, categoryResolver?) | 用可选的自定义解析器解析整合的类别 |
isOfficialWorkspace(handle) | 检查工作空间控件是否为正式的 Botpress 工作空间 |
dedupeById(items) | 通过 ID 删除重复的项目 |
此软件包不包括什么
这些是消费者的责任:
| 东西 | 为什么 | 怎么办 |
|---|---|---|
| 授权/ 会话 | 每个应用程序处理权限不同 | 创建自己的 @botpress/client 拿着你的证物 把它传给钩子 |
| 自定义 OAuth UX | 软件包包括默认的 OAuth 流量, 但针对应用程序的重定向和 UX 可更改 | 使用 oauthTemplateData 或覆盖到 renderConnectionsContent 编号 : IntegrationOAuthButton |
| 自定义配置形式行为 | 包装了静态ZUI默认渲染器,但应用软件可能需要自定义控制/验证/UX | 提供 renderConfigurationForm 仅在超过默认时 |
| 运行/ URL 同步 | 过于特定框架( React Router, TanStack 路由器, Next.js) | 管理 selectedIntegrationId 财务报告和审定财务报表 view 声明自己和地图到您的路由器 |
| 托拉斯通知 | 每个应用程序都有自己的土司系统 | 使用 onInstall, (中文(简体) ), onUninstall, (中文(简体) ), onError 呼唤回起你的祝酒词 |
| 分析/跟踪 | App 特定遥测 | 使用突变回调( U)onInstall, (中文(简体) ), onUninstall, (中文(简体) ), onEnable, (中文(简体) ), onDisable, (中文(简体) ), onUpgrade)和您自己的UI级跟踪钩 |
| 地物标志 | 苹果专用的标语 | 过 disableInstallation 或者说 hasWriteAccess 布尔 |
自定义默认值
包船具有通用默认. 为你的产品代替它们:
bannerSlides——宣传横幅内容(通过自己的幻灯片或需要隐藏的空数组)categories——有图标的集成类(默认为13个常见类)filterMenuLabels——以默认值来深处来更改标签,例如:{ verification: { official: 'Made by Botpress' } }noResultsDocumentationLink——搜索无结果时显示链接formatGithubLabel打开IntegrationSetupMetadataBar——自定义 GitHub URL 显示格式categoryResolver——功能以凌驾如何将整合分配给类别
UI 组件
全部从 @bpinternal/integration-hub数字 :
| 构成部分 | 目的 |
|---|---|
IntegrationHubBody | 完整中枢页面:分类侧栏,搜索,横幅自旋,应答卡网格,已安装列表,细节平板路由 |
IntegrationHubFilterMenu | 带有活性滤波药片的下拉式滤波器菜单( 可见性、 校验、 排序) |
IntegrationGridCard | 有图标、名称、描述、作者、徽章的整合卡 |
IntegrationInstalledList | 已排序/过滤的已安装集成状态列表 |
IntegrationDetailsLayout | 详细页外壳: 后键、 标题、 安装/ Uninstall/ Enable/ Disable/ Update 按钮、 侧面板槽 |
IntegrationSetupWizardLayout | 设置向导:“设置模式”编号步骤和“配置模式”标签 |
IntegrationSetupMetadataBar | 版本, GitHub 链接, 关于按钮行 |
IntegrationConnectionMethodSelector | 下放取连接方法( OAuth, 命名为配置, 沙盒) |
IntegrationWebhookUrlField | 只读有复制按钮和工具提示的 Webhook URL |
IntegrationConfigurationSection | 配置有标题、 Webhook 字段、 被屏蔽状态和子槽的包装 |
IntegrationCapabilitiesCards | 有选择状态的动作/事件/频道能力卡网格 |
结构要求
1. 进口包CSS
包船预编成组件样式 theme.css。在应用程序入口处导入一次:
import '@bpinternal/integration-hub/theme.css'
您无需添加 @bpinternal/integration-hub 改为运行时样式的 Tailwind 内容.
软件包源的尾风扫描只有在针对未发布的本地源开发时才有用.
2. CSS自定义属性
组件使用Radix风格的颜色符号. 任意使用 @radix-ui/themes 或定义这些变量:
:root {
--gray-1: #ffffff;
--gray-2: #f8f9fa;
--gray-3: #f1f3f5;
--gray-5: #e1e5ea;
--gray-6: #d0d7de;
--gray-7: #bfc8d3;
--gray-8: #9aa4b2;
--gray-9: #7a8594;
--gray-10: #6b7280;
--gray-11: #4b5563;
--gray-12: #111827;
--gray-a2: rgba(17, 24, 39, 0.04);
--gray-a3: rgba(17, 24, 39, 0.07);
--gray-a4: rgba(17, 24, 39, 0.1);
--gray-a5: rgba(17, 24, 39, 0.14);
--gray-a6: rgba(17, 24, 39, 0.2);
--gray-a8: rgba(17, 24, 39, 0.4);
--blue-a2: rgba(37, 99, 235, 0.12);
--blue-8: #3b82f6;
--blue-11: #1d4ed8;
--grass-3: #ecfdf3;
--grass-5: #a7f3d0;
--grass-10: #16a34a;
--accent-9: #0ea5e9;
--accent-11: #0284c7;
}
3. 集装箱查询
IntegrationHubBody 使用本地的 CSS 容器查询来响应网格.
如果您在 Tailwind v3 app 中从源头重建软件包样式,请添加:
import containerQueries from '@tailwindcss/container-queries'
export default { plugins: [containerQueries] }
构建
pnpm --filter @bpinternal/integration-hub build
pnpm --filter @bpinternal/integration-hub type-check
发布
pnpm --filter @bpinternal/integration-hub exec npm version patch
pnpm --filter @bpinternal/integration-hub exec npm publish --access public
prepack 运行 clean && build 发布前自动.
说明: 根据传给botpress客户端的选项(x-多集成=真),来自botpress Cloud的集成由他们的ALIAS键入,而不是他们的ID. 对于打算使用集成ID的编辑,确保明确使用.id参数.