How to Add a Custom Backend for an Unsupported Platform in Agent Reach
To add a custom backend for an unsupported platform in Agent Reach, create a new channel class inheriting from Channel in agent_reach/channels/, implement the can_handle and check methods, and register it in agent_reach/channels/__init__.py.
Agent Reach is an extensible automation framework that treats every internet platform as a channel. When you need to integrate an unsupported platform, you extend the channel architecture in the Panniantong/Agent-Reach repository. This guide walks through the exact steps to add a custom backend for an unsupported platform in Agent Reach, referencing the actual source files and implementation patterns used by existing channels like Twitter and YouTube.
Understand the Channel Architecture
The foundation of every platform integration is the abstract Channel base class defined in agent_reach/channels/base.py. Each channel represents a specific platform (e.g., Twitter, YouTube) and manages one or more backends—upstream runtimes like yt-dlp, twitter-cli, or OpenCLI that perform the actual work.
The Channel contract requires these specific attributes and methods:
name(str): Short identifier used in configuration keys (<channel>_backend).description(str): Human-readable description shown by thedoctorcommand.backends(List[str]): Ordered list of candidate backends; the first usable one becomesactive_backend.tier(int):0for zero-config,1for free API key,2for complex setup.can_handle(url): ReturnsTrueif the URL belongs to this platform.check(config): Probes the backends, setsself.active_backend, and returns a(status, message)tuple.
The base class provides the generic ordered_backends implementation, so you normally do not need to override backend selection logic.
Create a New Channel Module
Create a file named <platform>.py under agent_reach/channels/. Use existing channels such as agent_reach/channels/twitter.py or agent_reach/channels/youtube.py as templates. Below is a minimal example for a fictional "ExampleSocial" platform that reuses the shared OpenCLI backend.
# agent_reach/channels/example_social.py
# -*- coding: utf-8 -*-
"""ExampleSocial – a new platform that reuses the OpenCLI backend."""
from .base import Channel
from agent_reach.backends import opencli_status
class ExampleSocialChannel(Channel):
name = "examplesocial"
description = "ExampleSocial posts and comments"
# OpenCLI can drive this platform; list dedicated CLIs here if needed
backends = ["OpenCLI"]
tier = 0 # No API key required
def can_handle(self, url: str) -> bool:
from urllib.parse import urlparse
host = urlparse(url).netloc.lower()
return "examplesocial.com" in host
def check(self, config=None):
"""Probe OpenCLI; delegate to the shared status helper."""
st = opencli_status()
if not st.installed:
return "warn", (
"OpenCLI 未安装。安装方式:\n"
" npm install -g @jackwener/opencli"
)
if st.broken:
return "error", st.hint
if st.ready:
self.active_backend = "OpenCLI"
return "ok", "OpenCLI 可用(复用浏览器登录态)"
return "warn", st.hint
Key implementation details:
- The channel
namebecomes the configuration keyexamplesocial_backend. - The
backendslist tells the framework which runtimes to probe; the probing logic for OpenCLI resides inagent_reach/backends/opencli.py. - The
checkmethod mirrors the pattern inagent_reach/channels/twitter.py—it callsopencli_status(), assignsself.active_backend, and returns a status tuple.
Implementing a Dedicated Backend
If your platform requires a specific CLI tool (e.g., example-cli) instead of OpenCLI, add it to the backends list and implement a private probing method similar to _check_twitter_cli in agent_reach/channels/twitter.py. This method should verify the binary exists and return availability status.
Register the Channel in the Global Registry
After creating the channel module, you must expose it to the framework by updating the global registry in agent_reach/channels/__init__.py.
Import your new class and append an instance to ALL_CHANNELS:
# agent_reach/channels/__init__.py
...
from .example_social import ExampleSocialChannel
...
ALL_CHANNELS: List[Channel] = [
GitHubChannel(),
TwitterChannel(),
YouTubeChannel(),
RedditChannel(),
BilibiliChannel(),
XiaoHongShuChannel(),
LinkedInChannel(),
XiaoyuzhouChannel(),
V2EXChannel(),
XueqiuChannel(),
RSSChannel(),
ExaSearchChannel(),
WebChannel(),
ExampleSocialChannel(), # <-- newly added
]
This registration makes the channel visible to the CLI doctor command and the core routing logic.
Implement Platform-Specific Operations
If the platform supports reading posts, searching, or transcribing media, implement the corresponding optional methods. For example, a read method might invoke an upstream API wrapper. Follow the lazy import pattern used in YouTubeChannel.transcribe to avoid loading heavy dependencies when the feature is unused:
def transcribe(self, url: str, config=None):
from agent_reach.utils.media import download_audio
# Implementation here
Test Your Custom Backend
Validate your implementation by running the project's test suite:
pytest tests/ -v
Create unit tests in tests/test_<platform>_channel.py following the structure of tests/test_twitter_channel.py. Verify that:
can_handle()correctly identifies platform URLs.check()setsactive_backendto the expected backend under different probe outcomes.- The channel appears in the
get_all_channels()registry.
Summary
- Create a new channel class inheriting from
Channelinagent_reach/channels/to define the platform contract. - Implement
can_handle()for URL identification andcheck()for backend probing according to the interface inagent_reach/channels/base.py. - Reuse existing backends like OpenCLI via
agent_reach/backends/opencli.pyor implement dedicated probing logic similar toagent_reach/channels/twitter.py. - Register the channel instance in
ALL_CHANNELSinsideagent_reach/channels/__init__.pyto activate it. - Write unit tests following the pattern in
tests/test_twitter_channel.pyto ensure stability.
Frequently Asked Questions
What is the difference between a channel and a backend in Agent Reach?
A channel is the abstract representation of a platform (e.g., Twitter, YouTube) that inherits from the Channel base class in agent_reach/channels/base.py. A backend is the actual runtime tool or CLI (e.g., twitter-cli, yt-dlp, OpenCLI) that executes commands for that platform. The channel's check() method probes the backends list to determine which runtime is available and sets active_backend accordingly.
Can I use multiple backends for a single platform?
Yes. The backends attribute accepts an ordered list of strings. Agent Reach probes them sequentially, and the first usable backend becomes the active_backend. For example, the Twitter channel in agent_reach/channels/twitter.py can fall back from a dedicated CLI to OpenCLI if the primary tool is unavailable.
How do I handle authentication for my custom backend?
Authentication is typically handled by the backend itself (e.g., OpenCLI inherits browser login states). If your backend requires API keys, set tier = 1 or tier = 2 in your channel class and read the configuration in the check() method. Store sensitive credentials in Agent Reach's config system rather than hardcoding them in agent_reach/channels/<platform>.py.
Where should I place unit tests for my new channel?
Create a test file in the tests/ directory following the naming convention test_<platform>_channel.py. Mirror the test patterns found in tests/test_twitter_channel.py, which verify that can_handle() correctly identifies URLs and that check() sets the active_backend attribute under different probe outcomes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →