diff --git a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Bot.tsx b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Bot.tsx
index 0ae134ca..b13a0d05 100644
--- a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Bot.tsx
+++ b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Bot.tsx
@@ -1,48 +1,43 @@
import React from 'react';
-import { FullModalField, Switch } from '@capital/component';
+import {
+ DefaultFullModalInputEditorRender,
+ FullModalField,
+ Switch,
+} from '@capital/component';
import { useOpenAppInfo } from '../context';
-import { OpenAppCapability } from '../types';
-import { postRequest, useAsyncFn } from '@capital/common';
+import { Translate } from '../../translate';
+import { useOpenAppAction } from './useOpenAppAction';
const Bot: React.FC = React.memo(() => {
- const { refresh, appId, capability } = useOpenAppInfo();
-
- const [{ loading }, handleChangeBotCapability] = useAsyncFn(
- async (checked: boolean) => {
- const newCapability: OpenAppCapability[] = [...capability];
- const findIndex = newCapability.findIndex((c) => c === 'bot');
-
- if (checked) {
- if (findIndex === -1) {
- newCapability.push('bot');
- }
- } else {
- if (findIndex !== -1) {
- newCapability.splice(findIndex, 1);
- }
- }
-
- await postRequest('/openapi/app/setAppCapability', {
- appId,
- capability: newCapability,
- });
- await refresh();
- },
- [appId, capability, refresh]
- );
+ const { capability, bot } = useOpenAppInfo();
+ const { loading, handleChangeAppCapability, handleUpdateBotInfo } =
+ useOpenAppAction();
return (
handleChangeAppCapability('bot', checked)}
/>
}
/>
+
+ {capability.includes('bot') && (
+
+ handleUpdateBotInfo('callbackUrl', String(str))
+ }
+ />
+ )}
);
});
diff --git a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/OAuth.tsx b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/OAuth.tsx
index 32dba9e8..f0c2c1fe 100644
--- a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/OAuth.tsx
+++ b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/OAuth.tsx
@@ -5,44 +5,12 @@ import {
Switch,
} from '@capital/component';
import { useOpenAppInfo } from '../context';
-import { OpenAppCapability } from '../types';
-import { postRequest, useAsyncFn, useAsyncRequest } from '@capital/common';
+import { useOpenAppAction } from './useOpenAppAction';
const OAuth: React.FC = React.memo(() => {
- const { refresh, appId, capability, oauth } = useOpenAppInfo();
-
- const [{ loading }, handleChangeOAuthCapability] = useAsyncRequest(
- async (checked: boolean) => {
- const newCapability: OpenAppCapability[] = [...capability];
- const findIndex = newCapability.findIndex((c) => c === 'oauth');
- const isExist = findIndex !== -1;
-
- if (checked && !isExist) {
- newCapability.push('oauth');
- } else if (!checked && isExist) {
- newCapability.splice(findIndex, 1);
- }
-
- await postRequest('/openapi/app/setAppCapability', {
- appId,
- capability: newCapability,
- });
- await refresh();
- },
- [appId, capability, refresh]
- );
-
- const [, handleUpdateOAuthInfo] = useAsyncFn(
- async (name: string, value: any) => {
- await postRequest('/openapi/app/setAppOAuthInfo', {
- appId,
- fieldName: name,
- fieldValue: value,
- });
- await refresh();
- },
- []
- );
+ const { capability, oauth } = useOpenAppInfo();
+ const { loading, handleChangeAppCapability, handleUpdateOAuthInfo } =
+ useOpenAppAction();
return (
@@ -52,7 +20,7 @@ const OAuth: React.FC = React.memo(() => {
handleChangeAppCapability('oauth', checked)}
/>
}
/>
diff --git a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/useOpenAppAction.tsx b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/useOpenAppAction.tsx
new file mode 100644
index 00000000..72e38e52
--- /dev/null
+++ b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/useOpenAppAction.tsx
@@ -0,0 +1,65 @@
+import { postRequest, useAsyncFn } from '@capital/common';
+import { useOpenAppInfo } from '../context';
+import type { OpenAppBot, OpenAppCapability, OpenAppOAuth } from '../types';
+
+/**
+ * 开放应用操作
+ */
+export function useOpenAppAction() {
+ const { refresh, appId, capability } = useOpenAppInfo();
+
+ const [{ loading }, handleChangeAppCapability] = useAsyncFn(
+ async (targetCapability: OpenAppCapability, checked: boolean) => {
+ const newCapability: OpenAppCapability[] = [...capability];
+ const findIndex = newCapability.findIndex((c) => c === targetCapability);
+
+ if (checked) {
+ if (findIndex === -1) {
+ newCapability.push(targetCapability);
+ }
+ } else {
+ if (findIndex !== -1) {
+ newCapability.splice(findIndex, 1);
+ }
+ }
+
+ await postRequest('/openapi/app/setAppCapability', {
+ appId,
+ capability: newCapability,
+ });
+ await refresh();
+ },
+ [appId, capability, refresh]
+ );
+
+ const [, handleUpdateOAuthInfo] = useAsyncFn(
+ async (name: T, value: OpenAppOAuth[T]) => {
+ await postRequest('/openapi/app/setAppOAuthInfo', {
+ appId,
+ fieldName: name,
+ fieldValue: value,
+ });
+ await refresh();
+ },
+ []
+ );
+
+ const [, handleUpdateBotInfo] = useAsyncFn(
+ async (name: T, value: OpenAppBot[T]) => {
+ await postRequest('/openapi/app/setAppBotInfo', {
+ appId,
+ fieldName: name,
+ fieldValue: value,
+ });
+ await refresh();
+ },
+ [appId, refresh]
+ );
+
+ return {
+ loading,
+ handleChangeAppCapability,
+ handleUpdateOAuthInfo,
+ handleUpdateBotInfo,
+ };
+}
diff --git a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/types.ts b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/types.ts
index 74a4b266..f91bca74 100644
--- a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/types.ts
+++ b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/types.ts
@@ -6,10 +6,14 @@ const openAppCapability = [
export type OpenAppCapability = typeof openAppCapability[number];
-interface OpenAppOAuth {
+export interface OpenAppOAuth {
redirectUrls: string[];
}
+export interface OpenAppBot {
+ callbackUrl: string;
+}
+
export interface OpenApp {
_id: string;
appId: string;
@@ -19,6 +23,7 @@ export interface OpenApp {
appIcon: string;
capability: OpenAppCapability[];
oauth?: OpenAppOAuth;
+ bot?: OpenAppBot;
owner: string;
}
diff --git a/client/web/plugins/com.msgbyte.openapi/src/translate.ts b/client/web/plugins/com.msgbyte.openapi/src/translate.ts
index 16085180..7a6280f2 100644
--- a/client/web/plugins/com.msgbyte.openapi/src/translate.ts
+++ b/client/web/plugins/com.msgbyte.openapi/src/translate.ts
@@ -6,4 +6,20 @@ export const Translate = {
'zh-CN': '管理员没有开放 Openapi 服务',
'en-US': 'The administrator did not open the Openapi service',
}),
+ enableBotCapability: localTrans({
+ 'zh-CN': '开启机器人能力',
+ 'en-US': 'Enable Bot Capability',
+ }),
+ bot: {
+ callback: localTrans({
+ 'zh-CN': '消息回调地址',
+ 'en-US': 'Callback Url',
+ }),
+ callbackTip: localTrans({
+ 'zh-CN':
+ '机器人被 @ 的时候会向该地址发送请求(收件箱接受到新内容时会发送回调)',
+ 'en-US':
+ 'The bot will send a request to this address when it is mentioned (callback will be sent when the inbox receives new content)',
+ }),
+ },
};
diff --git a/server/models/openapi/app.ts b/server/models/openapi/app.ts
index 4336ae3e..f7d5c632 100644
--- a/server/models/openapi/app.ts
+++ b/server/models/openapi/app.ts
@@ -29,13 +29,14 @@ export function filterAvailableAppCapability(
) as OpenAppCapability[];
}
-class OpenAppOAuth {
- @prop({
- type: () => String,
- })
+export interface OpenAppOAuth {
redirectUrls: string[];
}
+export interface OpenAppBot {
+ callbackUrl: string;
+}
+
/**
* 开放平台应用
*/
@@ -70,11 +71,12 @@ export class OpenApp extends TimeStamps implements Base {
})
capability: OpenAppCapability[];
- @prop({
- type: () => OpenAppOAuth,
- })
+ @prop()
oauth?: OpenAppOAuth;
+ @prop()
+ bot?: OpenAppBot;
+
/**
* 根据appId获取openapp的实例
* 用于获得获得完整数据(包括secret)
diff --git a/server/services/openapi/app.service.ts b/server/services/openapi/app.service.ts
index 44631129..84741097 100644
--- a/server/services/openapi/app.service.ts
+++ b/server/services/openapi/app.service.ts
@@ -8,8 +8,10 @@ import {
import _ from 'lodash';
import {
filterAvailableAppCapability,
+ OpenAppBot,
OpenAppDocument,
OpenAppModel,
+ OpenAppOAuth,
} from '../../models/openapi/app';
import { Types } from 'mongoose';
import { nanoid } from 'nanoid';
@@ -67,6 +69,13 @@ class OpenAppService extends TcService {
fieldValue: 'any',
},
});
+ this.registerAction('setAppBotInfo', this.setAppBotInfo, {
+ params: {
+ appId: 'string',
+ fieldName: 'string',
+ fieldValue: 'any',
+ },
+ });
}
/**
@@ -201,11 +210,11 @@ class OpenAppService extends TcService {
/**
* 设置OAuth的设置信息
*/
- async setAppOAuthInfo(
+ async setAppOAuthInfo(
ctx: TcContext<{
appId: string;
- fieldName: string;
- fieldValue: any;
+ fieldName: T;
+ fieldValue: OpenAppOAuth[T];
}>
) {
const { appId, fieldName, fieldValue } = ctx.params;
@@ -233,6 +242,42 @@ class OpenAppService extends TcService {
}
);
}
+
+ /**
+ * 设置Bot的设置信息
+ */
+ async setAppBotInfo(
+ ctx: TcContext<{
+ appId: string;
+ fieldName: T;
+ fieldValue: OpenAppBot[T];
+ }>
+ ) {
+ const { appId, fieldName, fieldValue } = ctx.params;
+ const { userId } = ctx.meta;
+
+ if (!['callbackUrl'].includes(fieldName)) {
+ throw new Error('Not allowed fields');
+ }
+
+ if (fieldName === 'callbackUrl') {
+ if (typeof fieldValue !== 'string') {
+ throw new Error('`callbackUrl` should be a string');
+ }
+ }
+
+ await this.adapter.model.findOneAndUpdate(
+ {
+ appId,
+ owner: userId,
+ },
+ {
+ $set: {
+ [`bot.${fieldName}`]: fieldValue,
+ },
+ }
+ );
+ }
}
export default OpenAppService;