chore: update external connector deployment flow
This commit is contained in:
@ -83,6 +83,7 @@ class FeishuBotProvider:
|
||||
metadata = {
|
||||
"eventCallbackPath": "/feishu/events",
|
||||
"eventCallbackUrl": f"{self.public_base_url}/feishu/events",
|
||||
"bridgeBaseUrl": str(payload.get("callbackBaseUrl") or self.bridge_base_url),
|
||||
}
|
||||
app_id = str(options.get("appId") or options.get("app_id") or "").strip()
|
||||
app_secret = str(options.get("appSecret") or options.get("app_secret") or "").strip()
|
||||
@ -212,7 +213,7 @@ class FeishuBotProvider:
|
||||
if bridge_event is None:
|
||||
return {"ok": True, "ignored": "empty_or_oversized"}
|
||||
self.bridge_post(
|
||||
f"{self.bridge_base_url}/api/channel-connector-bridge/events",
|
||||
f"{_bridge_base_url(session, self.bridge_base_url)}/api/channel-connector-bridge/events",
|
||||
bridge_event,
|
||||
{"Authorization": f"Bearer {self.bridge_token}"},
|
||||
)
|
||||
@ -452,13 +453,17 @@ class FeishuBotProvider:
|
||||
"FEISHU_TEXT_BATCH_DELAY_MS": str(_positive_int(metadata.get("textBatchDelayMs"), default=0)),
|
||||
"FEISHU_TEXT_BATCH_MAX_MESSAGES": str(_positive_int(metadata.get("textBatchMaxMessages"), default=10)),
|
||||
"FEISHU_TEXT_BATCH_MAX_CHARS": str(_positive_int(metadata.get("textBatchMaxChars"), default=20000)),
|
||||
"BEAVER_BRIDGE_BASE_URL": self.bridge_base_url,
|
||||
"BEAVER_BRIDGE_BASE_URL": _bridge_base_url(session, self.bridge_base_url),
|
||||
"BEAVER_BRIDGE_TOKEN": self.bridge_token,
|
||||
}
|
||||
)
|
||||
return subprocess.Popen(["node", str(script)], env=env, cwd=str(script.parent))
|
||||
|
||||
|
||||
def _bridge_base_url(session: ConnectorSessionState, fallback: str) -> str:
|
||||
return str(session.metadata.get("bridgeBaseUrl") or fallback).rstrip("/")
|
||||
|
||||
|
||||
def _bridge_event_from_feishu(session: ConnectorSessionState, header: dict[str, Any], event: dict[str, Any]) -> dict[str, Any] | None:
|
||||
message = dict(event.get("message") or {})
|
||||
sender = dict(event.get("sender") or {})
|
||||
|
||||
@ -246,7 +246,7 @@ class WeixinIlinkProvider:
|
||||
flush=True,
|
||||
)
|
||||
self.bridge_post(
|
||||
f"{self.bridge_base_url}/api/channel-connector-bridge/events",
|
||||
f"{_bridge_base_url(session, self.bridge_base_url)}/api/channel-connector-bridge/events",
|
||||
event,
|
||||
{"Authorization": f"Bearer {self.bridge_token}"},
|
||||
)
|
||||
@ -384,6 +384,10 @@ def _url(base_url: str, endpoint: str) -> str:
|
||||
return f"{base_url.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||
|
||||
|
||||
def _bridge_base_url(session: ConnectorSessionState, fallback: str) -> str:
|
||||
return str(session.metadata.get("bridgeBaseUrl") or fallback).rstrip("/")
|
||||
|
||||
|
||||
def _base_info() -> dict[str, str]:
|
||||
return {"channel_version": "2.4.3", "bot_agent": "Beaver/1.0"}
|
||||
|
||||
|
||||
@ -384,6 +384,44 @@ def test_feishu_event_route_forwards_message_to_bridge(tmp_path) -> None:
|
||||
assert bridge_posts[0][1]["peerId"] == "ou_user"
|
||||
|
||||
|
||||
def test_feishu_event_route_uses_session_callback_base_url(tmp_path) -> None:
|
||||
bridge_posts: list[tuple[str, dict[str, object], dict[str, str]]] = []
|
||||
provider = _provider(tmp_path, bridge_posts=bridge_posts)
|
||||
provider.start_session(
|
||||
{
|
||||
"kind": "feishu",
|
||||
"connectionId": "conn_1",
|
||||
"channelId": "feishu-main",
|
||||
"displayName": "Feishu Main",
|
||||
"callbackBaseUrl": "http://app-instance-jaychen:8080",
|
||||
"options": {"appId": "cli_xxx", "appSecret": "secret", "verificationToken": "verify-token"},
|
||||
}
|
||||
)
|
||||
app = create_app(provider=provider, api_token="sidecar-token")
|
||||
|
||||
with TestClient(app) as client:
|
||||
response = client.post(
|
||||
"/feishu/events",
|
||||
json={
|
||||
"schema": "2.0",
|
||||
"header": {"event_id": "evt_1", "token": "verify-token", "app_id": "cli_xxx"},
|
||||
"event": {
|
||||
"sender": {"sender_id": {"open_id": "ou_user"}},
|
||||
"message": {
|
||||
"message_id": "om_1",
|
||||
"chat_id": "oc_chat",
|
||||
"chat_type": "p2p",
|
||||
"message_type": "text",
|
||||
"content": "{\"text\":\"hello feishu\"}",
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert bridge_posts[0][0] == "http://app-instance-jaychen:8080/api/channel-connector-bridge/events"
|
||||
|
||||
|
||||
def test_feishu_event_route_ignores_bot_sender_and_platform_commands(tmp_path) -> None:
|
||||
bridge_posts: list[tuple[str, dict[str, object], dict[str, str]]] = []
|
||||
provider = _provider(tmp_path, bridge_posts=bridge_posts)
|
||||
|
||||
@ -438,3 +438,35 @@ def test_weixin_ilink_provider_poll_once_forwards_bridge_event(tmp_path) -> None
|
||||
assert bridge_posts[0][1]["eventId"] == "weixin-main:42"
|
||||
assert bridge_posts[0][1]["content"] == "hello"
|
||||
assert bridge_posts[0][1]["peerId"] == "wx-user"
|
||||
|
||||
|
||||
def test_weixin_ilink_provider_poll_once_uses_session_callback_base_url(tmp_path) -> None:
|
||||
http = FakeHttpClient()
|
||||
bridge_posts: list[tuple[str, dict[str, object], dict[str, str]]] = []
|
||||
|
||||
def bridge_post(url: str, payload: dict[str, object], headers: dict[str, str]) -> None:
|
||||
bridge_posts.append((url, payload, headers))
|
||||
|
||||
provider = WeixinIlinkProvider(
|
||||
store=SidecarStateStore(tmp_path / "state.json"),
|
||||
http_client=http,
|
||||
bridge_base_url="http://global-beaver:8080",
|
||||
bridge_token="bridge-token",
|
||||
bridge_post=bridge_post,
|
||||
start_receivers=False,
|
||||
)
|
||||
session = provider.start_session(
|
||||
{
|
||||
"kind": "weixin",
|
||||
"connectionId": "conn_1",
|
||||
"channelId": "weixin-main",
|
||||
"displayName": "Weixin Main",
|
||||
"callbackBaseUrl": "http://app-instance-jaychen:8080",
|
||||
"options": {},
|
||||
}
|
||||
)
|
||||
provider.get_session(session["sessionId"])
|
||||
|
||||
provider.poll_once("conn_1")
|
||||
|
||||
assert bridge_posts[0][0] == "http://app-instance-jaychen:8080/api/channel-connector-bridge/events"
|
||||
|
||||
Reference in New Issue
Block a user