Skip to content

Commit 8f95679

Browse files
committed
feat(messaging): implement fallback definitions for channel connections in MessagingPanel
- Added fallback definitions for Telegram and Discord channels to enhance messaging capabilities when backend is unreachable. - Updated MessagingPanel to utilize fallback definitions if backend data is unavailable, improving error handling and user experience. - Refactored API service methods to return results directly, streamlining data retrieval for channel definitions and statuses.
1 parent a241574 commit 8f95679

3 files changed

Lines changed: 116 additions & 30 deletions

File tree

app/src/components/settings/panels/MessagingPanel.tsx

Lines changed: 99 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,82 @@ const AUTH_MODE_LABELS: Record<string, string> = {
4141
api_key: 'API Key',
4242
};
4343

44+
/** Fallback definitions used when the core sidecar is unreachable. */
45+
const FALLBACK_DEFINITIONS: ChannelDefinition[] = [
46+
{
47+
id: 'telegram',
48+
display_name: 'Telegram',
49+
description: 'Send and receive messages via Telegram.',
50+
icon: 'telegram',
51+
auth_modes: [
52+
{
53+
mode: 'bot_token',
54+
description: 'Provide your own Telegram Bot token from @BotFather.',
55+
fields: [
56+
{
57+
key: 'bot_token',
58+
label: 'Bot Token',
59+
field_type: 'secret',
60+
required: true,
61+
placeholder: '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
62+
},
63+
{
64+
key: 'allowed_users',
65+
label: 'Allowed Users',
66+
field_type: 'string',
67+
required: false,
68+
placeholder: 'Comma-separated Telegram usernames',
69+
},
70+
],
71+
auth_action: undefined,
72+
},
73+
{
74+
mode: 'managed_dm',
75+
description: 'Message the OpenHuman Telegram bot directly.',
76+
fields: [],
77+
auth_action: 'telegram_managed_dm',
78+
},
79+
],
80+
capabilities: ['send_text', 'receive_text', 'typing', 'draft_updates'],
81+
},
82+
{
83+
id: 'discord',
84+
display_name: 'Discord',
85+
description: 'Send and receive messages via Discord.',
86+
icon: 'discord',
87+
auth_modes: [
88+
{
89+
mode: 'bot_token',
90+
description: 'Provide your own Discord bot token.',
91+
fields: [
92+
{
93+
key: 'bot_token',
94+
label: 'Bot Token',
95+
field_type: 'secret',
96+
required: true,
97+
placeholder: 'Your Discord bot token',
98+
},
99+
{
100+
key: 'guild_id',
101+
label: 'Server (Guild) ID',
102+
field_type: 'string',
103+
required: false,
104+
placeholder: 'Optional: restrict to a specific server',
105+
},
106+
],
107+
auth_action: undefined,
108+
},
109+
{
110+
mode: 'oauth',
111+
description: 'Install the OpenHuman bot to your Discord server via OAuth.',
112+
fields: [],
113+
auth_action: 'discord_oauth',
114+
},
115+
],
116+
capabilities: ['send_text', 'receive_text', 'typing', 'threaded_replies'],
117+
},
118+
];
119+
44120
const MessagingPanel = () => {
45121
const { navigateBack } = useSettingsNavigation();
46122
const dispatch = useAppDispatch();
@@ -65,31 +141,37 @@ const MessagingPanel = () => {
65141
const load = async () => {
66142
try {
67143
const [defs, statusEntries] = await Promise.all([
68-
channelConnectionsApi.listDefinitions(),
69-
channelConnectionsApi.listStatus(),
144+
channelConnectionsApi.listDefinitions().catch(() => null),
145+
channelConnectionsApi.listStatus().catch(() => null),
70146
]);
71147
if (cancelled) return;
72148

73-
setDefinitions(defs);
74-
75-
// Sync status into Redux.
76-
for (const entry of statusEntries) {
77-
const channel = entry.channel_id as ChannelType;
78-
const authMode = entry.auth_mode as ChannelAuthMode;
79-
if (entry.connected) {
80-
dispatch(
81-
upsertChannelConnection({
82-
channel,
83-
authMode,
84-
patch: { status: 'connected', capabilities: ['read', 'write'] },
85-
})
86-
);
149+
// Use backend definitions if available, otherwise fall back.
150+
const resolvedDefs =
151+
defs && Array.isArray(defs) && defs.length > 0 ? defs : FALLBACK_DEFINITIONS;
152+
setDefinitions(resolvedDefs);
153+
154+
// Sync status into Redux when available.
155+
if (statusEntries && Array.isArray(statusEntries)) {
156+
for (const entry of statusEntries) {
157+
const channel = entry.channel_id as ChannelType;
158+
const authMode = entry.auth_mode as ChannelAuthMode;
159+
if (entry.connected) {
160+
dispatch(
161+
upsertChannelConnection({
162+
channel,
163+
authMode,
164+
patch: { status: 'connected', capabilities: ['read', 'write'] },
165+
})
166+
);
167+
}
87168
}
88169
}
89170
} catch (e) {
90171
const msg = e instanceof Error ? e.message : String(e);
91172
if (!cancelled) {
92-
setError(`Could not load channel definitions: ${msg}`);
173+
setDefinitions(FALLBACK_DEFINITIONS);
174+
setError(`Could not load from backend: ${msg}`);
93175
}
94176
} finally {
95177
if (!cancelled) setLoading(false);

app/src/services/api/channelConnectionsApi.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,34 @@ interface ConnectChannelPayload {
1515
export const channelConnectionsApi = {
1616
/** Fetch all available channel definitions from the backend. */
1717
listDefinitions: async (): Promise<ChannelDefinition[]> => {
18-
const response = await callCoreRpc<{ result: ChannelDefinition[] }>({
18+
const result = await callCoreRpc<ChannelDefinition[]>({
1919
method: 'openhuman.channels_list',
2020
params: {},
2121
});
22-
return response.result ?? [];
22+
return result;
2323
},
2424

2525
/** Get connection status for one or all channels. */
2626
listStatus: async (channel?: ChannelType): Promise<ChannelStatusEntry[]> => {
2727
const params: Record<string, string> = {};
2828
if (channel) params.channel = channel;
29-
const response = await callCoreRpc<{ result: ChannelStatusEntry[] }>({
29+
const result = await callCoreRpc<ChannelStatusEntry[]>({
3030
method: 'openhuman.channels_status',
3131
params,
3232
});
33-
return response.result ?? [];
33+
return result;
3434
},
3535

3636
/** Connect a channel with the given auth mode and credentials. */
3737
connectChannel: async (
3838
channel: ChannelType,
3939
payload: ConnectChannelPayload
4040
): Promise<ChannelConnectionResult> => {
41-
const response = await callCoreRpc<{ result: ChannelConnectionResult }>({
41+
const result = await callCoreRpc<ChannelConnectionResult>({
4242
method: 'openhuman.channels_connect',
4343
params: { channel, authMode: payload.authMode, credentials: payload.credentials ?? {} },
4444
});
45-
return response.result;
45+
return result;
4646
},
4747

4848
/** Disconnect a channel for a given auth mode. */
@@ -56,11 +56,11 @@ export const channelConnectionsApi = {
5656
authMode: ChannelAuthMode,
5757
credentials: Record<string, string>
5858
): Promise<{ success: boolean; message: string }> => {
59-
const response = await callCoreRpc<{ result: { success: boolean; message: string } }>({
59+
const result = await callCoreRpc<{ success: boolean; message: string }>({
6060
method: 'openhuman.channels_test',
6161
params: { channel, authMode, credentials },
6262
});
63-
return response.result;
63+
return result;
6464
},
6565

6666
/** Placeholder for default channel preference sync. */

docs/TODO.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ todo
1717
[] Integrate our custom memory engine into core - sanil
1818
[] Integrate our skills registry into core - steve
1919
[x] Integrate accessibility service installation
20-
[] Add as a step and setting in the UI - cyrus
21-
[x] Remove mentions of zeroclaw from the codebaes
22-
[x] Integrate local LLM into core
20+
[] Add as a step and setting in the UI - cyrus
21+
[x] Remove mentions of zeroclaw from the codebaes
22+
[x] Integrate local LLM into core
2323
[x] Handle process/deamon properly
2424
[x] install the linux philosophy of few modules that do their own thing really well sort of..
2525
[x] Remove android / ios support from the codebase.
@@ -29,9 +29,13 @@ todo
2929
[] Add icon and app name to the various permission settings - mithil
3030
[] add self update based on github release. create a update action on the cli - aniketh
3131
[] for each skill show information on how much data has been synced locally and information on how much syncs have happened so far etc.. - mithil/elvin
32-
[x] redo the docs once everything is done.
32+
[x] redo the docs once everything is done.
3333
[x] remove unwanted feature flags from the rust binary
3434
[] fix the config properly - mithil
3535
[] Allow for Migrating from OpenClaw - steve done - to be tested
3636
[] allow users to choose which version of LLM model they'd like to choose based on their CPU. better ram and gpu means higher parameter model can be used. - mithil
37-
[x] in the client side app, make console.log follow a logger style logging where there's a namespace for every logger (like python) - steve
37+
[x] in the client side app, make console.log follow a logger style logging where there's a namespace for every logger (like python) - steve
38+
39+
--- e2e tests to write up
40+
41+
- [ ] connecting a channel like telegram/discord works properly

0 commit comments

Comments
 (0)