diff --git a/src/infrastructure/giphy/gif_search.py b/src/infrastructure/giphy/gif_search.py index e4688c6..29852e5 100644 --- a/src/infrastructure/giphy/gif_search.py +++ b/src/infrastructure/giphy/gif_search.py @@ -1,7 +1,7 @@ """GIF search through Teams, with the account's own Microsoft sign-in and no key of our own. The Teams clients ask their middle tier for Giphy results (see `TeamsChatClient.gif_command`). The answer is a list of -`{composeType, composeValue, fieldValues: [{fieldName, fieldValue}]}`. The route is undocumented and the names in it were +`{composeType, composeValue, fieldValues: [{fieldName, fieldValue}]}`, nested as production showed. The route is undocumented and the names in it were read from Teams' client code, not from a live answer, so the GIF is found by its Giphy URL rather than by a field name. A GIF sends as a plain `` in the message body. """ diff --git a/src/infrastructure/teams/teams_chat_client.py b/src/infrastructure/teams/teams_chat_client.py index 2a0bfcb..7fe59b9 100644 --- a/src/infrastructure/teams/teams_chat_client.py +++ b/src/infrastructure/teams/teams_chat_client.py @@ -117,8 +117,9 @@ def gif_command(self, broker, query: str, limit: int, rating: str) -> list: if r.status_code == 401: self._drop_session(broker) raise ChatServiceError(r.status_code, "GIF command refused") - result = r.json().get("result") - return result if isinstance(result, list) else [] + # The answer nests: {result: [{templateType, result: [the GIFs]}]}. + groups = r.json().get("result") + return [item for group in groups if isinstance(group, dict) and isinstance(group.get("result"), list) for item in group["result"]] if isinstance(groups, list) else [] def _media_host(self, value) -> str | None: """The media service base URL when it is an https Microsoft media host, else None.""" diff --git a/tests/test_teams_extras.py b/tests/test_teams_extras.py index 7bd772d..0138e4f 100644 --- a/tests/test_teams_extras.py +++ b/tests/test_teams_extras.py @@ -391,7 +391,7 @@ def post(self, url, headers=None, content=None, timeout=None): if url == teams_chat.AUTHZ_URL: return FakeResponse(200, {"tokens": {"skypeToken": "skype", "expiresIn": 4000}, "regionGtms": {"chatService": "https://ch.ng.msg.teams.microsoft.com", "middleTier": middle_tier}}) calls.append({"url": url, "headers": headers, "body": json.loads(content)}) - return FakeResponse(status, {"result": result or []}) + return FakeResponse(status, {"result": [{"templateType": "grid", "result": result or []}]}) monkeypatch.setattr(teams_chat, "http_client", lambda: Http()) return calls