Skip to content

Commit ca4907d

Browse files
teknium1penwyp
andauthored
feat(gateway): add Feishu/Lark platform support (#3817)
Adds Feishu (ByteDance's enterprise messaging platform) as a gateway platform adapter with full feature parity: WebSocket + webhook transports, message batching, dedup, rate limiting, rich post/card content parsing, media handling (images/audio/files/video), group @mention gating, reaction routing, and interactive card button support. Cherry-picked from PR #1793 by penwyp with: - Moved to current main (PR was 458 commits behind) - Fixed _send_with_retry shadowing BasePlatformAdapter method (renamed to _feishu_send_with_retry to avoid signature mismatch crash) - Fixed import structure: aiohttp/websockets imported independently of lark_oapi so they remain available when SDK is missing - Fixed get_hermes_home import (hermes_constants, not hermes_cli.config) - Added skip decorators for tests requiring lark_oapi SDK - All 16 integration points added surgically to current main New dependency: lark-oapi>=1.5.3,<2 (optional, pip install hermes-agent[feishu]) Fixes #1788 Co-authored-by: penwyp <penwyp@users.noreply.github.com>
1 parent e314833 commit ca4907d

19 files changed

Lines changed: 6135 additions & 9 deletions

cron/scheduler.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ def _deliver_result(job: dict, content: str) -> None:
146146
"mattermost": Platform.MATTERMOST,
147147
"homeassistant": Platform.HOMEASSISTANT,
148148
"dingtalk": Platform.DINGTALK,
149+
"feishu": Platform.FEISHU,
149150
"email": Platform.EMAIL,
150151
"sms": Platform.SMS,
151152
}

gateway/config.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class Platform(Enum):
5757
DINGTALK = "dingtalk"
5858
API_SERVER = "api_server"
5959
WEBHOOK = "webhook"
60+
FEISHU = "feishu"
6061

6162

6263
@dataclass
@@ -274,6 +275,9 @@ def get_connected_platforms(self) -> List[Platform]:
274275
# Webhook uses enabled flag only (secrets are per-route)
275276
elif platform == Platform.WEBHOOK:
276277
connected.append(platform)
278+
# Feishu uses extra dict for app credentials
279+
elif platform == Platform.FEISHU and config.extra.get("app_id"):
280+
connected.append(platform)
277281
return connected
278282

279283
def get_home_channel(self, platform: Platform) -> Optional[HomeChannel]:
@@ -810,6 +814,33 @@ def _apply_env_overrides(config: GatewayConfig) -> None:
810814
if webhook_secret:
811815
config.platforms[Platform.WEBHOOK].extra["secret"] = webhook_secret
812816

817+
# Feishu / Lark
818+
feishu_app_id = os.getenv("FEISHU_APP_ID")
819+
feishu_app_secret = os.getenv("FEISHU_APP_SECRET")
820+
if feishu_app_id and feishu_app_secret:
821+
if Platform.FEISHU not in config.platforms:
822+
config.platforms[Platform.FEISHU] = PlatformConfig()
823+
config.platforms[Platform.FEISHU].enabled = True
824+
config.platforms[Platform.FEISHU].extra.update({
825+
"app_id": feishu_app_id,
826+
"app_secret": feishu_app_secret,
827+
"domain": os.getenv("FEISHU_DOMAIN", "feishu"),
828+
"connection_mode": os.getenv("FEISHU_CONNECTION_MODE", "websocket"),
829+
})
830+
feishu_encrypt_key = os.getenv("FEISHU_ENCRYPT_KEY", "")
831+
if feishu_encrypt_key:
832+
config.platforms[Platform.FEISHU].extra["encrypt_key"] = feishu_encrypt_key
833+
feishu_verification_token = os.getenv("FEISHU_VERIFICATION_TOKEN", "")
834+
if feishu_verification_token:
835+
config.platforms[Platform.FEISHU].extra["verification_token"] = feishu_verification_token
836+
feishu_home = os.getenv("FEISHU_HOME_CHANNEL")
837+
if feishu_home:
838+
config.platforms[Platform.FEISHU].home_channel = HomeChannel(
839+
platform=Platform.FEISHU,
840+
chat_id=feishu_home,
841+
name=os.getenv("FEISHU_HOME_CHANNEL_NAME", "Home"),
842+
)
843+
813844
# Session settings
814845
idle_minutes = os.getenv("SESSION_IDLE_MINUTES")
815846
if idle_minutes:

0 commit comments

Comments
 (0)