mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-22 16:00:51 +00:00
feat: Add telegram channel for Agent (#11947)
This commit is contained in:
@@ -271,6 +271,47 @@ func (b *BaseApi) UpdateAgentFeishuConfig(c *gin.Context) {
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags AI
|
||||
// @Summary Get Agent Telegram channel config
|
||||
// @Accept json
|
||||
// @Param request body dto.AgentTelegramConfigReq true "request"
|
||||
// @Success 200 {object} dto.AgentTelegramConfig
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /ai/agents/channel/telegram/get [post]
|
||||
func (b *BaseApi) GetAgentTelegramConfig(c *gin.Context) {
|
||||
var req dto.AgentTelegramConfigReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
data, err := agentService.GetTelegramConfig(req)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags AI
|
||||
// @Summary Update Agent Telegram channel config
|
||||
// @Accept json
|
||||
// @Param request body dto.AgentTelegramConfigUpdateReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /ai/agents/channel/telegram/update [post]
|
||||
func (b *BaseApi) UpdateAgentTelegramConfig(c *gin.Context) {
|
||||
var req dto.AgentTelegramConfigUpdateReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := agentService.UpdateTelegramConfig(req); err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags AI
|
||||
// @Summary Approve Agent Feishu pairing code
|
||||
// @Accept json
|
||||
@@ -290,3 +331,23 @@ func (b *BaseApi) ApproveAgentFeishuPairing(c *gin.Context) {
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags AI
|
||||
// @Summary Approve Agent channel pairing code
|
||||
// @Accept json
|
||||
// @Param request body dto.AgentChannelPairingApproveReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /ai/agents/channel/pairing/approve [post]
|
||||
func (b *BaseApi) ApproveAgentChannelPairing(c *gin.Context) {
|
||||
var req dto.AgentChannelPairingApproveReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := agentService.ApproveChannelPairing(req); err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
@@ -170,3 +170,26 @@ type AgentFeishuConfig struct {
|
||||
AppID string `json:"appId"`
|
||||
AppSecret string `json:"appSecret"`
|
||||
}
|
||||
|
||||
type AgentTelegramConfigReq struct {
|
||||
AgentID uint `json:"agentId" validate:"required"`
|
||||
}
|
||||
|
||||
type AgentTelegramConfigUpdateReq struct {
|
||||
AgentID uint `json:"agentId" validate:"required"`
|
||||
Enabled bool `json:"enabled"`
|
||||
DmPolicy string `json:"dmPolicy" validate:"required"`
|
||||
BotToken string `json:"botToken" validate:"required"`
|
||||
}
|
||||
|
||||
type AgentTelegramConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
DmPolicy string `json:"dmPolicy"`
|
||||
BotToken string `json:"botToken"`
|
||||
}
|
||||
|
||||
type AgentChannelPairingApproveReq struct {
|
||||
AgentID uint `json:"agentId" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=feishu telegram"`
|
||||
PairingCode string `json:"pairingCode" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -43,6 +43,9 @@ type IAgentService interface {
|
||||
DeleteAccount(req dto.AgentAccountDeleteReq) error
|
||||
GetFeishuConfig(req dto.AgentFeishuConfigReq) (*dto.AgentFeishuConfig, error)
|
||||
UpdateFeishuConfig(req dto.AgentFeishuConfigUpdateReq) error
|
||||
GetTelegramConfig(req dto.AgentTelegramConfigReq) (*dto.AgentTelegramConfig, error)
|
||||
UpdateTelegramConfig(req dto.AgentTelegramConfigUpdateReq) error
|
||||
ApproveChannelPairing(req dto.AgentChannelPairingApproveReq) error
|
||||
ApproveFeishuPairing(req dto.AgentFeishuPairingApproveReq) error
|
||||
}
|
||||
|
||||
@@ -570,14 +573,58 @@ func (a AgentService) UpdateFeishuConfig(req dto.AgentFeishuConfigUpdateReq) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AgentService) ApproveFeishuPairing(req dto.AgentFeishuPairingApproveReq) error {
|
||||
func (a AgentService) GetTelegramConfig(req dto.AgentTelegramConfigReq) (*dto.AgentTelegramConfig, error) {
|
||||
agent, _, err := a.loadAgentAndInstall(req.AgentID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conf, err := readOpenclawConfig(agent.ConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := extractTelegramConfig(conf)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (a AgentService) UpdateTelegramConfig(req dto.AgentTelegramConfigUpdateReq) error {
|
||||
agent, _, err := a.loadAgentAndInstall(req.AgentID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
conf, err := readOpenclawConfig(agent.ConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if req.DmPolicy == "" {
|
||||
req.DmPolicy = "pairing"
|
||||
}
|
||||
setTelegramConfig(conf, dto.AgentTelegramConfig{
|
||||
Enabled: req.Enabled,
|
||||
DmPolicy: req.DmPolicy,
|
||||
BotToken: req.BotToken,
|
||||
})
|
||||
if err := writeOpenclawConfigRaw(agent.ConfigPath, conf); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AgentService) ApproveChannelPairing(req dto.AgentChannelPairingApproveReq) error {
|
||||
_, install, err := a.loadAgentAndInstall(req.AgentID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
channelType := strings.ToLower(strings.TrimSpace(req.Type))
|
||||
if channelType == "" {
|
||||
channelType = "feishu"
|
||||
}
|
||||
if channelType != "feishu" && channelType != "telegram" {
|
||||
return fmt.Errorf("unsupported channel type: %s", channelType)
|
||||
}
|
||||
if err := cmd.RunDefaultBashCf(
|
||||
"docker exec %s openclaw pairing approve feishu %q",
|
||||
"docker exec %s openclaw pairing approve %s %q",
|
||||
install.ContainerName,
|
||||
channelType,
|
||||
strings.TrimSpace(req.PairingCode),
|
||||
); err != nil {
|
||||
return err
|
||||
@@ -585,6 +632,14 @@ func (a AgentService) ApproveFeishuPairing(req dto.AgentFeishuPairingApproveReq)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AgentService) ApproveFeishuPairing(req dto.AgentFeishuPairingApproveReq) error {
|
||||
return a.ApproveChannelPairing(dto.AgentChannelPairingApproveReq{
|
||||
AgentID: req.AgentID,
|
||||
Type: "feishu",
|
||||
PairingCode: req.PairingCode,
|
||||
})
|
||||
}
|
||||
|
||||
func (a AgentService) loadAgentAndInstall(agentID uint) (*model.Agent, *model.AppInstall, error) {
|
||||
agent, err := agentRepo.GetFirst(repo.WithByID(agentID))
|
||||
if err != nil {
|
||||
@@ -688,6 +743,38 @@ func setFeishuPluginEnabled(conf map[string]interface{}, enabled bool) {
|
||||
feishu["enabled"] = enabled
|
||||
}
|
||||
|
||||
func extractTelegramConfig(conf map[string]interface{}) dto.AgentTelegramConfig {
|
||||
result := dto.AgentTelegramConfig{Enabled: true, DmPolicy: "pairing"}
|
||||
channels, ok := conf["channels"].(map[string]interface{})
|
||||
if !ok {
|
||||
return result
|
||||
}
|
||||
telegram, ok := channels["telegram"].(map[string]interface{})
|
||||
if !ok {
|
||||
return result
|
||||
}
|
||||
if enabled, ok := telegram["enabled"].(bool); ok {
|
||||
result.Enabled = enabled
|
||||
}
|
||||
if dmPolicy, ok := telegram["dmPolicy"].(string); ok && strings.TrimSpace(dmPolicy) != "" {
|
||||
result.DmPolicy = dmPolicy
|
||||
}
|
||||
if botToken, ok := telegram["botToken"].(string); ok {
|
||||
result.BotToken = botToken
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func setTelegramConfig(conf map[string]interface{}, config dto.AgentTelegramConfig) {
|
||||
channels := ensureChildMap(conf, "channels")
|
||||
telegram := map[string]interface{}{
|
||||
"enabled": config.Enabled,
|
||||
"dmPolicy": config.DmPolicy,
|
||||
"botToken": config.BotToken,
|
||||
}
|
||||
channels["telegram"] = telegram
|
||||
}
|
||||
|
||||
func (a AgentService) syncAgentsByAccount(account *model.AgentAccount) error {
|
||||
agents, err := agentRepo.List(repo.WithByAccountID(account.ID))
|
||||
if err != nil {
|
||||
|
||||
@@ -54,5 +54,8 @@ func (a *AIToolsRouter) InitRouter(Router *gin.RouterGroup) {
|
||||
aiToolsRouter.POST("/agents/channel/feishu/get", baseApi.GetAgentFeishuConfig)
|
||||
aiToolsRouter.POST("/agents/channel/feishu/update", baseApi.UpdateAgentFeishuConfig)
|
||||
aiToolsRouter.POST("/agents/channel/feishu/approve", baseApi.ApproveAgentFeishuPairing)
|
||||
aiToolsRouter.POST("/agents/channel/telegram/get", baseApi.GetAgentTelegramConfig)
|
||||
aiToolsRouter.POST("/agents/channel/telegram/update", baseApi.UpdateAgentTelegramConfig)
|
||||
aiToolsRouter.POST("/agents/channel/pairing/approve", baseApi.ApproveAgentChannelPairing)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,4 +404,27 @@ export namespace AI {
|
||||
agentId: number;
|
||||
pairingCode: string;
|
||||
}
|
||||
|
||||
export interface AgentTelegramConfigReq {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
export interface AgentTelegramConfig {
|
||||
enabled: boolean;
|
||||
dmPolicy: string;
|
||||
botToken: string;
|
||||
}
|
||||
|
||||
export interface AgentTelegramConfigUpdateReq {
|
||||
agentId: number;
|
||||
enabled: boolean;
|
||||
dmPolicy: string;
|
||||
botToken: string;
|
||||
}
|
||||
|
||||
export interface AgentChannelPairingApproveReq {
|
||||
agentId: number;
|
||||
type: 'feishu' | 'telegram';
|
||||
pairingCode: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,3 +147,15 @@ export const updateAgentFeishuConfig = (req: AI.AgentFeishuConfigUpdateReq) => {
|
||||
export const approveAgentFeishuPairing = (req: AI.AgentFeishuPairingApproveReq) => {
|
||||
return http.post(`/ai/agents/channel/feishu/approve`, req);
|
||||
};
|
||||
|
||||
export const getAgentTelegramConfig = (req: AI.AgentTelegramConfigReq) => {
|
||||
return http.post<AI.AgentTelegramConfig>(`/ai/agents/channel/telegram/get`, req);
|
||||
};
|
||||
|
||||
export const updateAgentTelegramConfig = (req: AI.AgentTelegramConfigUpdateReq) => {
|
||||
return http.post(`/ai/agents/channel/telegram/update`, req);
|
||||
};
|
||||
|
||||
export const approveAgentChannelPairing = (req: AI.AgentChannelPairingApproveReq) => {
|
||||
return http.post(`/ai/agents/channel/pairing/approve`, req);
|
||||
};
|
||||
|
||||
@@ -710,7 +710,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: 'For custom model accounts, model names must start with custom/.',
|
||||
|
||||
@@ -706,7 +706,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: 'En la cuenta de modelo personalizada, el nombre del modelo debe empezar por custom/',
|
||||
|
||||
@@ -695,7 +695,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: 'カスタムモデルアカウントでは、モデル名は必ず custom/ で始めてください',
|
||||
|
||||
@@ -692,7 +692,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: '사용자 정의 모델 계정의 모델명은 반드시 custom/ 로 시작해야 합니다',
|
||||
|
||||
@@ -707,7 +707,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: 'Akaun model tersuai, nama model mesti bermula dengan custom/',
|
||||
|
||||
@@ -704,7 +704,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: 'Conta de modelo personalizada: o nome do modelo deve começar com custom/',
|
||||
|
||||
@@ -700,7 +700,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: 'Для пользовательской учетной записи модели имя модели должно начинаться с custom/',
|
||||
|
||||
@@ -714,7 +714,7 @@ const message = {
|
||||
pairingCodePlaceholder: 'Enter pairing code',
|
||||
approvePairing: 'Approve Pairing',
|
||||
feishuRequired: 'Please fill botName / appId / appSecret',
|
||||
feishuSaveSuccess: 'Saved successfully',
|
||||
saveSuccess: 'Saved successfully',
|
||||
pairingCodeRequired: 'Please enter pairing code',
|
||||
pairingApproveSuccess: 'Pairing approved successfully',
|
||||
customModelHelper: 'Özel model hesabında model adı custom/ ile başlamalıdır',
|
||||
|
||||
@@ -682,7 +682,7 @@ const message = {
|
||||
pairingCodePlaceholder: '請輸入配對碼',
|
||||
approvePairing: '批准配對',
|
||||
feishuRequired: '請填寫 botName / appId / appSecret',
|
||||
feishuSaveSuccess: '保存成功',
|
||||
saveSuccess: '保存成功',
|
||||
pairingCodeRequired: '請輸入配對碼',
|
||||
pairingApproveSuccess: '配對成功',
|
||||
customModelHelper: '自訂模型帳號,模型需固定以 custom/ 開頭',
|
||||
|
||||
@@ -684,7 +684,7 @@ const message = {
|
||||
pairingCodePlaceholder: '请输入配对码',
|
||||
approvePairing: '批准配对',
|
||||
feishuRequired: '请填写 botName / appId / appSecret',
|
||||
feishuSaveSuccess: '保存成功',
|
||||
saveSuccess: '保存成功',
|
||||
pairingCodeRequired: '请输入配对码',
|
||||
pairingApproveSuccess: '配对成功',
|
||||
customModelHelper: '自定义模型账号,模型固定以 custom/ 开头',
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<template>
|
||||
<DrawerPro v-model="open" :header="header" size="large" @close="handleClose">
|
||||
<el-tabs v-model="activeTab" tab-position="left" class="config-tabs" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="t('aiTools.model.model')" name="model">
|
||||
<ModelTab ref="modelRef" @updated="handleModelUpdated" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="t('aiTools.agents.channelsTab')" name="channels">
|
||||
<ChannelsTab ref="channelsRef" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<template #content>
|
||||
<el-tabs v-model="activeTab" tab-position="left" class="config-tabs" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="t('aiTools.model.model')" name="model">
|
||||
<ModelTab ref="modelRef" @updated="handleModelUpdated" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="t('aiTools.agents.channelsTab')" name="channels">
|
||||
<ChannelsTab ref="channelsRef" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,134 +1,45 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
|
||||
<el-form-item :label="t('aiTools.agents.feishu')">
|
||||
<el-switch v-model="form.enabled" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-link type="primary" icon="Position" @click="toFeishuDoc">
|
||||
{{ t('container.mirrorsHelper2') }}
|
||||
</el-link>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.dmPolicy')" prop="dmPolicy">
|
||||
<el-select v-model="form.dmPolicy">
|
||||
<el-option label="pairing" value="pairing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.botName')" prop="botName">
|
||||
<el-input v-model="form.botName" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.appId')" prop="appId">
|
||||
<el-input v-model="form.appId" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.appSecret')" prop="appSecret">
|
||||
<el-input v-model="form.appSecret" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="saving" @click="saveChannel">
|
||||
{{ t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-form-item :label="t('aiTools.agents.pairingCode')">
|
||||
<el-input v-model="pairingCode" :placeholder="t('aiTools.agents.pairingCodePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="approving" @click="approvePairing">
|
||||
{{ t('aiTools.agents.approvePairing') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="t('aiTools.agents.feishu')" name="feishu">
|
||||
<FeishuTab ref="feishuRef" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="Telegram" name="telegram">
|
||||
<TelegramTab ref="telegramRef" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue';
|
||||
import type { FormInstance } from 'element-plus';
|
||||
import { nextTick, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { AI } from '@/api/interface/ai';
|
||||
import { approveAgentFeishuPairing, getAgentFeishuConfig, updateAgentFeishuConfig } from '@/api/modules/ai';
|
||||
import { MsgSuccess, MsgWarning } from '@/utils/message';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import FeishuTab from './channels/feishu.vue';
|
||||
import TelegramTab from './channels/telegram.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const saving = ref(false);
|
||||
const approving = ref(false);
|
||||
const activeTab = ref('feishu');
|
||||
const agentId = ref(0);
|
||||
const pairingCode = ref('');
|
||||
const formRef = ref<FormInstance>();
|
||||
const feishuRef = ref();
|
||||
const telegramRef = ref();
|
||||
|
||||
const form = reactive<AI.AgentFeishuConfig>({
|
||||
enabled: true,
|
||||
dmPolicy: 'pairing',
|
||||
botName: '',
|
||||
appId: '',
|
||||
appSecret: '',
|
||||
});
|
||||
const loadCurrentTab = async () => {
|
||||
if (agentId.value <= 0) {
|
||||
return;
|
||||
}
|
||||
await nextTick();
|
||||
if (activeTab.value === 'telegram') {
|
||||
await telegramRef.value?.load(agentId.value);
|
||||
return;
|
||||
}
|
||||
await feishuRef.value?.load(agentId.value);
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
dmPolicy: [Rules.requiredSelect],
|
||||
botName: [Rules.requiredInput],
|
||||
appId: [Rules.requiredInput],
|
||||
appSecret: [Rules.requiredInput],
|
||||
});
|
||||
|
||||
const toFeishuDoc = () => {
|
||||
window.open('https://openclaw.club/guides/feishu-platform', '_blank');
|
||||
const handleTabClick = async () => {
|
||||
await loadCurrentTab();
|
||||
};
|
||||
|
||||
const load = async (id: number) => {
|
||||
agentId.value = id;
|
||||
pairingCode.value = '';
|
||||
const res = await getAgentFeishuConfig({ agentId: id });
|
||||
Object.assign(form, res.data || {});
|
||||
if (!form.dmPolicy) {
|
||||
form.dmPolicy = 'pairing';
|
||||
}
|
||||
};
|
||||
|
||||
const saveChannel = async () => {
|
||||
if (!agentId.value) {
|
||||
return;
|
||||
}
|
||||
if (!formRef.value) {
|
||||
return;
|
||||
}
|
||||
await formRef.value.validate();
|
||||
saving.value = true;
|
||||
try {
|
||||
await updateAgentFeishuConfig({
|
||||
agentId: agentId.value,
|
||||
enabled: form.enabled,
|
||||
dmPolicy: form.dmPolicy || 'pairing',
|
||||
botName: form.botName,
|
||||
appId: form.appId,
|
||||
appSecret: form.appSecret,
|
||||
});
|
||||
MsgSuccess(t('aiTools.agents.feishuSaveSuccess'));
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const approvePairing = async () => {
|
||||
if (!agentId.value) {
|
||||
return;
|
||||
}
|
||||
if (!pairingCode.value) {
|
||||
MsgWarning(t('aiTools.agents.pairingCodeRequired'));
|
||||
return;
|
||||
}
|
||||
approving.value = true;
|
||||
try {
|
||||
await approveAgentFeishuPairing({
|
||||
agentId: agentId.value,
|
||||
pairingCode: pairingCode.value,
|
||||
});
|
||||
MsgSuccess(t('aiTools.agents.pairingApproveSuccess'));
|
||||
pairingCode.value = '';
|
||||
} finally {
|
||||
approving.value = false;
|
||||
}
|
||||
await loadCurrentTab();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
|
||||
<el-form-item :label="t('commons.table.status')">
|
||||
<el-switch v-model="form.enabled" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-link type="primary" icon="Position" @click="toFeishuDoc">
|
||||
{{ t('container.mirrorsHelper2') }}
|
||||
</el-link>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.dmPolicy')" prop="dmPolicy">
|
||||
<el-select v-model="form.dmPolicy">
|
||||
<el-option label="pairing" value="pairing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.botName')" prop="botName">
|
||||
<el-input v-model="form.botName" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.appId')" prop="appId">
|
||||
<el-input v-model="form.appId" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.appSecret')" prop="appSecret">
|
||||
<el-input v-model="form.appSecret" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="saving" @click="saveChannel">
|
||||
{{ t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-form-item :label="t('aiTools.agents.pairingCode')">
|
||||
<el-input v-model="pairingCode" :placeholder="t('aiTools.agents.pairingCodePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="approving" @click="approvePairing">
|
||||
{{ t('aiTools.agents.approvePairing') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue';
|
||||
import type { FormInstance } from 'element-plus';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { AI } from '@/api/interface/ai';
|
||||
import { approveAgentChannelPairing, getAgentFeishuConfig, updateAgentFeishuConfig } from '@/api/modules/ai';
|
||||
import { MsgSuccess, MsgWarning } from '@/utils/message';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
const { t } = useI18n();
|
||||
const saving = ref(false);
|
||||
const approving = ref(false);
|
||||
const agentId = ref(0);
|
||||
const pairingCode = ref('');
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const form = reactive<AI.AgentFeishuConfig>({
|
||||
enabled: true,
|
||||
dmPolicy: 'pairing',
|
||||
botName: '',
|
||||
appId: '',
|
||||
appSecret: '',
|
||||
});
|
||||
|
||||
const rules = reactive({
|
||||
dmPolicy: [Rules.requiredSelect],
|
||||
botName: [Rules.requiredInput],
|
||||
appId: [Rules.requiredInput],
|
||||
appSecret: [Rules.requiredInput],
|
||||
});
|
||||
|
||||
const toFeishuDoc = () => {
|
||||
window.open('https://openclaw.club/guides/feishu-platform', '_blank');
|
||||
};
|
||||
|
||||
const load = async (id: number) => {
|
||||
agentId.value = id;
|
||||
pairingCode.value = '';
|
||||
const res = await getAgentFeishuConfig({ agentId: id });
|
||||
Object.assign(form, res.data || {});
|
||||
if (!form.dmPolicy) {
|
||||
form.dmPolicy = 'pairing';
|
||||
}
|
||||
};
|
||||
|
||||
const saveChannel = async () => {
|
||||
if (!agentId.value || !formRef.value) {
|
||||
return;
|
||||
}
|
||||
await formRef.value.validate();
|
||||
saving.value = true;
|
||||
try {
|
||||
await updateAgentFeishuConfig({
|
||||
agentId: agentId.value,
|
||||
enabled: form.enabled,
|
||||
dmPolicy: form.dmPolicy || 'pairing',
|
||||
botName: form.botName,
|
||||
appId: form.appId,
|
||||
appSecret: form.appSecret,
|
||||
});
|
||||
MsgSuccess(t('aiTools.agents.saveSuccess'));
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const approvePairing = async () => {
|
||||
if (!agentId.value) {
|
||||
return;
|
||||
}
|
||||
if (!pairingCode.value) {
|
||||
MsgWarning(t('aiTools.agents.pairingCodeRequired'));
|
||||
return;
|
||||
}
|
||||
approving.value = true;
|
||||
try {
|
||||
await approveAgentChannelPairing({
|
||||
agentId: agentId.value,
|
||||
type: 'feishu',
|
||||
pairingCode: pairingCode.value,
|
||||
});
|
||||
MsgSuccess(t('aiTools.agents.pairingApproveSuccess'));
|
||||
pairingCode.value = '';
|
||||
} finally {
|
||||
approving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
load,
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
|
||||
<el-form-item :label="t('commons.table.status')">
|
||||
<el-switch v-model="form.enabled" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('aiTools.agents.dmPolicy')" prop="dmPolicy">
|
||||
<el-select v-model="form.dmPolicy">
|
||||
<el-option label="pairing" value="pairing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="Bot Token" prop="botToken">
|
||||
<el-input v-model="form.botToken" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="saving" @click="saveChannel">
|
||||
{{ t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-form-item :label="t('aiTools.agents.pairingCode')">
|
||||
<el-input v-model="pairingCode" :placeholder="t('aiTools.agents.pairingCodePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="approving" @click="approvePairing">
|
||||
{{ t('aiTools.agents.approvePairing') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue';
|
||||
import type { FormInstance } from 'element-plus';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { AI } from '@/api/interface/ai';
|
||||
import { approveAgentChannelPairing, getAgentTelegramConfig, updateAgentTelegramConfig } from '@/api/modules/ai';
|
||||
import { MsgSuccess, MsgWarning } from '@/utils/message';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
const { t } = useI18n();
|
||||
const saving = ref(false);
|
||||
const approving = ref(false);
|
||||
const agentId = ref(0);
|
||||
const pairingCode = ref('');
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const form = reactive<AI.AgentTelegramConfig>({
|
||||
enabled: true,
|
||||
dmPolicy: 'pairing',
|
||||
botToken: '',
|
||||
});
|
||||
|
||||
const rules = reactive({
|
||||
dmPolicy: [Rules.requiredSelect],
|
||||
botToken: [Rules.requiredInput],
|
||||
});
|
||||
|
||||
const load = async (id: number) => {
|
||||
agentId.value = id;
|
||||
pairingCode.value = '';
|
||||
const res = await getAgentTelegramConfig({ agentId: id });
|
||||
Object.assign(form, res.data || {});
|
||||
if (!form.dmPolicy) {
|
||||
form.dmPolicy = 'pairing';
|
||||
}
|
||||
};
|
||||
|
||||
const saveChannel = async () => {
|
||||
if (!agentId.value || !formRef.value) {
|
||||
return;
|
||||
}
|
||||
await formRef.value.validate();
|
||||
saving.value = true;
|
||||
try {
|
||||
await updateAgentTelegramConfig({
|
||||
agentId: agentId.value,
|
||||
enabled: form.enabled,
|
||||
dmPolicy: form.dmPolicy || 'pairing',
|
||||
botToken: form.botToken,
|
||||
});
|
||||
MsgSuccess(t('aiTools.agents.saveSuccess'));
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const approvePairing = async () => {
|
||||
if (!agentId.value) {
|
||||
return;
|
||||
}
|
||||
if (!pairingCode.value) {
|
||||
MsgWarning(t('aiTools.agents.pairingCodeRequired'));
|
||||
return;
|
||||
}
|
||||
approving.value = true;
|
||||
try {
|
||||
await approveAgentChannelPairing({
|
||||
agentId: agentId.value,
|
||||
type: 'telegram',
|
||||
pairingCode: pairingCode.value,
|
||||
});
|
||||
MsgSuccess(t('aiTools.agents.pairingApproveSuccess'));
|
||||
pairingCode.value = '';
|
||||
} finally {
|
||||
approving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
load,
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user