add fake channel

This commit is contained in:
2026-07-09 18:14:45 +08:00
parent 8fed449b95
commit 9c852cd99b
37 changed files with 4300 additions and 679 deletions
@@ -67,6 +67,7 @@ const isActive = computed(() => {
'instagram',
'tiktok',
'voice',
'fake',
].includes(key);
});
@@ -382,6 +382,34 @@
"ERROR_MESSAGE": "We were not able to save the api channel"
}
},
"FAKE_CHANNEL": {
"TITLE": "Fake Test Channel",
"DESC": "Create a Fake message channel for automated integration testing.",
"CHANNEL_NAME": {
"LABEL": "Channel Name",
"PLACEHOLDER": "Please enter a channel name",
"ERROR": "This field is required"
},
"IDENTIFIER": {
"LABEL": "Identifier",
"PLACEHOLDER": "e.g. fake_test_1",
"ERROR": "This field is required"
},
"WEBHOOK_URL": {
"LABEL": "Webhook URL",
"SUBTITLE": "FakeMessagePlatform callback receive endpoint (e.g. http://127.0.0.1:9100/receive).",
"PLACEHOLDER": "Webhook URL"
},
"TOKEN": {
"LABEL": "Token (optional)",
"SUBTITLE": "Shared secret for X-Fake-Token header verification.",
"PLACEHOLDER": "Token"
},
"SUBMIT_BUTTON": "Create Fake Channel",
"API": {
"ERROR_MESSAGE": "We were not able to create the fake channel"
}
},
"EMAIL_CHANNEL": {
"TITLE": "Email Channel",
"DESC": "Integrate your email inbox.",
@@ -489,6 +517,10 @@
"TITLE": "Instagram",
"DESCRIPTION": "Connect your instagram account"
},
"FAKE": {
"TITLE": "Fake Test Platform",
"DESCRIPTION": "Create a Fake message channel for automated integration testing"
},
"TIKTOK": {
"TITLE": "TikTok",
"DESCRIPTION": "Connect your TikTok account"
@@ -1165,7 +1197,8 @@
"API": "API Channel",
"INSTAGRAM": "Instagram",
"TIKTOK": "TikTok",
"VOICE": "Voice"
"VOICE": "Voice",
"FAKE": "Fake Test Channel"
}
}
}
@@ -382,6 +382,34 @@
"ERROR_MESSAGE": "我们无法保存 api 频道"
}
},
"FAKE_CHANNEL": {
"TITLE": "Fake 测试频道",
"DESC": "创建一个 Fake 消息渠道,用于自动化集成测试。",
"CHANNEL_NAME": {
"LABEL": "频道名称",
"PLACEHOLDER": "请输入频道名称",
"ERROR": "此字段是必填项"
},
"IDENTIFIER": {
"LABEL": "标识符",
"PLACEHOLDER": "例如 fake_test_1",
"ERROR": "此字段是必填项"
},
"WEBHOOK_URL": {
"LABEL": "Webhook URL",
"SUBTITLE": "FakeMessagePlatform 的回调接收端点(例如 http://127.0.0.1:9100/receive)。",
"PLACEHOLDER": "Webhook URL"
},
"TOKEN": {
"LABEL": "Token(可选)",
"SUBTITLE": "用于 X-Fake-Token 头验证的共享密钥。",
"PLACEHOLDER": "Token"
},
"SUBMIT_BUTTON": "创建 Fake 频道",
"API": {
"ERROR_MESSAGE": "我们无法创建 fake 频道"
}
},
"EMAIL_CHANNEL": {
"TITLE": "电子邮件频道",
"DESC": "集成您的电子邮件收件箱。",
@@ -489,6 +517,10 @@
"TITLE": "Instagram",
"DESCRIPTION": "连接您的 instagram 帐户"
},
"FAKE": {
"TITLE": "Fake 测试平台",
"DESCRIPTION": "创建用于自动化测试的 Fake 消息渠道"
},
"TIKTOK": {
"TITLE": "TikTok",
"DESCRIPTION": "Connect your TikTok account"
@@ -1165,7 +1197,8 @@
"API": "API 频道",
"INSTAGRAM": "Instagram",
"TIKTOK": "TikTok",
"VOICE": "语音"
"VOICE": "语音",
"FAKE": "Fake 测试频道"
}
}
}
@@ -12,6 +12,7 @@ import Telegram from './channels/Telegram.vue';
import Instagram from './channels/Instagram.vue';
import Tiktok from './channels/Tiktok.vue';
import Voice from './channels/Voice.vue';
import Fake from './channels/Fake.vue';
const channelViewList = {
facebook: Facebook,
@@ -26,6 +27,7 @@ const channelViewList = {
instagram: Instagram,
tiktok: Tiktok,
voice: Voice,
fake: Fake,
};
export default defineComponent({
@@ -77,6 +77,12 @@ const channelList = computed(() => {
description: t('INBOX_MGMT.ADD.AUTH.CHANNEL.INSTAGRAM.DESCRIPTION'),
icon: 'i-woot-instagram',
},
{
key: 'fake',
title: t('INBOX_MGMT.ADD.AUTH.CHANNEL.FAKE.TITLE'),
description: t('INBOX_MGMT.ADD.AUTH.CHANNEL.FAKE.DESCRIPTION'),
icon: 'i-woot-api',
},
];
if (hasTiktokConfigured.value) {
@@ -0,0 +1,164 @@
<script>
import { mapGetters } from 'vuex';
import { useVuelidate } from '@vuelidate/core';
import { useAlert } from 'dashboard/composables';
import { required } from '@vuelidate/validators';
import router from '../../../../index';
import PageHeader from '../../SettingsSubPageHeader.vue';
import NextButton from 'dashboard/components-next/button/Button.vue';
const shouldBeWebhookUrl = (value = '') =>
value ? value.startsWith('http') : true;
export default {
components: {
PageHeader,
NextButton,
},
setup() {
return { v$: useVuelidate() };
},
data() {
return {
channelName: '',
identifier: '',
webhookUrl: '',
token: '',
};
},
computed: {
...mapGetters({
uiFlags: 'inboxes/getUIFlags',
}),
},
validations: {
channelName: { required },
identifier: { required },
webhookUrl: { shouldBeWebhookUrl },
},
methods: {
async createChannel() {
this.v$.$touch();
if (this.v$.$invalid) {
return;
}
try {
const fakeChannel = await this.$store.dispatch(
'inboxes/createChannel',
{
name: this.channelName?.trim(),
channel: {
type: 'fake',
identifier: this.identifier?.trim(),
webhook_url: this.webhookUrl?.trim(),
token: this.token?.trim(),
},
}
);
router.replace({
name: 'settings_inboxes_add_agents',
params: {
page: 'new',
inbox_id: fakeChannel.id,
},
});
} catch (error) {
useAlert(
error.message ||
this.$t('INBOX_MGMT.ADD.FAKE_CHANNEL.API.ERROR_MESSAGE')
);
}
},
},
};
</script>
<template>
<div class="h-full w-full p-6 col-span-6">
<PageHeader
:header-title="$t('INBOX_MGMT.ADD.FAKE_CHANNEL.TITLE')"
:header-content="$t('INBOX_MGMT.ADD.FAKE_CHANNEL.DESC')"
/>
<form
class="flex flex-wrap flex-col mx-0"
@submit.prevent="createChannel()"
>
<div class="flex-shrink-0 flex-grow-0">
<label :class="{ error: v$.channelName.$error }">
{{ $t('INBOX_MGMT.ADD.FAKE_CHANNEL.CHANNEL_NAME.LABEL') }}
<input
v-model="channelName"
type="text"
:placeholder="
$t('INBOX_MGMT.ADD.FAKE_CHANNEL.CHANNEL_NAME.PLACEHOLDER')
"
@blur="v$.channelName.$touch"
/>
<span v-if="v$.channelName.$error" class="message">{{
$t('INBOX_MGMT.ADD.FAKE_CHANNEL.CHANNEL_NAME.ERROR')
}}</span>
</label>
</div>
<div class="flex-shrink-0 flex-grow-0">
<label :class="{ error: v$.identifier.$error }">
{{ $t('INBOX_MGMT.ADD.FAKE_CHANNEL.IDENTIFIER.LABEL') }}
<input
v-model="identifier"
type="text"
:placeholder="
$t('INBOX_MGMT.ADD.FAKE_CHANNEL.IDENTIFIER.PLACEHOLDER')
"
@blur="v$.identifier.$touch"
/>
<span v-if="v$.identifier.$error" class="message">{{
$t('INBOX_MGMT.ADD.FAKE_CHANNEL.IDENTIFIER.ERROR')
}}</span>
</label>
</div>
<div class="flex-shrink-0 flex-grow-0">
<label :class="{ error: v$.webhookUrl.$error }">
{{ $t('INBOX_MGMT.ADD.FAKE_CHANNEL.WEBHOOK_URL.LABEL') }}
<input
v-model="webhookUrl"
type="text"
:placeholder="
$t('INBOX_MGMT.ADD.FAKE_CHANNEL.WEBHOOK_URL.PLACEHOLDER')
"
@blur="v$.webhookUrl.$touch"
/>
<p class="help-text">
{{ $t('INBOX_MGMT.ADD.FAKE_CHANNEL.WEBHOOK_URL.SUBTITLE') }}
</p>
</label>
</div>
<div class="flex-shrink-0 flex-grow-0">
<label>
{{ $t('INBOX_MGMT.ADD.FAKE_CHANNEL.TOKEN.LABEL') }}
<input
v-model="token"
type="text"
:placeholder="$t('INBOX_MGMT.ADD.FAKE_CHANNEL.TOKEN.PLACEHOLDER')"
/>
<p class="help-text">
{{ $t('INBOX_MGMT.ADD.FAKE_CHANNEL.TOKEN.SUBTITLE') }}
</p>
</label>
</div>
<div class="w-full mt-4">
<NextButton
:is-loading="uiFlags.isCreating"
type="submit"
solid
blue
:label="$t('INBOX_MGMT.ADD.FAKE_CHANNEL.SUBMIT_BUTTON')"
/>
</div>
</form>
</div>
</template>