chore: bot setting updates

This commit is contained in:
Tristan Yang
2022-12-23 21:58:30 +08:00
parent aab18ae745
commit 1cb2a94b68
9 changed files with 52 additions and 9 deletions
+2
View File
@@ -84,6 +84,8 @@
}
},
"bot": {
"add_api_key": "Add API Key",
"no_api_key": "No API Key Yet",
"bot_tip_title": "Bots can send messages to channels.",
"bot_tip_desc": "Please note that we do not display a Bots API key again after generation. You can always generate a new API key of a Bot by clicking “Add API Key” and this wont nullify the previous API key(s).",
"webhook_tip_title": "Webhooks can receive messages in a channel and should a URL provided by you.",
+4
View File
@@ -82,6 +82,8 @@
}
},
"bot": {
"add_api_key": "新增API Key",
"no_api_key": "暂未创建API Key",
"bot_tip_title": "使用机器人向频道里发送消息",
"bot_tip_desc": "注意:机器人的API Key只在生成那一刻展示,如果忘记,请生成一个新的Key。",
"webhook_tip_title": "Webhook是一个用以接收VoceChat推送数据的URL地址",
@@ -90,6 +92,8 @@
"manage_desc": "机器人一旦删除,所有与其相关的接口也立即失效,包括Webhook。",
"create_title": "创建机器人",
"create_desc": "给你的机器人一个名字,同时也可以设置Webhook URL,用以接收推送的数据。",
"create_key_title": "创建机器人API Key",
"create_key_desc": "使用API Key授权机器人与VoceChat数据流通",
"delete_title": "删除机器人",
"delete_desc": "确定删除该机器人?",
"delete_key_title": "删除机器人API Key",
+3 -1
View File
@@ -24,7 +24,9 @@ const whiteList = [
"getMetamaskNonce",
"renew",
"getInitialized",
"createAdmin"
"createAdmin",
"getBotRelatedChannels",
"sendMessageByBot"
];
const baseQuery = fetchBaseQuery({
+26 -2
View File
@@ -1,5 +1,5 @@
import { createApi } from "@reduxjs/toolkit/query/react";
import BASE_URL, { PAYMENT_URL_PREFIX } from "../config";
import BASE_URL, { ContentTypes, PAYMENT_URL_PREFIX } from "../config";
import { updateInfo } from "../slices/server";
import baseQuery from "./base.query";
import { RootState } from "../store";
@@ -18,6 +18,8 @@ import {
RenewLicense,
RenewLicenseResponse
} from "../../types/server";
import { Channel } from "../../types/channel";
import { ContentTypeKey } from "../../types/message";
const defaultExpireDuration = 2 * 24 * 60 * 60;
@@ -224,7 +226,29 @@ export const serverApi = createApi({
method: "PUT",
body: { license }
})
})
}),
getBotRelatedChannels: builder.query<Channel[], { api_key: string, public_only?: boolean }>({
query: ({ api_key, public_only = false }) => ({
url: public_only ? `/bot?public_only=${public_only}` : `/bot`,
headers: {
"x-api-key": api_key
},
})
}),
sendMessageByBot: builder.mutation<number, { uid?: number, cid?: number, api_key: string, content: string, type?: ContentTypeKey, properties?: object }>({
query: ({ uid, cid, api_key, type = "text", properties, content }) => ({
headers: {
"x-api-key": api_key,
"content-type": ContentTypes[type],
"X-Properties": properties
? btoa(unescape(encodeURIComponent(JSON.stringify(properties))))
: ""
},
url: cid ? `/bot/send_to_group/${cid}` : `/bot/send_to_user/${uid}`,
method: "POST",
body: content
})
}),
})
});
+2 -1
View File
@@ -157,7 +157,8 @@ export const userApi = createApi({
});
}
}
})
}),
})
});
+3
View File
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="24" height="24" viewBox="0 0 48 48" stroke="#333" xmlns="http://www.w3.org/2000/svg">
<path d="M10.7769 30L18.019 15.0386V4H30.0283V15.0386L37.246 30" stroke-width="4" stroke-linejoin="round"/>
<path d="M7.79433 43.673C6.16744 42.8855 5.48698 40.9282 6.27449 39.3013L10.7769 30C10.7769 30 18.0001 35 24.0001 30C30.0001 25 37.2461 30 37.2461 30L41.7352 39.3052C41.9492 39.7488 42.0603 40.2348 42.0603 40.7273C42.0603 42.5347 40.595 44 38.7876 44H9.22025C8.72636 44 8.23888 43.8882 7.79433 43.673Z" stroke-width="4" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 596 B

