Skip to content

feat(channels): complete Telegram Managed DM flow and realtime sync (#288)#322

Merged
senamakel merged 13 commits intotinyhumansai:mainfrom
oxoxDev:feat/channels-managed-dm-288
Apr 4, 2026
Merged

feat(channels): complete Telegram Managed DM flow and realtime sync (#288)#322
senamakel merged 13 commits intotinyhumansai:mainfrom
oxoxDev:feat/channels-managed-dm-288

Conversation

@oxoxDev
Copy link
Copy Markdown
Contributor

@oxoxDev oxoxDev commented Apr 4, 2026

Summary

  • completes the Telegram Managed DM user flow on the Channels page in a polished, product-feeling state
  • adds managed DM API client helpers for initiate/status/poll behavior with focused unit tests
  • wires realtime channel updates so managed DM verification reflects in UI connection state
  • merges latest main into this branch to keep the diff reviewable and current

Problem

Solution

  • integrate Managed DM initiate flow in Telegram channel config and launch Telegram deep-link reliably
  • add polling fallback and connection-state transitions (connecting -> connected / error) for robust UX
  • normalize socket-driven managed DM connection updates to shared channel connection state
  • add targeted tests for TelegramConfig and managedDmApi behavior

Submission Checklist

  • Unit tests — Vitest for TelegramConfig and managedDmApi
  • E2E / integration — Follow-up in [Channels] E2E verification and test coverage for Telegram + Discord #290
  • N/A — Rust/core tests not applicable for this UI/API-client scoped change
  • Doc comments — Existing module naming and API shape kept clear; no new public Rust API
  • Inline comments — Kept code paths explicit without adding noisy comments

Impact

  • Improves Telegram channel onboarding reliability and user confidence in /channels
  • No migration required
  • Low runtime risk, scoped to channel auth UI/state handling

Related

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Telegram managed direct message connection enabling authentication via deep links, real-time verification monitoring with automatic error recovery, user-friendly error notifications, and comprehensive resource cleanup on disconnect or application close.
  • Tests

    • Expanded test coverage for managed DM authentication workflows, verification monitoring, API interactions, and real-time event updates.

oxoxDev and others added 13 commits April 3, 2026 15:50
Move FALLBACK_DEFINITIONS, STATUS_STYLES, and AUTH_MODE_LABELS from
MessagingPanel into a shared module so both the settings panel and
the upcoming Channels page can reuse them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…abilities

Reusable UI primitives for the Channels page: status pill badge,
credential form input, and capability chip list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shared hook that loads channel definitions and status from the core
RPC, falls back to local definitions, and syncs Redux state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tab bar component showing Web / Telegram / Discord with connection
status badges and active route summary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…flow

Channel-specific config panels with per-auth-mode credential fields,
connect/disconnect, status badges, and error handling. TelegramConfig
includes the managed DM deep link initiation flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ChannelConfigPanel switches between Telegram/Discord/Web configs based
on selection. WebChannelConfig shows a simple always-connected card.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Top-level /channels page with ChannelSelector + ChannelConfigPanel.
Updates sidebar nav to point to /channels instead of /settings/messaging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…onents

Replace inline loading logic with useChannelDefinitions hook, inline
status badges with ChannelStatusBadge, and inline capability chips
with ChannelCapabilities. Reduces duplication with the new Channels page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

📝 Walkthrough

Walkthrough

Added a managed DM connection flow for Telegram authentication. Implemented managedDmApi module with functions to initiate managed DM setup, poll verification status with configurable timeout/interval, and handle abort signals. Updated TelegramConfig component to call initiate, open the deep link, poll until verified, and cleanup on disconnect. Added socket event handler for backend verification notifications.

Changes

Cohort / File(s) Summary
Managed DM API
app/src/services/api/managedDmApi.ts, app/src/services/api/__tests__/managedDmApi.test.ts
New API module with typed contracts (ManagedDmInitiateResponse, ManagedDmStatusResponse, ManagedDmPollOptions) and three exported functions: initiateManagedDm(), getManagedDmStatus(), and pollManagedDmStatusUntilVerified() with configurable polling interval/timeout and AbortSignal support. Tests verify POST/GET calls and polling termination logic.
Telegram Config Component
app/src/components/channels/TelegramConfig.tsx, app/src/components/channels/__tests__/TelegramConfig.test.tsx
Updated component to initiate managed DM, open Telegram deep link, and poll for verification using AbortController per connection key. Replaces prior follow-up message handling with full initiate-poll-verify flow. On success, upserts connected channel with ['dm'] capabilities; on failure, sets error state. Cleanup aborts all polling on disconnect and unmount. Tests refactored to assert the full async flow.
Socket Event Handler
app/src/services/socketService.ts
Added channel:managed-dm-verified socket event handler that validates payload, extracts token, telegramUsername, and chatId, and dispatches upsertChannelConnection for Telegram with managed_dm auth mode and connected status.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant TelegramConfig as TelegramConfig
    participant ManagedDmApi as managedDmApi
    participant Backend as Backend
    participant TelegramDeepLink as Telegram Deep Link
    participant SocketService as Socket Service

    User->>TelegramConfig: Click Connect (Managed DM)
    TelegramConfig->>ManagedDmApi: initiateManagedDm()
    ManagedDmApi->>Backend: POST /telegram/managed-dm/initiate
    Backend-->>ManagedDmApi: {token, deepLink, expiresAt}
    ManagedDmApi-->>TelegramConfig: {token, deepLink, expiresAt}
    
    TelegramConfig->>TelegramDeepLink: openUrl(deepLink)
    User->>TelegramDeepLink: Complete verification
    
    TelegramConfig->>ManagedDmApi: pollManagedDmStatusUntilVerified(token, {signal})
    loop Poll until verified (interval: 3s, timeout: 5min)
        ManagedDmApi->>Backend: GET /telegram/managed-dm/status/{token}
        alt Verified
            Backend-->>ManagedDmApi: {verified: true, telegramUsername}
            ManagedDmApi-->>TelegramConfig: {verified: true, ...}
        else Not yet verified
            Backend-->>ManagedDmApi: {verified: false}
            ManagedDmApi->>ManagedDmApi: Sleep 3s
        else Timeout/Error
            ManagedDmApi-->>TelegramConfig: null
        end
    end
    
    Backend->>SocketService: channel:managed-dm-verified event
    SocketService->>SocketService: upsertChannelConnection(telegram, managed_dm, connected)
    
    TelegramConfig->>TelegramConfig: Update UI: Connected
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • [Channels] Telegram Managed DM auth and user mapping #288: Directly aligns with implementing the frontend managed-DM flow (initiate/poll API, UI state handling, socket event integration) for Telegram authentication, matching the goal of adding Telegram Managed DM auth and wiring the complete connection flow.

Poem

🐰 A hop and a poll, a deep link so true,
Telegram connects with managed DM brand new!
AbortController stands guard with a sigh,
Verification blooms when the socket says hi,
Connected at last—what a marvelous sight! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(channels): complete Telegram Managed DM flow and realtime sync (#288)' clearly and concisely summarizes the main change across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
app/src/services/api/__tests__/managedDmApi.test.ts (1)

30-39: Good polling test, but consider adding timeout and abort coverage.

The test validates the happy path where polling succeeds on the second attempt. Consider adding tests for:

  • Timeout expiration (returns null)
  • AbortSignal cancellation (returns null early)
Example test for timeout behavior
it('returns null when polling times out', async () => {
  apiClient.get.mockResolvedValue({ data: { verified: false, telegramUsername: null } });

  await expect(
    managedDmApi.pollManagedDmStatusUntilVerified('dm-token', { intervalMs: 10, timeoutMs: 25 })
  ).resolves.toBeNull();
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/services/api/__tests__/managedDmApi.test.ts` around lines 30 - 39,
Add unit tests for pollManagedDmStatusUntilVerified to cover timeout and
AbortSignal cancellation: create one test where apiClient.get always returns {
verified: false } and call managedDmApi.pollManagedDmStatusUntilVerified with a
short timeoutMs (e.g., intervalMs small, timeoutMs small) and assert it resolves
to null; create another test that passes an AbortSignal which is aborted early
and assert the function resolves to null immediately, using apiClient.get mocks
and referencing managedDmApi.pollManagedDmStatusUntilVerified and apiClient.get
to locate the code under test.
app/src/services/api/managedDmApi.ts (1)

86-88: Consider adding debug logging for polling errors.

The empty catch block silently swallows network errors during polling. While "best-effort polling" is the right strategy, adding debug logging would help diagnose issues in production:

Suggested enhancement
+import debug from 'debug';
+const log = debug('api:managedDm');

     } catch {
-      // Best-effort polling: keep trying until timeout or cancellation.
+      // Best-effort polling: keep trying until timeout or cancellation.
+      log('poll attempt failed, retrying...');
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/services/api/managedDmApi.ts` around lines 86 - 88, The empty catch
that follows the "Best-effort polling: keep trying until timeout or
cancellation." comment should log caught errors at debug/trace level rather than
silently swallow them; inside that catch in the polling routine, call the
project's logger (e.g., logger.debug or this.logger.debug) and include the error
object and minimal context (operation name, attempt count or timeout info) but
keep the current behavior of not rethrowing so polling remains best-effort.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/src/services/api/__tests__/managedDmApi.test.ts`:
- Around line 30-39: Add unit tests for pollManagedDmStatusUntilVerified to
cover timeout and AbortSignal cancellation: create one test where apiClient.get
always returns { verified: false } and call
managedDmApi.pollManagedDmStatusUntilVerified with a short timeoutMs (e.g.,
intervalMs small, timeoutMs small) and assert it resolves to null; create
another test that passes an AbortSignal which is aborted early and assert the
function resolves to null immediately, using apiClient.get mocks and referencing
managedDmApi.pollManagedDmStatusUntilVerified and apiClient.get to locate the
code under test.

In `@app/src/services/api/managedDmApi.ts`:
- Around line 86-88: The empty catch that follows the "Best-effort polling: keep
trying until timeout or cancellation." comment should log caught errors at
debug/trace level rather than silently swallow them; inside that catch in the
polling routine, call the project's logger (e.g., logger.debug or
this.logger.debug) and include the error object and minimal context (operation
name, attempt count or timeout info) but keep the current behavior of not
rethrowing so polling remains best-effort.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5f8f0653-dc76-4ba5-8c97-be2b270439fb

📥 Commits

Reviewing files that changed from the base of the PR and between ef708bd and dffa159.

📒 Files selected for processing (5)
  • app/src/components/channels/TelegramConfig.tsx
  • app/src/components/channels/__tests__/TelegramConfig.test.tsx
  • app/src/services/api/__tests__/managedDmApi.test.ts
  • app/src/services/api/managedDmApi.ts
  • app/src/services/socketService.ts

@senamakel senamakel merged commit b40449b into tinyhumansai:main Apr 4, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants