From 598f5649c3d6c6a139674df04561c9691d8a13b8 Mon Sep 17 00:00:00 2001 From: Norbert Kwizera Date: Thu, 9 Oct 2025 12:11:25 +0200 Subject: [PATCH 1/5] Update get_flows and get_globals by adjusting filterable fields --- temba_client/v2/__init__.py | 13 ++++++++----- temba_client/v2/tests.py | 23 ++++++++++++++++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/temba_client/v2/__init__.py b/temba_client/v2/__init__.py index 4693b67..f344a4b 100644 --- a/temba_client/v2/__init__.py +++ b/temba_client/v2/__init__.py @@ -145,13 +145,15 @@ def get_fields(self, key=None): """ return self._get_query("fields", self._build_params(key=key), Field) - def get_flows(self, uuid=None): + def get_flows(self, uuid=None, type=None, archived=None): """ Gets all matching flows :param uuid: flow UUID + :param str type: "message" or "voice" + :param archived: whether to include archived flows :return: flow query """ - return self._get_query("flows", self._build_params(uuid=uuid), Flow) + return self._get_query("flows", self._build_params(uuid=uuid, type=type, archived=archived), Flow) def get_flow_starts(self, uuid=None): """ @@ -161,12 +163,13 @@ def get_flow_starts(self, uuid=None): """ return self._get_query("flow_starts", self._build_params(uuid=uuid), FlowStart) - def get_globals(self): + def get_globals(self, key=None): """ Gets all globals + :param key: field key :return: global query """ - return self._get_query("globals", {}, Global) + return self._get_query("globals", self._build_params(key=key), Global) def get_groups(self, uuid=None, name=None): """ @@ -293,7 +296,7 @@ def create_campaign_event(self, campaign, relative_to, offset, unit, delivery_ho :param int delivery_hour: :param str message: :param * flow: flow object, UUID or name - :return: the new campaign + :return: the new campaign event """ payload = self._build_params( campaign=campaign, diff --git a/temba_client/v2/tests.py b/temba_client/v2/tests.py index a69bf65..58efc9c 100644 --- a/temba_client/v2/tests.py +++ b/temba_client/v2/tests.py @@ -498,11 +498,27 @@ def test_get_flows(self, mock_request): ["2bfbd76a-245a-473c-a296-28e4815f3a98", "d8b0ed18-a5c2-48be-98af-9b7f017fdc6c"], ) - # check with all params + # check with uuid param self.client.get_flows(uuid="ffce0fbb-4fe1-4052-b26a-91beb2ebae9a").all() self.assertRequest(mock_request, "get", "flows", params={"uuid": "ffce0fbb-4fe1-4052-b26a-91beb2ebae9a"}) + # check with type param + self.client.get_flows(type="message").all() + + self.assertRequest(mock_request, "get", "flows", params={"type": "message"}) + + # check with archived param + self.client.get_flows(archived=True).all() + + self.assertRequest(mock_request, "get", "flows", params={"archived": True}) + + # check with all param + self.client.get_flows(uuid="ffce0fbb-4fe1-4052-b26a-91beb2ebae9a", type="message", archived=False).all() + + self.assertRequest(mock_request, "get", "flows", params={"uuid": "ffce0fbb-4fe1-4052-b26a-91beb2ebae9a", "type": "message", "archived": False}) + + def test_get_flow_starts(self, mock_request): # check no params mock_request.return_value = MockResponse(200, self.read_json("flow_starts")) @@ -548,6 +564,11 @@ def test_get_globals(self, mock_request): self.assertEqual(results[0].value, "Acme Ltd") self.assertEqual(results[0].modified_on, datetime(2015, 6, 8, 12, 18, 7, 671000, tzone.utc)) + # check with all params + self.client.get_globals(key="org_name").all() + + self.assertRequest(mock_request, "get", "globals", params={"key": "org_name"}) + def test_get_groups(self, mock_request): # check no params mock_request.return_value = MockResponse(200, self.read_json("groups")) From d1624f61b6a4baf138f6dc374c5d9d789bce6cc0 Mon Sep 17 00:00:00 2001 From: Norbert Kwizera Date: Thu, 9 Oct 2025 12:45:02 +0200 Subject: [PATCH 2/5] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- temba_client/v2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temba_client/v2/__init__.py b/temba_client/v2/__init__.py index f344a4b..204bd01 100644 --- a/temba_client/v2/__init__.py +++ b/temba_client/v2/__init__.py @@ -150,7 +150,7 @@ def get_flows(self, uuid=None, type=None, archived=None): Gets all matching flows :param uuid: flow UUID :param str type: "message" or "voice" - :param archived: whether to include archived flows + :param bool archived: whether to include archived flows :return: flow query """ return self._get_query("flows", self._build_params(uuid=uuid, type=type, archived=archived), Flow) From 7d87b06029abbe3389ef1a1630f20d7a054b7159 Mon Sep 17 00:00:00 2001 From: Norbert Kwizera Date: Thu, 9 Oct 2025 12:45:11 +0200 Subject: [PATCH 3/5] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- temba_client/v2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temba_client/v2/__init__.py b/temba_client/v2/__init__.py index 204bd01..00d47b0 100644 --- a/temba_client/v2/__init__.py +++ b/temba_client/v2/__init__.py @@ -166,7 +166,7 @@ def get_flow_starts(self, uuid=None): def get_globals(self, key=None): """ Gets all globals - :param key: field key + :param str key: field key :return: global query """ return self._get_query("globals", self._build_params(key=key), Global) From 9b7125d6d4a988ec9c289bb83b5809859b9cbf90 Mon Sep 17 00:00:00 2001 From: Norbert Kwizera Date: Thu, 9 Oct 2025 13:03:45 +0200 Subject: [PATCH 4/5] Update ruff --- .github/workflows/ci.yml | 2 +- poetry.lock | 41 +++++++++++++++++++---------------- pyproject.toml | 6 +++-- temba_client/serialization.py | 4 ++-- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1f172a..77c29c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: run: poetry run black temba_client - name: Run ruff - run: poetry run ruff temba_client + run: poetry run ruff check temba_client - name: Run isort run: poetry run isort temba_client diff --git a/poetry.lock b/poetry.lock index ad00849..86723ce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -389,28 +389,31 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.0.171" -description = "An extremely fast Python linter, written in Rust." +version = "0.14.0" +description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "ruff-0.0.171-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:feb9ab6b4d1ae24f314c76f8218574b8d83079b1cf1929497a3504bf0ad14141"}, - {file = "ruff-0.0.171-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:7153e00617f94a5124a528fba04fde51b08ebff835f3674117174f6f2a5e0246"}, - {file = "ruff-0.0.171-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9b3f4d68ed03f666c41ba7897cef85a0f0ea10be160ae74e0e7f17828c69de"}, - {file = "ruff-0.0.171-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:745bac32c8503217d5f72aaaeee96103e4cb59caf711e3347cd9e29f7674c82f"}, - {file = "ruff-0.0.171-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27cb7d6857e9ec108b932b19508ad782720f25703018d19c537911d67c69486b"}, - {file = "ruff-0.0.171-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5db2b1d00630e29a4203bb53d860ecaa60e7e7110b6235e7a22542b64114a9d4"}, - {file = "ruff-0.0.171-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a630a1d980f8c399e61aae7bc21f0034b871c0c48dd14e933d3ea0f0bd9623ac"}, - {file = "ruff-0.0.171-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ec5e135e287f26b4bc4428f886e5f4d90223869024745d8d77d22104d3659c3"}, - {file = "ruff-0.0.171-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdbafd7d996b84b23bca61a3b4f9d259a47f0f68b3f4938c813106fd91bb5d45"}, - {file = "ruff-0.0.171-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e6dc77da063636b2098da9a7b1f0e703f1177f4f6e87886eba4e8abad0241c4e"}, - {file = "ruff-0.0.171-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:36211c353182fb33d528ca748d21cf1aa99dd9d85619feb9a303196391da5641"}, - {file = "ruff-0.0.171-py3-none-musllinux_1_2_i686.whl", hash = "sha256:7f3139f0d2d52e485ff133fb6f7ddea8dfc151ec61f32423efaab69efcb7a0a9"}, - {file = "ruff-0.0.171-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:07f906ebf1e883d6160b7f1cacfcafe0e3b268ea49214a7481bf39eb2b8d50a3"}, - {file = "ruff-0.0.171-py3-none-win32.whl", hash = "sha256:09b9d1e6e4ac108991880c738dab6e77e3903cb889ccf502fcf4a92b0a2b2ba1"}, - {file = "ruff-0.0.171-py3-none-win_amd64.whl", hash = "sha256:a1af62c97359f712be472297ab03a3b039a25ed4553ffbd516ea02d846d3b0f9"}, - {file = "ruff-0.0.171.tar.gz", hash = "sha256:80501b1ada6a56010f0d316d64c37cf65a60edea2d43e1ebd9fc0c400678dfa2"}, + {file = "ruff-0.14.0-py3-none-linux_armv6l.whl", hash = "sha256:58e15bffa7054299becf4bab8a1187062c6f8cafbe9f6e39e0d5aface455d6b3"}, + {file = "ruff-0.14.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:838d1b065f4df676b7c9957992f2304e41ead7a50a568185efd404297d5701e8"}, + {file = "ruff-0.14.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:703799d059ba50f745605b04638fa7e9682cc3da084b2092feee63500ff3d9b8"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ba9a8925e90f861502f7d974cc60e18ca29c72bb0ee8bfeabb6ade35a3abde7"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e41f785498bd200ffc276eb9e1570c019c1d907b07cfb081092c8ad51975bbe7"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30a58c087aef4584c193aebf2700f0fbcfc1e77b89c7385e3139956fa90434e2"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f8d07350bc7af0a5ce8812b7d5c1a7293cf02476752f23fdfc500d24b79b783c"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eec3bbbf3a7d5482b5c1f42d5fc972774d71d107d447919fca620b0be3e3b75e"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16b68e183a0e28e5c176d51004aaa40559e8f90065a10a559176713fcf435206"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb732d17db2e945cfcbbc52af0143eda1da36ca8ae25083dd4f66f1542fdf82e"}, + {file = "ruff-0.14.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c958f66ab884b7873e72df38dcabee03d556a8f2ee1b8538ee1c2bbd619883dd"}, + {file = "ruff-0.14.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7eb0499a2e01f6e0c285afc5bac43ab380cbfc17cd43a2e1dd10ec97d6f2c42d"}, + {file = "ruff-0.14.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c63b2d99fafa05efca0ab198fd48fa6030d57e4423df3f18e03aa62518c565f"}, + {file = "ruff-0.14.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:668fce701b7a222f3f5327f86909db2bbe99c30877c8001ff934c5413812ac02"}, + {file = "ruff-0.14.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a86bf575e05cb68dcb34e4c7dfe1064d44d3f0c04bbc0491949092192b515296"}, + {file = "ruff-0.14.0-py3-none-win32.whl", hash = "sha256:7450a243d7125d1c032cb4b93d9625dea46c8c42b4f06c6b709baac168e10543"}, + {file = "ruff-0.14.0-py3-none-win_amd64.whl", hash = "sha256:ea95da28cd874c4d9c922b39381cbd69cb7e7b49c21b8152b014bd4f52acddc2"}, + {file = "ruff-0.14.0-py3-none-win_arm64.whl", hash = "sha256:f42c9495f5c13ff841b1da4cb3c2a42075409592825dada7c5885c2c844ac730"}, + {file = "ruff-0.14.0.tar.gz", hash = "sha256:62ec8969b7510f77945df916de15da55311fade8d6050995ff7f680afe582c57"}, ] [[package]] @@ -490,4 +493,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.1" python-versions = ">=3.10" -content-hash = "dcf33b9b7017ec16f7f04b61fc271af40732b3ceea849e8db472bdbc1296fd4c" +content-hash = "d7b2bf362632f6a94796b29371e19a6f37ad292ff5d2609ab2f48766ae307594" diff --git a/pyproject.toml b/pyproject.toml index 71010c3..8eee054 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ packages = [ [tool.poetry.group.dev.dependencies] coverage = "^5.3" -ruff = "^0.0.171" +ruff = "^0.14.0" isort = "^5.10.1" black = "^24.3.0" nose2 = "^0.12.0" @@ -40,9 +40,11 @@ line-length = 119 [tool.ruff] line-length = 120 +fix = true + +[tool.ruff.lint] select = ["E", "F", "W"] ignore = ["E501", "F405"] -fix = true [tool.isort] multi_line_output = 3 diff --git a/temba_client/serialization.py b/temba_client/serialization.py index 24dc622..4dc70a8 100644 --- a/temba_client/serialization.py +++ b/temba_client/serialization.py @@ -100,14 +100,14 @@ def deserialize(self, value): class IntegerField(SimpleField): def deserialize(self, value): - if value is not None and type(value) != int: + if value is not None and not isinstance(value, int): raise TembaSerializationException("Value '%s' field is not an integer" % str(value)) return value class ListField(SimpleField): def deserialize(self, value): - if value is not None and type(value) != list: + if value is not None and not isinstance(value, list): raise TembaSerializationException("Value '%s' field is not a list" % str(value)) return value From 74a452cea74ee5eb9e5478b4af356f74c3c6b47f Mon Sep 17 00:00:00 2001 From: Norbert Kwizera Date: Thu, 9 Oct 2025 14:09:08 +0200 Subject: [PATCH 5/5] Add support for message quick replies --- temba_client/tests.py | 2 +- temba_client/v2/__init__.py | 13 ++++++---- temba_client/v2/tests.py | 52 ++++++++++++++++++++++++++++++++----- temba_client/v2/types.py | 10 +++++-- test_files/v2/messages.json | 2 ++ 5 files changed, 65 insertions(+), 14 deletions(-) diff --git a/temba_client/tests.py b/temba_client/tests.py index d35c41f..ea42730 100644 --- a/temba_client/tests.py +++ b/temba_client/tests.py @@ -64,7 +64,7 @@ def assertRequestURL(self, mock, method, url, **kwargs): "User-Agent": "test/0.1 rapidpro-python/%s" % CLIENT_VERSION, }, verify=None, - **kwargs + **kwargs, ) mock.reset_mock() diff --git a/temba_client/v2/__init__.py b/temba_client/v2/__init__.py index 00d47b0..a3ca27f 100644 --- a/temba_client/v2/__init__.py +++ b/temba_client/v2/__init__.py @@ -235,9 +235,7 @@ def get_resthook_subscribers(self, id=None, resthook=None): params = self._build_params(id=id, resthook=resthook) return self._get_query("resthook_subscribers", params, ResthookSubscriber) - def get_runs( - self, uuid=None, flow=None, responded=None, before=None, after=None, reverse=None, paths=None - ): + def get_runs(self, uuid=None, flow=None, responded=None, before=None, after=None, reverse=None, paths=None): """ Gets all matching flow runs :param uuid: flow run UUID @@ -382,16 +380,21 @@ def create_label(self, name): """ return Label.deserialize(self._post("labels", None, self._build_params(name=name))) - def create_message(self, contact, text, attachments): + def create_message(self, contact, text, attachments, quick_replies=[]): """ Creates a new outgoing message :param str contact: contact UUID :param str text: message text :param list[str] attachments: message attachments + :param list[dict] quick_replies: message quick replies :return: the new message """ return Message.deserialize( - self._post("messages", None, self._build_params(contact=contact, text=text, attachments=attachments)) + self._post( + "messages", + None, + self._build_params(contact=contact, text=text, attachments=attachments, quick_replies=quick_replies), + ) ) def create_resthook_subscriber(self, resthook, target_url): diff --git a/temba_client/v2/tests.py b/temba_client/v2/tests.py index 58efc9c..00f0139 100644 --- a/temba_client/v2/tests.py +++ b/temba_client/v2/tests.py @@ -267,7 +267,11 @@ def test_get_broadcasts(self, mock_request): mock_request, "get", "broadcasts", - params={"uuid": "c4f3b6e1-2d3a-4f4b-8f4e-1e2d3c4b5a6f", "after": "2014-12-12T22:34:36.978123Z", "before": "2014-12-12T22:56:58.917123Z"}, + params={ + "uuid": "c4f3b6e1-2d3a-4f4b-8f4e-1e2d3c4b5a6f", + "after": "2014-12-12T22:34:36.978123Z", + "before": "2014-12-12T22:56:58.917123Z", + }, ) def test_get_campaigns(self, mock_request): @@ -516,8 +520,12 @@ def test_get_flows(self, mock_request): # check with all param self.client.get_flows(uuid="ffce0fbb-4fe1-4052-b26a-91beb2ebae9a", type="message", archived=False).all() - self.assertRequest(mock_request, "get", "flows", params={"uuid": "ffce0fbb-4fe1-4052-b26a-91beb2ebae9a", "type": "message", "archived": False}) - + self.assertRequest( + mock_request, + "get", + "flows", + params={"uuid": "ffce0fbb-4fe1-4052-b26a-91beb2ebae9a", "type": "message", "archived": False}, + ) def test_get_flow_starts(self, mock_request): # check no params @@ -564,7 +572,7 @@ def test_get_globals(self, mock_request): self.assertEqual(results[0].value, "Acme Ltd") self.assertEqual(results[0].modified_on, datetime(2015, 6, 8, 12, 18, 7, 671000, tzone.utc)) - # check with all params + # check with all params self.client.get_globals(key="org_name").all() self.assertRequest(mock_request, "get", "globals", params={"key": "org_name"}) @@ -647,6 +655,11 @@ def test_get_messages(self, mock_request): self.assertEqual(results[1].attachments[0].content_type, "audio/wav") self.assertEqual(results[1].attachments[0].url, "http://domain.com/recording.wav") + self.assertEqual(results[1].quick_replies[0].text, "Red") + self.assertEqual(results[1].quick_replies[1].text, "Green") + self.assertEqual(results[1].quick_replies[1].extra, "Like grass") + self.assertEqual(results[1].quick_replies[2].text, "Blue") + # check with all params self.client.get_messages( uuid="eb6aeae0-0433-45de-bbed-031039a1cfaa", @@ -953,10 +966,34 @@ def test_create_message(self, mock_request): mock_request, "post", "messages", - data={"contact": "5079cb96-a1d8-4f47-8c87-d8c7bb6ddab9", "text": "Hi there", "attachments": []}, + data={ + "contact": "5079cb96-a1d8-4f47-8c87-d8c7bb6ddab9", + "text": "Hi there", + "attachments": [], + "quick_replies": [], + }, ) self.assertEqual(message.uuid, "eb6aeae0-0433-45de-bbed-031039a1cfaa") + message = self.client.create_message( + contact="5079cb96-a1d8-4f47-8c87-d8c7bb6ddab9", + text="Hi there", + attachments=[], + quick_replies=[{"text": "Blue"}, {"text": "Green", "extra": "Like grass"}], + ) + + self.assertRequest( + mock_request, + "post", + "messages", + data={ + "contact": "5079cb96-a1d8-4f47-8c87-d8c7bb6ddab9", + "text": "Hi there", + "attachments": [], + "quick_replies": [{"text": "Blue"}, {"text": "Green", "extra": "Like grass"}], + }, + ) + def test_create_resthook_subscriber(self, mock_request): subscriber_json = self.read_json("resthook_subscribers", extract_result=0) @@ -1262,7 +1299,10 @@ def test_contact_actions(self, mock_request): def test_message_actions(self, mock_request): mock_request.return_value = MockResponse(204, "") - messages = [Message.create(uuid="eb6aeae0-0433-45de-bbed-031039a1cfaa"), "2be38dc4-b3ae-4fdf-a3b6-7defb3c11c4c"] + messages = [ + Message.create(uuid="eb6aeae0-0433-45de-bbed-031039a1cfaa"), + "2be38dc4-b3ae-4fdf-a3b6-7defb3c11c4c", + ] resolved_messages = ["eb6aeae0-0433-45de-bbed-031039a1cfaa", "2be38dc4-b3ae-4fdf-a3b6-7defb3c11c4c"] self.client.bulk_label_messages(messages=messages, label="Testing", label_name="Spam") diff --git a/temba_client/v2/types.py b/temba_client/v2/types.py index c1eb63b..0fc9a32 100644 --- a/temba_client/v2/types.py +++ b/temba_client/v2/types.py @@ -65,6 +65,7 @@ class Broadcast(TembaObject): text = SimpleField() created_on = DatetimeField() + class Campaign(TembaObject): uuid = SimpleField() name = SimpleField() @@ -93,11 +94,10 @@ class Device(TembaObject): power_source = SimpleField() network_type = SimpleField() - uuid = SimpleField() name = SimpleField() address = SimpleField() - type=SimpleField() + type = SimpleField() country = SimpleField() device = ObjectField(item_class=Device) last_seen = DatetimeField() @@ -134,6 +134,7 @@ class Export(TembaObject): fields = ListField() groups = ListField() + class Field(TembaObject): key = SimpleField() name = SimpleField() @@ -206,6 +207,10 @@ class AttachmentRef(TembaObject): content_type = SimpleField() url = SimpleField() + class QuickReply(TembaObject): + text = SimpleField() + extra = SimpleField() + uuid = SimpleField() contact = ObjectField(item_class=ObjectRef) urn = SimpleField() @@ -217,6 +222,7 @@ class AttachmentRef(TembaObject): text = SimpleField() labels = ObjectListField(item_class=ObjectRef) attachments = ObjectListField(item_class=AttachmentRef) + quick_replies = ObjectListField(item_class=QuickReply) flow = ObjectField(item_class=ObjectRef) created_on = DatetimeField() sent_on = DatetimeField() diff --git a/test_files/v2/messages.json b/test_files/v2/messages.json index 3f58f3c..a72f14f 100644 --- a/test_files/v2/messages.json +++ b/test_files/v2/messages.json @@ -20,6 +20,7 @@ "text": "How are you?", "labels": [], "attachments": [], + "quick_replies": [], "flow": { "uuid": "6ca413c7-bc3a-42cb-9744-6938f791bc36", "name": "Registration" @@ -53,6 +54,7 @@ "url": "http://domain.com/recording.wav" } ], + "quick_replies": [{"text": "Red"}, {"text": "Green", "extra": "Like grass"}, {"text": "Blue"}], "flow": null, "created_on": "2015-11-10T12:59:10+00:00", "sent_on": null,