@@ -33,6 +33,7 @@ const StyledWrapper = styled.div`
flex-direction: column;
height: calc(100% - 52px - 10px);
overflow-y: scroll;
overflow-x: hidden;
.user {
cursor: pointer;
display: flex;
+4 -4
View File
@@ -40,7 +40,7 @@ const BotAPIKeys = ({ uid }: Props) => {
return (
<div className='flex flex-col gap-2 items-start'>
<div className='border-t border-solid border-b border-gray-100 py-2 w-full'>
<table className="min-w-full table-auto font-mono">
<table className="min-w-full table-fixed font-mono">
<thead >
<tr >
{[t("col_key_name"), t('col_key_value'), t('col_key_create_time'), t('col_key_last_used'), ""].map((title, idx) => <th key={title} scope="col" className={clsx(`text-xs text-gray-900 px-1 text-left pb-2`, colWidths[idx])}>
@@ -71,14 +71,14 @@ const BotAPIKeys = ({ uid }: Props) => {
</td>
</tr>;
}) : <tr>
<td colSpan={5} className='w-full text-center text-xs text-gray-400 pt-4'>
No API Key Yet
<td colSpan={4} className='text-center text-xs text-gray-400 py-2'>
{t("no_api_key")}
</td>
</tr>}
</tbody>
</table>
<button onClick={toggleCreateModal.bind(null, uid)} className="text-green-600 text-xs py-0.5 flex items-center gap-1 m-auto my-2 bg-green-50 rounded-full px-2 ">
<IconAdd className="!w-4 !h-4 fill-green-600" /> Add API Key
<IconAdd className="!w-4 !h-4 fill-green-600" /> {t("add_api_key")}
</button>
</div>
{currentUid && <CreateAPIKeyModal uid={currentUid} closeModal={toggleCreateModal.bind(null, undefined)} />}
+7 -1
View File
@@ -7,6 +7,7 @@ import { useAppSelector } from '../../../app/store';
import AvatarUploader from '../../../common/component/AvatarUploader';
import Button from '../../../common/component/styled/Button';
import IconDelete from '../../../assets/icons/delete.svg';
// import IconTest from '../../../assets/icons/test.svg';
import CreateModal from './CreateModal';
import WebhookEdit from './WebhookEdit';
import WebhookModal from './WebhookModal';
@@ -32,6 +33,7 @@ export default function BotConfig() {
const [currDeleteParams, setCurrDeleteParams] = useState<DeleteParams | undefined>(undefined);
const bots = useAppSelector(store => Object.values(store.users.byId).filter(u => !!u.is_bot));
const { t } = useTranslation("setting", { keyPrefix: "bot" });
const { t: ct } = useTranslation();
const toggleCreateModalVisible = () => {
setCreateModalVisible(prev => !prev);
@@ -104,7 +106,11 @@ export default function BotConfig() {
</tbody>
</table>
</div>
<Button onClick={toggleCreateModalVisible} className="ghost small">Add</Button>
<Button onClick={toggleCreateModalVisible} className="ghost small">{ct("action.add")}</Button>
{/* <div className="flex gap-4">
<Button onClick={toggleCreateModalVisible} className="small">{ct("action.add")}</Button>
<Button onClick={toggleCreateModalVisible} className="ghost small stroke-slate-200 fill-gray-200"> Test API Key</Button>
</div> */}
</div>
{createModalVisible && <CreateModal closeModal={toggleCreateModalVisible} />}