fix(desktop): update IM adapter setup guidance

Put Telegram first in the IM adapter settings, add a single documentation link in the setup copy, and keep per-platform settings focused on configuration.

Tested: cd desktop && bun run test AdapterSettings.test.tsx
Tested: bun run check:desktop
Scope-risk: narrow
Confidence: high
This commit is contained in:
程序员阿江(Relakkes) 2026-06-11 00:09:01 +08:00
parent e8fcccebf0
commit ae09a39e55
7 changed files with 56 additions and 15 deletions

View File

@ -444,7 +444,9 @@ export const en = {
// Settings > Adapters
'settings.tab.adapters': 'IM Adapters',
'settings.adapters.description': 'Configure IM adapters to chat with Claude Code via WeChat, DingTalk, WhatsApp, Telegram, or Feishu.',
'settings.adapters.description': 'Configure IM adapters to chat with Claude Code via Telegram, WeChat, DingTalk, WhatsApp, or Feishu. For setup details, see',
'settings.adapters.configurationDocs': 'documentation link',
'settings.adapters.descriptionAfterDocs': '.',
'settings.adapters.telegram': 'Telegram',
'settings.adapters.feishu': 'Feishu',
'settings.adapters.wechat': 'WeChat',

View File

@ -446,7 +446,9 @@ export const jp: Record<TranslationKey, string> = {
// Settings > Adapters
'settings.tab.adapters': 'IM アダプター',
'settings.adapters.description': 'WeChat、DingTalk、WhatsApp、Telegram、Feishu 経由で Claude Code とチャットできるよう IM アダプターを設定します。',
'settings.adapters.description': 'Telegram、WeChat、DingTalk、WhatsApp、Feishu 経由で Claude Code とチャットできるよう IM アダプターを設定します。詳しい設定手順は',
'settings.adapters.configurationDocs': 'ドキュメントリンク',
'settings.adapters.descriptionAfterDocs': 'を参照してください。',
'settings.adapters.telegram': 'Telegram',
'settings.adapters.feishu': 'Feishu',
'settings.adapters.wechat': 'WeChat',

View File

@ -446,7 +446,9 @@ export const kr: Record<TranslationKey, string> = {
// Settings > Adapters
'settings.tab.adapters': 'IM 어댑터',
'settings.adapters.description': 'WeChat, DingTalk, WhatsApp, Telegram, Feishu를 통해 Claude Code와 채팅할 수 있도록 IM 어댑터를 구성합니다.',
'settings.adapters.description': 'Telegram, WeChat, DingTalk, WhatsApp, Feishu를 통해 Claude Code와 채팅할 수 있도록 IM 어댑터를 구성합니다. 자세한 설정은',
'settings.adapters.configurationDocs': '문서 링크',
'settings.adapters.descriptionAfterDocs': '를 참고하세요.',
'settings.adapters.telegram': 'Telegram',
'settings.adapters.feishu': 'Feishu',
'settings.adapters.wechat': 'WeChat',

View File

@ -446,7 +446,9 @@ export const zh: Record<TranslationKey, string> = {
// Settings > Adapters
'settings.tab.adapters': 'IM 接入',
'settings.adapters.description': '配置即時通訊介面卡透過微信、釘釘、WhatsApp、Telegram 或飛書與 Claude Code 對話。',
'settings.adapters.description': '配置即時通訊介面卡,透過 Telegram、微信、釘釘、WhatsApp 或飛書與 Claude Code 對話。首次配置請參考',
'settings.adapters.configurationDocs': '文件地址',
'settings.adapters.descriptionAfterDocs': '。',
'settings.adapters.telegram': 'Telegram',
'settings.adapters.feishu': '飛書',
'settings.adapters.wechat': '微信',

View File

@ -446,7 +446,9 @@ export const zh: Record<TranslationKey, string> = {
// Settings > Adapters
'settings.tab.adapters': 'IM 接入',
'settings.adapters.description': '配置即时通讯适配器通过微信、钉钉、WhatsApp、Telegram 或飞书与 Claude Code 对话。',
'settings.adapters.description': '配置即时通讯适配器,通过 Telegram、微信、钉钉、WhatsApp 或飞书与 Claude Code 对话。首次配置请参考',
'settings.adapters.configurationDocs': '文档地址',
'settings.adapters.descriptionAfterDocs': '。',
'settings.adapters.telegram': 'Telegram',
'settings.adapters.feishu': '飞书',
'settings.adapters.wechat': '微信',

View File

@ -8,6 +8,7 @@ import { useSettingsStore } from '../stores/settingsStore'
import type { AdapterFileConfig } from '../types/adapter'
const FEISHU_CREATE_BOT_URL = 'https://open.feishu.cn/page/openclaw?form=multiAgent'
const IM_CONFIG_DOCS_URL = 'https://claudecode-haha.relakkesyang.org/im/'
function renderAdapterSettings(
config: AdapterFileConfig,
@ -44,9 +45,25 @@ afterEach(() => {
useSettingsStore.setState(useSettingsStore.getInitialState(), true)
})
describe('AdapterSettings IM setup entry', () => {
it('shows Telegram first by default and links to the unified documentation URL', () => {
renderAdapterSettings({})
const tabs = screen.getAllByRole('tab').map((tab) => tab.textContent)
expect(tabs).toEqual(['Telegram', 'Feishu', 'WeChat', 'DingTalk', 'WhatsApp'])
expect(screen.getByRole('tab', { name: 'Telegram' })).toHaveAttribute('aria-selected', 'true')
expect(screen.getByLabelText('Bot Token')).toBeInTheDocument()
expect(screen.getByRole('link', { name: 'documentation link' })).toHaveAttribute(
'href',
IM_CONFIG_DOCS_URL,
)
})
})
describe('AdapterSettings Feishu onboarding', () => {
it('shows the documented one-click Feishu bot link before credentials are configured', () => {
renderAdapterSettings({})
fireEvent.click(screen.getByRole('tab', { name: 'Feishu' }))
expect(screen.getByText('Need a Feishu bot?')).toBeInTheDocument()
expect(screen.getByText(/OpenClaw template/)).toBeInTheDocument()
@ -65,6 +82,7 @@ describe('AdapterSettings Feishu onboarding', () => {
appSecret: '****cret',
},
})
fireEvent.click(screen.getByRole('tab', { name: 'Feishu' }))
expect(screen.queryByRole('link', { name: /create feishu bot/i })).not.toBeInTheDocument()
expect(screen.queryByText('Need a Feishu bot?')).not.toBeInTheDocument()

View File

@ -7,11 +7,12 @@ import { DirectoryPicker } from '../components/shared/DirectoryPicker'
import { ConfirmDialog } from '../components/shared/ConfirmDialog'
import QRCode from 'qrcode'
type ImTab = 'feishu' | 'wechat' | 'dingtalk' | 'whatsapp' | 'telegram'
type ImTab = 'telegram' | 'feishu' | 'wechat' | 'dingtalk' | 'whatsapp'
type ImPlatform = 'telegram' | 'feishu' | 'wechat' | 'dingtalk' | 'whatsapp'
type AdapterUnbindTarget = 'wechatAccount' | 'dingtalkBot' | 'whatsappAccount'
const FEISHU_CREATE_BOT_URL = 'https://open.feishu.cn/page/openclaw?form=multiAgent'
const IM_CONFIG_DOCS_URL = 'https://claudecode-haha.relakkesyang.org/im/'
export function AdapterSettings() {
const t = useTranslation()
@ -33,8 +34,8 @@ export function AdapterSettings() {
unbindWhatsAppAccount,
} = useAdapterStore()
// Active IM tab —— Feishu 默认展示,在前
const [activeIm, setActiveIm] = useState<ImTab>('feishu')
// Active IM tab
const [activeIm, setActiveIm] = useState<ImTab>('telegram')
// Server —— serverUrl 不再暴露在 UI 里(见下方 Server URL 注释),
// 桌面端用 sidecar env var 注入动态端口。
@ -498,7 +499,19 @@ export function AdapterSettings() {
<div className="max-w-2xl space-y-8">
{/* Description */}
<div>
<p className="text-sm text-[var(--color-text-secondary)]">{t('settings.adapters.description')}</p>
<p className="text-sm leading-6 text-[var(--color-text-secondary)]">
{t('settings.adapters.description')}{' '}
<a
href={IM_CONFIG_DOCS_URL}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 font-medium text-[var(--color-brand)] transition-colors hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-brand)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg)]"
>
{t('settings.adapters.configurationDocs')}
<span className="material-symbols-outlined text-[14px]" aria-hidden="true">open_in_new</span>
</a>
{t('settings.adapters.descriptionAfterDocs')}
</p>
</div>
{/* Pairing */}
@ -587,9 +600,14 @@ export function AdapterSettings() {
</p>
</div>
{/* IM Adapter Tabs —— Feishu 默认在前Telegram 在后 */}
{/* IM Adapter Tabs */}
<section className="rounded-xl border border-[var(--color-border)] overflow-hidden">
<div role="tablist" aria-label="IM adapter" className="flex items-stretch border-b border-[var(--color-border)] bg-[var(--color-surface-hover)]">
<ImTabButton
label={t('settings.adapters.telegram')}
active={activeIm === 'telegram'}
onClick={() => setActiveIm('telegram')}
/>
<ImTabButton
label={t('settings.adapters.feishu')}
active={activeIm === 'feishu'}
@ -610,11 +628,6 @@ export function AdapterSettings() {
active={activeIm === 'whatsapp'}
onClick={() => setActiveIm('whatsapp')}
/>
<ImTabButton
label={t('settings.adapters.telegram')}
active={activeIm === 'telegram'}
onClick={() => setActiveIm('telegram')}
/>
</div>
{activeIm === 'feishu' && (