From ae9f254e24932e48e2a2e85cc7d99c1606881003 Mon Sep 17 00:00:00 2001 From: Douglas Alves de Sousa Date: Mon, 11 Sep 2023 21:22:51 -0300 Subject: [PATCH] first --- .gitignore | 172 ++++++++++++++++++ LICENSE.txt | 17 ++ README.md | 1 + __init__.py | 1 + moorse/.vscode/settings.json | 3 + moorse/clients/auth_client.py | 11 ++ moorse/clients/billing_client.py | 21 +++ moorse/clients/integration_client.py | 37 ++++ moorse/clients/message/instagram_client.py | 13 ++ moorse/clients/message/sms_client.py | 13 ++ moorse/clients/message/whatsapp_client.py | 48 +++++ moorse/clients/report_client.py | 29 +++ moorse/clients/template_client.py | 39 ++++ moorse/clients/webhook_client.py | 48 +++++ moorse/dto/authorization/login_response.py | 10 + moorse/dto/billing/billing_data.py | 17 ++ moorse/dto/billing/billing_dto.py | 13 ++ .../delete/integration_deletion_data.py | 12 ++ .../delete/integration_deletion_message.py | 7 + .../get_all/integrations_content.py | 9 + .../integration/get_all/integrations_data.py | 12 ++ .../get_all/integrations_data_attributes.py | 25 +++ .../integration/get_one/integration_data.py | 15 ++ .../get_one/integration_data_attributes.py | 49 +++++ .../get_status/integration_status.py | 9 + .../get_status/integration_status_data.py | 14 ++ moorse/dto/message/buttons/button.py | 14 ++ .../buttons/buttons_message_request.py | 19 ++ moorse/dto/message/menu/action.py | 13 ++ .../dto/message/menu/menu_message_request.py | 19 ++ moorse/dto/message/menu/row.py | 14 ++ moorse/dto/message/menu/section.py | 16 ++ moorse/dto/message/message_sent_response.py | 11 ++ .../dto/message/message_sent_response_data.py | 11 ++ moorse/dto/message/template/component.py | 16 ++ .../template/parameter/document_parameter.py | 7 + .../parameter/file_info/document_info.py | 14 ++ .../parameter/file_info/image_info.py | 11 ++ .../parameter/file_info/video_info.py | 11 ++ .../template/parameter/image_parameter.py | 7 + .../message/template/parameter/parameter.py | 34 ++++ .../template/parameter/text_parameter.py | 6 + .../template/parameter/video_parameter.py | 8 + .../template/template_message_request.py | 19 ++ moorse/dto/moorse_error.py | 11 ++ moorse/dto/pair.py | 8 + .../channel/messages_by_channel_report_dto.py | 12 ++ .../reports/channel/report_channel_data.py | 19 ++ .../reports/standard/messages_report_dto.py | 14 ++ moorse/dto/reports/standard/report_data.py | 13 ++ .../reports/timeline/date_message_counter.py | 9 + .../messages_by_timeline_report_dto.py | 16 ++ .../reports/timeline/report_timeline_data.py | 21 +++ moorse/dto/template/button/button.py | 32 ++++ .../template/button/button_phone_number.py | 17 ++ .../dto/template/button/button_quick_reply.py | 17 ++ moorse/dto/template/button/button_url.py | 18 ++ .../component/template_button_component.py | 19 ++ .../template/component/template_component.py | 35 ++++ .../component/template_component_example.py | 15 ++ .../component/template_document_component.py | 19 ++ .../component/template_image_component.py | 19 ++ .../component/template_text_component.py | 20 ++ .../dto/template/request/template_request.py | 43 +++++ .../response/multiple/template_list.py | 16 ++ .../multiple/template_list_content.py | 12 ++ .../response/single/template_response.py | 75 ++++++++ moorse/dto/template/template_dto.py | 14 ++ .../webhook/response/multiple/webhook_list.py | 15 ++ .../response/multiple/webhook_list_data.py | 14 ++ .../response/multiple/webhook_list_element.py | 39 ++++ moorse/dto/webhook/response/webhook_dto.py | 17 ++ moorse/dto/webhook/response/webhook_header.py | 19 ++ .../webhook/response/webhook_integration.py | 23 +++ .../dto/webhook/response/webhook_response.py | 49 +++++ moorse/dto/webhook/webhook_request.py | 66 +++++++ moorse/enums/communication_channel.py | 6 + moorse/enums/template/button_type.py | 6 + .../component/template_component_format.py | 8 + .../component/template_component_type.py | 8 + moorse/enums/template/template_category.py | 15 ++ moorse/enums/template/template_language.py | 20 ++ moorse/enums/template/template_type.py | 6 + moorse/enums/url.py | 31 ++++ moorse/enums/webhook/webhook_method.py | 5 + moorse/moorse.py | 58 ++++++ moorse/service/auth_service.py | 48 +++++ moorse/service/billing_service.py | 13 ++ moorse/service/integration_service.py | 21 +++ moorse/service/message/instagram_service.py | 28 +++ moorse/service/message/sms_service.py | 28 +++ moorse/service/message/whatsapp_service.py | 28 +++ moorse/service/report_service.py | 27 +++ moorse/service/template_service.py | 24 +++ moorse/service/validators/email_validator.py | 11 ++ moorse/service/webhook_service.py | 25 +++ setup.cfg | 3 + setup.py | 26 +++ 98 files changed, 2076 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 __init__.py create mode 100644 moorse/.vscode/settings.json create mode 100644 moorse/clients/auth_client.py create mode 100644 moorse/clients/billing_client.py create mode 100644 moorse/clients/integration_client.py create mode 100644 moorse/clients/message/instagram_client.py create mode 100644 moorse/clients/message/sms_client.py create mode 100644 moorse/clients/message/whatsapp_client.py create mode 100644 moorse/clients/report_client.py create mode 100644 moorse/clients/template_client.py create mode 100644 moorse/clients/webhook_client.py create mode 100644 moorse/dto/authorization/login_response.py create mode 100644 moorse/dto/billing/billing_data.py create mode 100644 moorse/dto/billing/billing_dto.py create mode 100644 moorse/dto/integration/delete/integration_deletion_data.py create mode 100644 moorse/dto/integration/delete/integration_deletion_message.py create mode 100644 moorse/dto/integration/get_all/integrations_content.py create mode 100644 moorse/dto/integration/get_all/integrations_data.py create mode 100644 moorse/dto/integration/get_all/integrations_data_attributes.py create mode 100644 moorse/dto/integration/get_one/integration_data.py create mode 100644 moorse/dto/integration/get_one/integration_data_attributes.py create mode 100644 moorse/dto/integration/get_status/integration_status.py create mode 100644 moorse/dto/integration/get_status/integration_status_data.py create mode 100644 moorse/dto/message/buttons/button.py create mode 100644 moorse/dto/message/buttons/buttons_message_request.py create mode 100644 moorse/dto/message/menu/action.py create mode 100644 moorse/dto/message/menu/menu_message_request.py create mode 100644 moorse/dto/message/menu/row.py create mode 100644 moorse/dto/message/menu/section.py create mode 100644 moorse/dto/message/message_sent_response.py create mode 100644 moorse/dto/message/message_sent_response_data.py create mode 100644 moorse/dto/message/template/component.py create mode 100644 moorse/dto/message/template/parameter/document_parameter.py create mode 100644 moorse/dto/message/template/parameter/file_info/document_info.py create mode 100644 moorse/dto/message/template/parameter/file_info/image_info.py create mode 100644 moorse/dto/message/template/parameter/file_info/video_info.py create mode 100644 moorse/dto/message/template/parameter/image_parameter.py create mode 100644 moorse/dto/message/template/parameter/parameter.py create mode 100644 moorse/dto/message/template/parameter/text_parameter.py create mode 100644 moorse/dto/message/template/parameter/video_parameter.py create mode 100644 moorse/dto/message/template/template_message_request.py create mode 100644 moorse/dto/moorse_error.py create mode 100644 moorse/dto/pair.py create mode 100644 moorse/dto/reports/channel/messages_by_channel_report_dto.py create mode 100644 moorse/dto/reports/channel/report_channel_data.py create mode 100644 moorse/dto/reports/standard/messages_report_dto.py create mode 100644 moorse/dto/reports/standard/report_data.py create mode 100644 moorse/dto/reports/timeline/date_message_counter.py create mode 100644 moorse/dto/reports/timeline/messages_by_timeline_report_dto.py create mode 100644 moorse/dto/reports/timeline/report_timeline_data.py create mode 100644 moorse/dto/template/button/button.py create mode 100644 moorse/dto/template/button/button_phone_number.py create mode 100644 moorse/dto/template/button/button_quick_reply.py create mode 100644 moorse/dto/template/button/button_url.py create mode 100644 moorse/dto/template/component/template_button_component.py create mode 100644 moorse/dto/template/component/template_component.py create mode 100644 moorse/dto/template/component/template_component_example.py create mode 100644 moorse/dto/template/component/template_document_component.py create mode 100644 moorse/dto/template/component/template_image_component.py create mode 100644 moorse/dto/template/component/template_text_component.py create mode 100644 moorse/dto/template/request/template_request.py create mode 100644 moorse/dto/template/response/multiple/template_list.py create mode 100644 moorse/dto/template/response/multiple/template_list_content.py create mode 100644 moorse/dto/template/response/single/template_response.py create mode 100644 moorse/dto/template/template_dto.py create mode 100644 moorse/dto/webhook/response/multiple/webhook_list.py create mode 100644 moorse/dto/webhook/response/multiple/webhook_list_data.py create mode 100644 moorse/dto/webhook/response/multiple/webhook_list_element.py create mode 100644 moorse/dto/webhook/response/webhook_dto.py create mode 100644 moorse/dto/webhook/response/webhook_header.py create mode 100644 moorse/dto/webhook/response/webhook_integration.py create mode 100644 moorse/dto/webhook/response/webhook_response.py create mode 100644 moorse/dto/webhook/webhook_request.py create mode 100644 moorse/enums/communication_channel.py create mode 100644 moorse/enums/template/button_type.py create mode 100644 moorse/enums/template/component/template_component_format.py create mode 100644 moorse/enums/template/component/template_component_type.py create mode 100644 moorse/enums/template/template_category.py create mode 100644 moorse/enums/template/template_language.py create mode 100644 moorse/enums/template/template_type.py create mode 100644 moorse/enums/url.py create mode 100644 moorse/enums/webhook/webhook_method.py create mode 100644 moorse/moorse.py create mode 100644 moorse/service/auth_service.py create mode 100644 moorse/service/billing_service.py create mode 100644 moorse/service/integration_service.py create mode 100644 moorse/service/message/instagram_service.py create mode 100644 moorse/service/message/sms_service.py create mode 100644 moorse/service/message/whatsapp_service.py create mode 100644 moorse/service/report_service.py create mode 100644 moorse/service/template_service.py create mode 100644 moorse/service/validators/email_validator.py create mode 100644 moorse/service/webhook_service.py create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a429426 --- /dev/null +++ b/.gitignore @@ -0,0 +1,172 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +/env/ +/responses/ +/moorse/.git/ + +testes_webhooks.py +testes_billing.py +testes_login.py +testes_reports.py +testes_integration.py +testes_template.py +testes_mensagens.py + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..3754756 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,17 @@ +MIT License +Copyright (c) 2018 YOUR NAME +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4183fd4 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Documentação \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..9a2bf72 --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +from moorse import Moorse \ No newline at end of file diff --git a/moorse/.vscode/settings.json b/moorse/.vscode/settings.json new file mode 100644 index 0000000..a6735e5 --- /dev/null +++ b/moorse/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.analysis.typeCheckingMode": "off" +} \ No newline at end of file diff --git a/moorse/clients/auth_client.py b/moorse/clients/auth_client.py new file mode 100644 index 0000000..32cc7b2 --- /dev/null +++ b/moorse/clients/auth_client.py @@ -0,0 +1,11 @@ +from enums.url import URL +from dto.authorization.login_response import LoginResponse +import requests +import json + +class AuthClient: + + def login(self, email: str, password: str) -> LoginResponse: + data: dict[str, str] = { 'login': email, 'senha': password } + response = requests.post(URL.AUTH_LOGIN.value, json=data).json() + return LoginResponse(response) diff --git a/moorse/clients/billing_client.py b/moorse/clients/billing_client.py new file mode 100644 index 0000000..b2f3f17 --- /dev/null +++ b/moorse/clients/billing_client.py @@ -0,0 +1,21 @@ +from dto.billing.billing_dto import BillingDto +from dto.moorse_error import MoorseError +from enums.url import URL +import requests +import json + +class BillingClient: + + def get_credits(self, token: str, integration_id: str): + response = requests.get( + URL.BILLING.value.format(integration_id), + headers = {'Authorization': f"Bearer {token}"} + ) + try: + response = response.json() + except: + response = { + "data": None, + "errors": ["Integração não encontrada"] + } + return BillingDto(response) \ No newline at end of file diff --git a/moorse/clients/integration_client.py b/moorse/clients/integration_client.py new file mode 100644 index 0000000..5d02fc9 --- /dev/null +++ b/moorse/clients/integration_client.py @@ -0,0 +1,37 @@ +import requests +from enums.url import URL +from dto.integration.delete.integration_deletion_data import IntegrationDeletionData +from dto.integration.get_one.integration_data import IntegrationData +from dto.integration.get_all.integrations_data import IntegrationsData +from dto.integration.get_status.integration_status_data import IntegrationStatusData +import json + +class IntegrationClient: + + def delete(self, token: str, integration_id: str) -> IntegrationDeletionData: + response = requests.delete( + URL.SEARCH_INTEGRATION.value.format(integration_id), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return IntegrationDeletionData(response) + + def get_one(self, token: str, integration_id: str) -> IntegrationData: + response = requests.get( + URL.SEARCH_INTEGRATION.value.format(integration_id), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return IntegrationData(response) + + def get_all(self, token: str) -> IntegrationsData: + response = requests.get( + URL.INTEGRATION.value, + headers = {'Authorization': f"Bearer {token}"} + ).json() + return IntegrationsData(response) + + def get_status(self, token: str, integration_id: str) -> IntegrationStatusData: + response = requests.get( + URL.SEARCH_INTEGRATION_STATUS.value.format(integration_id), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return IntegrationStatusData(response) \ No newline at end of file diff --git a/moorse/clients/message/instagram_client.py b/moorse/clients/message/instagram_client.py new file mode 100644 index 0000000..ed6b07b --- /dev/null +++ b/moorse/clients/message/instagram_client.py @@ -0,0 +1,13 @@ +import requests +from enums.url import URL +from dto.message.message_sent_response import MessageSentResponse + +class InstagramClient: + + def send_text(self, token: str, integration_id: str, to: str, body: str): + response = requests.post( + URL.INSTAGRAM_TEXT_MESSAGE.value.format(integration_id), + json = {'to': to, 'body': body}, + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessageSentResponse(response) \ No newline at end of file diff --git a/moorse/clients/message/sms_client.py b/moorse/clients/message/sms_client.py new file mode 100644 index 0000000..b1fc5fa --- /dev/null +++ b/moorse/clients/message/sms_client.py @@ -0,0 +1,13 @@ +import requests +from enums.url import URL +from dto.message.message_sent_response import MessageSentResponse + +class SmsClient: + + def send_text(self, token: str, integration_id: str, to: str, body: str): + response = requests.post( + URL.SMS_TEXT_MESSAGE.value.format(integration_id), + json = {'to': to, 'body': body}, + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessageSentResponse(response) \ No newline at end of file diff --git a/moorse/clients/message/whatsapp_client.py b/moorse/clients/message/whatsapp_client.py new file mode 100644 index 0000000..d9a1d0f --- /dev/null +++ b/moorse/clients/message/whatsapp_client.py @@ -0,0 +1,48 @@ +import requests +from enums.url import URL +from dto.message.message_sent_response import MessageSentResponse +from dto.message.menu.menu_message_request import MenuMessageRequest +from dto.message.buttons.buttons_message_request import ButtonsMessageRequest +from dto.message.template.template_message_request import TemplateMessageRequest + +class WhatsappClient: + + def send_text(self, token: str, to: str, body: str, integration_id: str) -> MessageSentResponse: + response = requests.post( + URL.WHATSAPP_TEXT_MESSAGE.value.format(integration_id), + json = {'to': to, 'body': body}, + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessageSentResponse(response) + + def send_file(self, token: str, to: str, body: str, filename: str, integration_id: str, caption: str = None) -> MessageSentResponse: + response = requests.post( + URL.WHATSAPP_FILE_MESSAGE.value.format(integration_id), + json = {'to': to, 'body': body, 'filename': filename, 'caption': caption}, + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessageSentResponse(response) + + def send_list_menu(self, token: str, menu: MenuMessageRequest, integration_id: str) -> MessageSentResponse: + response = requests.post( + URL.WHATSAPP_LIST_MENU_MESSAGE.value.format(integration_id), + json = menu.to_json(), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessageSentResponse(response) + + def send_buttons(self, token: str, buttons: ButtonsMessageRequest, integration_id: str) -> MessageSentResponse: + response = requests.post( + URL.WHATSAPP_BUTTONS_MESSAGE.value.format(integration_id), + json = buttons.to_json(), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessageSentResponse(response) + + def send_template(self, token: str, template: TemplateMessageRequest, integration_id: str) -> MessageSentResponse: + response = requests.post( + URL.WHATSAPP_TEMPLATE_MESSAGE.value.format(integration_id), + json = template.to_json(), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessageSentResponse(response) \ No newline at end of file diff --git a/moorse/clients/report_client.py b/moorse/clients/report_client.py new file mode 100644 index 0000000..adbb07b --- /dev/null +++ b/moorse/clients/report_client.py @@ -0,0 +1,29 @@ +from dto.reports.standard.messages_report_dto import MessagesReportDto +from dto.reports.channel.messages_by_channel_report_dto import MessagesByChannelReportDto +from dto.reports.timeline.messages_by_timeline_report_dto import MessagesByTimelineReportDto +from enums.url import URL +import requests +import json + +class ReportClient: + + def get_messages(self, token: str, begin: str, end: str) -> MessagesReportDto: + response = requests.get( + URL.REPORT.value.format(begin, end), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessagesReportDto(response) + + def get_messages_by_channel(self, token: str, begin: str, end: str) -> MessagesByChannelReportDto: + response = requests.get( + URL.REPORT_BY_CHANNEL.value.format(begin, end), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessagesByChannelReportDto(response) + + def get_messages_by_timeline(self, token: str, begin: str, end: str) -> MessagesByTimelineReportDto: + response = requests.get( + URL.REPORT_BY_TIMELINE.value.format(begin, end), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return MessagesByTimelineReportDto(response) \ No newline at end of file diff --git a/moorse/clients/template_client.py b/moorse/clients/template_client.py new file mode 100644 index 0000000..dfea44d --- /dev/null +++ b/moorse/clients/template_client.py @@ -0,0 +1,39 @@ +from dto.template.template_dto import TemplateDto +from dto.template.request.template_request import TemplateRequest +from dto.template.response.multiple.template_list import TemplateList +from enums.url import URL +import requests + +class TemplateClient: + + def create(self, token: str, template: TemplateRequest) -> TemplateDto: + response = requests.post( + URL.TEMPLATE.value, + json = template.to_json(), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return TemplateDto(response) + + def delete(self, token: str, template_id: str) -> TemplateDto: + response = None + try: + response = requests.delete( + URL.SEARCH_TEMPLATE.value.format(template_id), + headers = {'Authorization': f"Bearer {token}"} + ).json() + except: response = { 'data': None, 'errors': [] } + return TemplateDto(response) + + def get_one(self, token: str, template_id: str) -> TemplateDto: + response = requests.get( + URL.SEARCH_TEMPLATE.value.format(template_id), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return TemplateDto(response) + + def get_all(self, token: str) -> TemplateList: + response = requests.get( + URL.TEMPLATE.value, + headers = {'Authorization': f"Bearer {token}"} + ).json() + return TemplateList(response) diff --git a/moorse/clients/webhook_client.py b/moorse/clients/webhook_client.py new file mode 100644 index 0000000..aa44b2f --- /dev/null +++ b/moorse/clients/webhook_client.py @@ -0,0 +1,48 @@ +from dto.webhook.response.multiple.webhook_list import WebhookList +from dto.webhook.response.webhook_dto import WebhookDto +from dto.webhook.webhook_request import WebhookRequest +from enums.url import URL +import requests +import json + +class WebhookClient: + + def create(self, token: str, webhook: WebhookRequest) -> WebhookDto: + response = requests.post( + URL.WEBHOOK.value, + json = webhook.to_json(), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return WebhookDto(response) + + def update(self, token: str, webhook_id: str, webhook: WebhookRequest) -> WebhookDto: + response = requests.put( + URL.SEARCH_WEBHOOK.value.format(webhook_id), + json = webhook.to_json(), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return WebhookDto(response) + + def delete(self, token: str, webhook_id: str) -> WebhookDto: + response = None + try: + response = requests.delete( + URL.SEARCH_WEBHOOK.value.format(webhook_id), + headers = {'Authorization': f"Bearer {token}"} + ).json() + except: response = { 'data': None, 'errors': [] } + return WebhookDto(response) + + def getOne(self, token: str, webhook_id: str) -> WebhookDto: + response = requests.get( + URL.SEARCH_WEBHOOK.value.format(webhook_id), + headers = {'Authorization': f"Bearer {token}"} + ).json() + return WebhookDto(response) + + def getAll(self, token: str) -> WebhookList: + response = requests.get( + URL.WEBHOOK.value, + headers = {'Authorization': f"Bearer {token}"} + ).json() + return WebhookList(response) diff --git a/moorse/dto/authorization/login_response.py b/moorse/dto/authorization/login_response.py new file mode 100644 index 0000000..04b6d3e --- /dev/null +++ b/moorse/dto/authorization/login_response.py @@ -0,0 +1,10 @@ +import json + +class LoginResponse: + + data: str + errors: list[str] + + def __init__(self, data: dict[str, object]): + self.data = data.get('data') + self.errors = data.get('errors') \ No newline at end of file diff --git a/moorse/dto/billing/billing_data.py b/moorse/dto/billing/billing_data.py new file mode 100644 index 0000000..740ee3c --- /dev/null +++ b/moorse/dto/billing/billing_data.py @@ -0,0 +1,17 @@ +class BillingData: + + integration_id: str = None + balance: int = None + credit: int = None + channel: str = None + billing_type: str = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.integration_id = data.get('integrationId') + self.balance = data.get('balance') + self.credit = data.get('credit') + self.channel = data.get('channel') + self.billing_type = data.get('billingType') \ No newline at end of file diff --git a/moorse/dto/billing/billing_dto.py b/moorse/dto/billing/billing_dto.py new file mode 100644 index 0000000..f362e8e --- /dev/null +++ b/moorse/dto/billing/billing_dto.py @@ -0,0 +1,13 @@ +from dto.billing.billing_data import BillingData + +class BillingDto: + + data: BillingData = None + errors: list[str] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.data = BillingData(data.get('data')) + self.errors = data.get('errors') \ No newline at end of file diff --git a/moorse/dto/integration/delete/integration_deletion_data.py b/moorse/dto/integration/delete/integration_deletion_data.py new file mode 100644 index 0000000..91f8e85 --- /dev/null +++ b/moorse/dto/integration/delete/integration_deletion_data.py @@ -0,0 +1,12 @@ +from dto.integration.delete.integration_deletion_message import IntegrationDeletionMessage +from dto.moorse_error import MoorseError + +class IntegrationDeletionData: + + data: IntegrationDeletionMessage = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + if(data == None): return + self.data = IntegrationDeletionMessage(data['data']) + self.errors = [MoorseError(error) for error in data['errors']] \ No newline at end of file diff --git a/moorse/dto/integration/delete/integration_deletion_message.py b/moorse/dto/integration/delete/integration_deletion_message.py new file mode 100644 index 0000000..4574684 --- /dev/null +++ b/moorse/dto/integration/delete/integration_deletion_message.py @@ -0,0 +1,7 @@ +class IntegrationDeletionMessage: + + message: str = None + + def __init__(self, data: dict[str, object]): + if(data == None): return + self.message = data['message'] \ No newline at end of file diff --git a/moorse/dto/integration/get_all/integrations_content.py b/moorse/dto/integration/get_all/integrations_content.py new file mode 100644 index 0000000..f9ed79a --- /dev/null +++ b/moorse/dto/integration/get_all/integrations_content.py @@ -0,0 +1,9 @@ +from dto.integration.get_all.integrations_data_attributes import IntegrationsDataAttributes + +class IntegrationsContent: + + content: list[IntegrationsDataAttributes] = [] + + def __init__(self, data: dict[str, object]): + if(data == None): return + self.content = [IntegrationsDataAttributes(content) for content in data.get('content')] \ No newline at end of file diff --git a/moorse/dto/integration/get_all/integrations_data.py b/moorse/dto/integration/get_all/integrations_data.py new file mode 100644 index 0000000..b734823 --- /dev/null +++ b/moorse/dto/integration/get_all/integrations_data.py @@ -0,0 +1,12 @@ +from dto.moorse_error import MoorseError +from dto.integration.get_all.integrations_content import IntegrationsContent + +class IntegrationsData: + + data: IntegrationsContent = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + if(data == None): return + self.data = IntegrationsContent(data.get('data')) + self.errors = [MoorseError(error) for error in data['errors']] \ No newline at end of file diff --git a/moorse/dto/integration/get_all/integrations_data_attributes.py b/moorse/dto/integration/get_all/integrations_data_attributes.py new file mode 100644 index 0000000..6f98c7c --- /dev/null +++ b/moorse/dto/integration/get_all/integrations_data_attributes.py @@ -0,0 +1,25 @@ +class IntegrationsDataAttributes: + + id: str = None + name: str = None + description: str = None + account_name: str = None + account_description: str = None + type: str = None + external_id: str = None + trial: bool = None + official: bool = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.id = data.get('id') + self.name = data.get('name') + self.description = data.get('description') + self.account_name = data.get('accountName') + self.account_description = data.get('accountDescription') + self.type = data.get('type') + self.external_id = data.get('externalId') + self.trial = data.get('trial') + self.official = data.get('official') \ No newline at end of file diff --git a/moorse/dto/integration/get_one/integration_data.py b/moorse/dto/integration/get_one/integration_data.py new file mode 100644 index 0000000..35e2899 --- /dev/null +++ b/moorse/dto/integration/get_one/integration_data.py @@ -0,0 +1,15 @@ +from dto.integration.get_one.integration_data_attributes import IntegrationDataAttributes +from dto.moorse_error import MoorseError + +class IntegrationData: + + data: IntegrationDataAttributes = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.data = IntegrationDataAttributes(data.get('data')) + self.errors = [MoorseError(error) for error in data.get('errors')] + diff --git a/moorse/dto/integration/get_one/integration_data_attributes.py b/moorse/dto/integration/get_one/integration_data_attributes.py new file mode 100644 index 0000000..d4758ec --- /dev/null +++ b/moorse/dto/integration/get_one/integration_data_attributes.py @@ -0,0 +1,49 @@ +from dto.webhook.response.webhook_response import WebhookResponse + +class IntegrationDataAttributes: + + id: str = None + name: str = None + description: str = None + account_name: str = None + account_description: str = None + type: str = None + external_id: str = None + moorse_management: bool = None + billing_type: str = None + device: str = None + model: str = None + battery: int = None + state: str = None + avatar: str = None + phone_description: str = None + trial: bool = None + official: bool = None + external_client_id: str = None + external_channel_id: str = None + webhooks: list[WebhookResponse] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.id = data.get('id') + self.name = data.get('name') + self.description = data.get('description') + self.account_name = data.get('accountName') + self.account_description = data.get('accountDescription') + self.type = data.get('type') + self.external_id = data.get('externalId') + self.moorse_management = data.get('moorseManagement') + self.billing_type = data.get('billingType') + self.device = data.get('device') + self.model = data.get('model') + self.battery = data.get('battery') + self.state = data.get('state') + self.avatar = data.get('avatar') + self.phone_description = data.get('phoneDescription') + self.trial = data.get('trial') + self.official = data.get('official') + self.external_client_id = data.get('externalClientId') + self.external_channel_id = data.get('externalChannelId') + self.webhooks = [WebhookResponse(webhook) for webhook in data.get('webhooks')] \ No newline at end of file diff --git a/moorse/dto/integration/get_status/integration_status.py b/moorse/dto/integration/get_status/integration_status.py new file mode 100644 index 0000000..9dbd97c --- /dev/null +++ b/moorse/dto/integration/get_status/integration_status.py @@ -0,0 +1,9 @@ +class IntegrationStatus: + + status: str = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.status = data.get('status') \ No newline at end of file diff --git a/moorse/dto/integration/get_status/integration_status_data.py b/moorse/dto/integration/get_status/integration_status_data.py new file mode 100644 index 0000000..98d6173 --- /dev/null +++ b/moorse/dto/integration/get_status/integration_status_data.py @@ -0,0 +1,14 @@ +from dto.moorse_error import MoorseError +from dto.integration.get_status.integration_status import IntegrationStatus + +class IntegrationStatusData: + + data: IntegrationStatus = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.data = IntegrationStatus(data.get('data')) + self.errors = [MoorseError(error) for error in data.get('errors')] \ No newline at end of file diff --git a/moorse/dto/message/buttons/button.py b/moorse/dto/message/buttons/button.py new file mode 100644 index 0000000..664f3c3 --- /dev/null +++ b/moorse/dto/message/buttons/button.py @@ -0,0 +1,14 @@ +class Button: + + id: str + title: str + + def __init__(self, id: str, title: str): + self.id = id + self.title = title + + def to_json(self): + return { + 'id': self.id, + 'title': self.title, + } \ No newline at end of file diff --git a/moorse/dto/message/buttons/buttons_message_request.py b/moorse/dto/message/buttons/buttons_message_request.py new file mode 100644 index 0000000..679db74 --- /dev/null +++ b/moorse/dto/message/buttons/buttons_message_request.py @@ -0,0 +1,19 @@ +from dto.message.buttons.button import Button + +class ButtonsMessageRequest: + + to: str + title: str + buttons: list[Button] + + def __init__(self, to: str, title: str, buttons: list[Button]): + self.to = to + self.title = title + self.buttons = buttons + + def to_json(self): + return { + 'to': self.to, + 'title': self.title, + 'buttonsId': [button.to_json() for button in self.buttons], + } \ No newline at end of file diff --git a/moorse/dto/message/menu/action.py b/moorse/dto/message/menu/action.py new file mode 100644 index 0000000..e99d6f8 --- /dev/null +++ b/moorse/dto/message/menu/action.py @@ -0,0 +1,13 @@ +from dto.message.menu.section import Section + +class Action: + + sections: list[Section] + + def __init__(self, sections: list[Section]): + self.sections = sections + + def to_json(self): + return { + 'sections': [section.to_json() for section in self.sections] + } \ No newline at end of file diff --git a/moorse/dto/message/menu/menu_message_request.py b/moorse/dto/message/menu/menu_message_request.py new file mode 100644 index 0000000..77fd08e --- /dev/null +++ b/moorse/dto/message/menu/menu_message_request.py @@ -0,0 +1,19 @@ +from dto.message.menu.action import Action + +class MenuMessageRequest: + + to: str + body: str + action: Action + + def __init__(self, to: str, body: str, action: Action): + self.to = to + self.body = body + self.action = action + + def to_json(self): + return { + 'to': self.to, + 'body': self.body, + 'action': self.action.to_json() + } \ No newline at end of file diff --git a/moorse/dto/message/menu/row.py b/moorse/dto/message/menu/row.py new file mode 100644 index 0000000..7a36b18 --- /dev/null +++ b/moorse/dto/message/menu/row.py @@ -0,0 +1,14 @@ +class Row: + + id: str + title: str + + def __init__(self, id: str, title: str): + self.id = id + self.title = title + + def to_json(self): + return { + 'id': self.id, + 'title': self.title + } \ No newline at end of file diff --git a/moorse/dto/message/menu/section.py b/moorse/dto/message/menu/section.py new file mode 100644 index 0000000..ccdd9d4 --- /dev/null +++ b/moorse/dto/message/menu/section.py @@ -0,0 +1,16 @@ +from dto.message.menu.row import Row + +class Section: + + title: str + rows: list[Row] + + def __init__(self, title: str, rows: list[Row]): + self.title = title + self.rows = rows + + def to_json(self): + return { + "title": self.title, + "rows": [row.to_json() for row in self.rows] + } \ No newline at end of file diff --git a/moorse/dto/message/message_sent_response.py b/moorse/dto/message/message_sent_response.py new file mode 100644 index 0000000..777174c --- /dev/null +++ b/moorse/dto/message/message_sent_response.py @@ -0,0 +1,11 @@ +from dto.message.message_sent_response_data import MessageSentResponseData + +class MessageSentResponse: + + data: MessageSentResponseData = None + errors: list[str] = [] + + def __init__(self, data: dict[str, object]): + if(data == None or not isinstance(data, dict)): return + self.data = MessageSentResponseData(data.get('data')) + self.errors = data.get('errors') \ No newline at end of file diff --git a/moorse/dto/message/message_sent_response_data.py b/moorse/dto/message/message_sent_response_data.py new file mode 100644 index 0000000..91c34d9 --- /dev/null +++ b/moorse/dto/message/message_sent_response_data.py @@ -0,0 +1,11 @@ +class MessageSentResponseData: + + control: str + creation_date: str + message: str + + def __init__(self, data: dict[str, object]): + if(data == None or not isinstance(data, dict)): return + self.control = data.get('control') + self.creation_date = data.get('creation_date') + self.message = data.get('message') \ No newline at end of file diff --git a/moorse/dto/message/template/component.py b/moorse/dto/message/template/component.py new file mode 100644 index 0000000..8fd0e10 --- /dev/null +++ b/moorse/dto/message/template/component.py @@ -0,0 +1,16 @@ +from dto.message.template.parameter.parameter import Parameter + +class Component: + + type: str + parameters: list[Parameter] + + def __init__(self, type: str, parameters: list[Parameter]): + self.type = type + self.parameters = parameters + + def to_json(self): + return { + "type": self.type, + "parameters": [parameter.to_json() for parameter in self.parameters] + } \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/document_parameter.py b/moorse/dto/message/template/parameter/document_parameter.py new file mode 100644 index 0000000..18585c6 --- /dev/null +++ b/moorse/dto/message/template/parameter/document_parameter.py @@ -0,0 +1,7 @@ +from dto.message.template.parameter.parameter import Parameter +from dto.message.template.parameter.file_info.document_info import DocumentInfo + +class DocumentParameter(Parameter): + + def __init__(self, url: str, filename: str): + super().__init__("document", None, None, DocumentInfo(url, filename), None) \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/file_info/document_info.py b/moorse/dto/message/template/parameter/file_info/document_info.py new file mode 100644 index 0000000..f5c98f6 --- /dev/null +++ b/moorse/dto/message/template/parameter/file_info/document_info.py @@ -0,0 +1,14 @@ +class DocumentInfo: + + link: str + filename: str + + def __init__(self, link: str, filename: str): + self.link = link + self.filename = filename + + def to_json(self): + return { + "link": self.link, + "filename": self.filename + } \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/file_info/image_info.py b/moorse/dto/message/template/parameter/file_info/image_info.py new file mode 100644 index 0000000..0be62c9 --- /dev/null +++ b/moorse/dto/message/template/parameter/file_info/image_info.py @@ -0,0 +1,11 @@ +class ImageInfo: + + link: str + + def __init__(self, link: str): + self.link = link + + def to_json(self): + return { + "link": self.link + } \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/file_info/video_info.py b/moorse/dto/message/template/parameter/file_info/video_info.py new file mode 100644 index 0000000..03fb9ab --- /dev/null +++ b/moorse/dto/message/template/parameter/file_info/video_info.py @@ -0,0 +1,11 @@ +class VideoInfo: + + link: str + + def __init__(self, link: str): + self.link = link + + def to_json(self): + return { + "link": self.link + } \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/image_parameter.py b/moorse/dto/message/template/parameter/image_parameter.py new file mode 100644 index 0000000..0f17124 --- /dev/null +++ b/moorse/dto/message/template/parameter/image_parameter.py @@ -0,0 +1,7 @@ +from dto.message.template.parameter.parameter import Parameter +from dto.message.template.parameter.file_info.image_info import ImageInfo + +class ImageParameter: + + def __init__(self, url: str): + super().__init__("image", None, ImageInfo(url), None, None) \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/parameter.py b/moorse/dto/message/template/parameter/parameter.py new file mode 100644 index 0000000..b19a34f --- /dev/null +++ b/moorse/dto/message/template/parameter/parameter.py @@ -0,0 +1,34 @@ +from dto.message.template.parameter.file_info.image_info import ImageInfo +from dto.message.template.parameter.file_info.document_info import DocumentInfo +from dto.message.template.parameter.file_info.video_info import VideoInfo + +class Parameter: + + type: str + text: str + image: ImageInfo + document: DocumentInfo + video: VideoInfo + + def __init__( + self, + type: str, + text: str, + image: ImageInfo, + document: DocumentInfo, + video: VideoInfo + ): + self.type = type + self.text = text + self.image = image + self.document = document + self.video = video + + def to_json(self): + return { + "type": self.type, + "text": self.text if self.text else None, + "image": self.image.to_json() if self.image else None, + "document": self.document.to_json() if self.document else None, + "video": self.video.to_json() if self.video else None + } \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/text_parameter.py b/moorse/dto/message/template/parameter/text_parameter.py new file mode 100644 index 0000000..0963057 --- /dev/null +++ b/moorse/dto/message/template/parameter/text_parameter.py @@ -0,0 +1,6 @@ +from dto.message.template.parameter.parameter import Parameter + +class ImageParameter(Parameter): + + def __init__(self, text: str): + super().__init__("text", text, None, None, None) \ No newline at end of file diff --git a/moorse/dto/message/template/parameter/video_parameter.py b/moorse/dto/message/template/parameter/video_parameter.py new file mode 100644 index 0000000..86c096d --- /dev/null +++ b/moorse/dto/message/template/parameter/video_parameter.py @@ -0,0 +1,8 @@ +from dto.message.template.parameter.parameter import Parameter +from dto.message.template.parameter.file_info.video_info import VideoInfo + +class VideoParameter(Parameter): + + def __init__(self, url: str): + super().__init__("video", None, None, None, VideoInfo(url)) + self.url = url \ No newline at end of file diff --git a/moorse/dto/message/template/template_message_request.py b/moorse/dto/message/template/template_message_request.py new file mode 100644 index 0000000..feb2b09 --- /dev/null +++ b/moorse/dto/message/template/template_message_request.py @@ -0,0 +1,19 @@ +from dto.message.template.component import Component + +class TemplateMessageRequest: + + to: str + template_name: str + components: list[Component] + + def __init__(self, to: str, template_name: str, components: list[Component]): + self.to = to + self.template_name = template_name + self.components = components + + def to_json(self): + return { + 'to': self.to, + 'template_name': self.template_name, + 'components': [component.to_json() for component in self.components] + } \ No newline at end of file diff --git a/moorse/dto/moorse_error.py b/moorse/dto/moorse_error.py new file mode 100644 index 0000000..9adcdc7 --- /dev/null +++ b/moorse/dto/moorse_error.py @@ -0,0 +1,11 @@ +class MoorseError: + + code: str = None + message: str = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.code = data.get('code') + self.message = data.get('message') \ No newline at end of file diff --git a/moorse/dto/pair.py b/moorse/dto/pair.py new file mode 100644 index 0000000..268ff80 --- /dev/null +++ b/moorse/dto/pair.py @@ -0,0 +1,8 @@ +class Pair: + + key: str + value: str + + def __init__(self, key: str, value: str): + self.key = key + self.value = value \ No newline at end of file diff --git a/moorse/dto/reports/channel/messages_by_channel_report_dto.py b/moorse/dto/reports/channel/messages_by_channel_report_dto.py new file mode 100644 index 0000000..a41ddbf --- /dev/null +++ b/moorse/dto/reports/channel/messages_by_channel_report_dto.py @@ -0,0 +1,12 @@ +from dto.reports.channel.report_channel_data import ReportChannelData +from dto.moorse_error import MoorseError + +class MessagesByChannelReportDto: + + data: ReportChannelData = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + if(data == None): return + self.data = ReportChannelData(data.get('data')) + self.errors = [MoorseError(error) for error in data.get('errors')] \ No newline at end of file diff --git a/moorse/dto/reports/channel/report_channel_data.py b/moorse/dto/reports/channel/report_channel_data.py new file mode 100644 index 0000000..7955311 --- /dev/null +++ b/moorse/dto/reports/channel/report_channel_data.py @@ -0,0 +1,19 @@ +class ReportChannelData: + + whatsapp: int = None + messenger: int = None + instagram: int = None + telegram: int = None + sms: int = None + email: int = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.whatsapp = data.get('whatsapp') + self.messenger = data.get('messenger') + self.instagram = data.get('instagram') + self.telegram = data.get('telegram') + self.sms = data.get('sms') + self.email = data.get('email') \ No newline at end of file diff --git a/moorse/dto/reports/standard/messages_report_dto.py b/moorse/dto/reports/standard/messages_report_dto.py new file mode 100644 index 0000000..bc2b76e --- /dev/null +++ b/moorse/dto/reports/standard/messages_report_dto.py @@ -0,0 +1,14 @@ +from dto.reports.standard.report_data import ReportData +from dto.moorse_error import MoorseError + +class MessagesReportDto: + + data: ReportData = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.data = ReportData(data.get('data')) + self.errors = [MoorseError(error) for error in data.get('errors')] \ No newline at end of file diff --git a/moorse/dto/reports/standard/report_data.py b/moorse/dto/reports/standard/report_data.py new file mode 100644 index 0000000..9ae1eee --- /dev/null +++ b/moorse/dto/reports/standard/report_data.py @@ -0,0 +1,13 @@ +class ReportData: + + total_messages_sent: int = None + total_messages_received: int = None + total_contacts: int = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.total_messages_sent = data.get('totalMessageSent') + self.total_messages_received = data.get('totalMessagesReceived') + self.total_contacts = data.get('totalContacts') \ No newline at end of file diff --git a/moorse/dto/reports/timeline/date_message_counter.py b/moorse/dto/reports/timeline/date_message_counter.py new file mode 100644 index 0000000..ad08953 --- /dev/null +++ b/moorse/dto/reports/timeline/date_message_counter.py @@ -0,0 +1,9 @@ +class DateMessageCounter: + + date: str = None + total: int = None + + def __init__(self, data: dict[str, object]): + if(data == None): return + self.date = data.get('date') + self.total = data.get('total') \ No newline at end of file diff --git a/moorse/dto/reports/timeline/messages_by_timeline_report_dto.py b/moorse/dto/reports/timeline/messages_by_timeline_report_dto.py new file mode 100644 index 0000000..711e632 --- /dev/null +++ b/moorse/dto/reports/timeline/messages_by_timeline_report_dto.py @@ -0,0 +1,16 @@ +from dto.reports.timeline.report_timeline_data import ReportTimelineData +from dto.moorse_error import MoorseError + +class MessagesByTimelineReportDto: + + data: ReportTimelineData = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.data = ReportTimelineData(data.get('data')) + + for i in data.get('errors'): + self.errors.append(MoorseError(i)) \ No newline at end of file diff --git a/moorse/dto/reports/timeline/report_timeline_data.py b/moorse/dto/reports/timeline/report_timeline_data.py new file mode 100644 index 0000000..498ed35 --- /dev/null +++ b/moorse/dto/reports/timeline/report_timeline_data.py @@ -0,0 +1,21 @@ +from dto.reports.timeline.date_message_counter import DateMessageCounter + +class ReportTimelineData: + + total_send: int = None + total_received: int = None + send: list[DateMessageCounter] = [] + received: list[DateMessageCounter] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.total_send = data.get('totalSend') + self.total_received = data.get('totalReceived') + + for i in data.get('send'): + self.send.append(DateMessageCounter(i)) + + for i in data.get('received'): + self.received.append(DateMessageCounter(i)) \ No newline at end of file diff --git a/moorse/dto/template/button/button.py b/moorse/dto/template/button/button.py new file mode 100644 index 0000000..3f3a0de --- /dev/null +++ b/moorse/dto/template/button/button.py @@ -0,0 +1,32 @@ +from enums.template.button_type import ButtonType + +class Button: + + type: ButtonType = None + text: str = None + url: str = None + phone_number: str = None + example: list[str] = None + + def __init__( + self, + type: ButtonType, + text: str, + url: str, + phone_number: str, + example: list[str] = None + ): + self.type = type + self.text = text + self.url = url + self.phone_number = phone_number + self.example = example + + def to_json(self) -> dict: + return { + "type": self.type.value, + "text": self.text, + "url": self.url, + "phoneNumber": self.phone_number, + "example": self.example + } \ No newline at end of file diff --git a/moorse/dto/template/button/button_phone_number.py b/moorse/dto/template/button/button_phone_number.py new file mode 100644 index 0000000..9093468 --- /dev/null +++ b/moorse/dto/template/button/button_phone_number.py @@ -0,0 +1,17 @@ +from dto.template.button.button import Button +from enums.template.button_type import ButtonType + +class ButtonPhoneNumber(Button): + + def __init__( + self, + phone_number: str, + example: list[str] = None + ): + super().__init__( + ButtonType.PHONE_NUMBER, + None, + None, + phone_number, + example + ) \ No newline at end of file diff --git a/moorse/dto/template/button/button_quick_reply.py b/moorse/dto/template/button/button_quick_reply.py new file mode 100644 index 0000000..8c941a8 --- /dev/null +++ b/moorse/dto/template/button/button_quick_reply.py @@ -0,0 +1,17 @@ +from dto.template.button.button import Button +from enums.template.button_type import ButtonType + +class ButtonQuickReply(Button): + + def __init__( + self, + text: str, + example: list[str] = None + ): + super().__init__( + ButtonType.QUICK_REPLY, + text, + None, + None, + example + ) \ No newline at end of file diff --git a/moorse/dto/template/button/button_url.py b/moorse/dto/template/button/button_url.py new file mode 100644 index 0000000..97f6bcf --- /dev/null +++ b/moorse/dto/template/button/button_url.py @@ -0,0 +1,18 @@ +from dto.template.button.button import Button +from enums.template.button_type import ButtonType + +class ButtonUrl(Button): + + def __init__( + self, + text: str, + url: str, + example: list[str] = None + ): + super().__init__( + ButtonType.URL, + text, + url, + None, + example + ) \ No newline at end of file diff --git a/moorse/dto/template/component/template_button_component.py b/moorse/dto/template/component/template_button_component.py new file mode 100644 index 0000000..be78e9c --- /dev/null +++ b/moorse/dto/template/component/template_button_component.py @@ -0,0 +1,19 @@ +from dto.template.component.template_component import TemplateComponent +from dto.template.button.button import Button +from dto.template.component.template_component_example import TemplateComponentExample +from enums.template.component.template_component_type import TemplateComponentType + +class TemplateButtonComponent(TemplateComponent): + + def __init__( + self, + buttons: list[Button], + example: TemplateComponentExample = None + ): + super().__init__( + type = TemplateComponentType.BUTTONS, + text = None, + format = None, + example = example, + buttons = buttons + ) \ No newline at end of file diff --git a/moorse/dto/template/component/template_component.py b/moorse/dto/template/component/template_component.py new file mode 100644 index 0000000..49c8280 --- /dev/null +++ b/moorse/dto/template/component/template_component.py @@ -0,0 +1,35 @@ +from enums.template.component.template_component_type import TemplateComponentType +from enums.template.component.template_component_format import TemplateComponentFormat +from dto.template.component.template_component_example import TemplateComponentExample +from dto.template.button.button import Button + +class TemplateComponent: + + type: TemplateComponentType = None + text: str = None + format: TemplateComponentFormat = None + example: TemplateComponentExample = None + buttons: list[Button] = None + + def __init__( + self, + type: TemplateComponentType, + text: str, + format: TemplateComponentFormat, + example: TemplateComponentExample = None, + buttons: list[Button] = None + ): + self.type = type + self.text = text + self.format = format + self.example = example + self.buttons = buttons + + def to_json(self): + return { + 'type': self.type.value, + 'text': self.text, + 'format': self.format.value if self.type.value == TemplateComponentType.HEADER.value else None, + 'example': self.example.to_json() if self.example else None, + 'buttons': [button.to_json() for button in self.buttons] if isinstance(self.buttons, list) else None + } \ No newline at end of file diff --git a/moorse/dto/template/component/template_component_example.py b/moorse/dto/template/component/template_component_example.py new file mode 100644 index 0000000..3b611a7 --- /dev/null +++ b/moorse/dto/template/component/template_component_example.py @@ -0,0 +1,15 @@ +class TemplateComponentExample: + + header_text: list[str] + body_text: list[list[str]] + header_handle: list[str] + + def __init__( + self, + header_text: list[str], + body_text: list[list[str]], + header_handle: list[str] + ): + self.header_text = header_text + self.body_text = body_text + self.header_handle = header_handle \ No newline at end of file diff --git a/moorse/dto/template/component/template_document_component.py b/moorse/dto/template/component/template_document_component.py new file mode 100644 index 0000000..832ea74 --- /dev/null +++ b/moorse/dto/template/component/template_document_component.py @@ -0,0 +1,19 @@ +from dto.template.component.template_component import TemplateComponent +from dto.template.component.template_component_example import TemplateComponentExample +from enums.template.component.template_component_format import TemplateComponentFormat +from enums.template.component.template_component_type import TemplateComponentType + +class TemplateDocumentComponent(TemplateComponent): + + def __init__( + self, + type: TemplateComponentType, + example: TemplateComponentExample = None + ): + super().__init__( + type = type, + text = None, + format = TemplateComponentFormat.DOCUMENT, + example = example, + buttons = None + ) \ No newline at end of file diff --git a/moorse/dto/template/component/template_image_component.py b/moorse/dto/template/component/template_image_component.py new file mode 100644 index 0000000..f7102f2 --- /dev/null +++ b/moorse/dto/template/component/template_image_component.py @@ -0,0 +1,19 @@ +from dto.template.component.template_component import TemplateComponent +from dto.template.component.template_component_example import TemplateComponentExample +from enums.template.component.template_component_format import TemplateComponentFormat +from enums.template.component.template_component_type import TemplateComponentType + +class TemplateImageComponent(TemplateComponent): + + def __init__( + self, + type: TemplateComponentType, + example: TemplateComponentExample = None + ): + super().__init__( + type = type, + text = None, + format = TemplateComponentFormat.IMAGE, + example = example, + buttons = None + ) \ No newline at end of file diff --git a/moorse/dto/template/component/template_text_component.py b/moorse/dto/template/component/template_text_component.py new file mode 100644 index 0000000..8baef83 --- /dev/null +++ b/moorse/dto/template/component/template_text_component.py @@ -0,0 +1,20 @@ +from dto.template.component.template_component import TemplateComponent +from dto.template.component.template_component_example import TemplateComponentExample +from enums.template.component.template_component_format import TemplateComponentFormat +from enums.template.component.template_component_type import TemplateComponentType + +class TemplateTextComponent(TemplateComponent): + + def __init__( + self, + type: TemplateComponentType, + text: str, + example: TemplateComponentExample = None + ): + super().__init__( + type = type, + text = text, + format = TemplateComponentFormat.TEXT, + example = example, + buttons = None + ) \ No newline at end of file diff --git a/moorse/dto/template/request/template_request.py b/moorse/dto/template/request/template_request.py new file mode 100644 index 0000000..2083713 --- /dev/null +++ b/moorse/dto/template/request/template_request.py @@ -0,0 +1,43 @@ +from enums.template.template_type import TemplateType +from enums.template.template_language import TemplateLanguage +from enums.template.template_category import TemplateCategory +from dto.template.component.template_component import TemplateComponent + +class TemplateRequest: + + name: str = None + description: str = None + type: TemplateType = None + integration_id: str = None + category: TemplateCategory = None + language: TemplateLanguage = None + components: list[TemplateComponent] = [] + + def __init__( + self, + name: str, + description: str, + type: TemplateType, + integration_id: str, + category: TemplateCategory, + language: TemplateLanguage, + components: list[TemplateComponent] + ): + self.name = name + self.description = description + self.type = type + self.integration_id = integration_id + self.category = category + self.language = language + self.components = components + + def to_json(self): + return { + 'name': self.name, + 'description': self.description, + 'type': self.type.value, + 'integrationId': self.integration_id, + 'category': self.category.value, + 'language': self.language.value, + 'components': [component.to_json() for component in self.components] + } \ No newline at end of file diff --git a/moorse/dto/template/response/multiple/template_list.py b/moorse/dto/template/response/multiple/template_list.py new file mode 100644 index 0000000..e1ce388 --- /dev/null +++ b/moorse/dto/template/response/multiple/template_list.py @@ -0,0 +1,16 @@ +from dto.template.response.multiple.template_list_content import TemplateListContent +from dto.moorse_error import MoorseError + +class TemplateList: + + data: TemplateListContent = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None or not isinstance(data, dict)): return + + if(data.get("errors") == None): data["errors"] = [] + + self.data = TemplateListContent(data.get("data")) + self.errors = [MoorseError(error) for error in data.get("errors", [])] \ No newline at end of file diff --git a/moorse/dto/template/response/multiple/template_list_content.py b/moorse/dto/template/response/multiple/template_list_content.py new file mode 100644 index 0000000..7ea916b --- /dev/null +++ b/moorse/dto/template/response/multiple/template_list_content.py @@ -0,0 +1,12 @@ +from dto.template.response.single.template_response import TemplateResponse + +class TemplateListContent: + + content: list[TemplateResponse] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None or not isinstance(data, dict)): return + if(data.get("content") == None): data["content"] = [] + + self.content = [TemplateResponse(template) for template in data.get("content")] \ No newline at end of file diff --git a/moorse/dto/template/response/single/template_response.py b/moorse/dto/template/response/single/template_response.py new file mode 100644 index 0000000..62c64b3 --- /dev/null +++ b/moorse/dto/template/response/single/template_response.py @@ -0,0 +1,75 @@ +from dto.template.request.template_request import TemplateRequest +from dto.template.component.template_component import TemplateComponent +from dto.template.button.button import Button +from enums.template.component.template_component_format import TemplateComponentFormat +from enums.template.template_type import TemplateType +from enums.template.template_language import TemplateLanguage +from enums.template.template_category import TemplateCategory +from enums.template.button_type import ButtonType +import json + +class TemplateResponse(TemplateRequest): + + id: str = None + creation_date: str = None + last_update_date: str = None + client_id: str = None + status: str = None + rejected_reason: str = None + template_fb: str = None + + def __init__(self, data: dict[str, object]): + + if(data == None or not isinstance(data, dict)): return + + self.id = data.get("id") + self.creation_date = data.get("creationDate") + self.last_update_date = data.get("lastUpdateDate") + self.client_id = data.get("clientId") + self.status = data.get("status") + self.rejected_reason = data.get("rejectedReason") + self.template_fb = data.get("templateFb") + + super().__init__( + data.get("name"), + data.get("description"), + TemplateType(data.get("type")) if data.get("type") != None else None, + data.get("integrationId"), + TemplateCategory(data.get("category")) if data.get("category") != None else None, + TemplateLanguage(data.get("language")) if data.get("language") != None else None, + self.__getComponentsList(data.get("components")) + ) + + def __getComponentsList(self, components: list[dict[str, object]]) -> list[TemplateComponent]: + + if(components == None or not isinstance(components, list)): return None + + answer: list[TemplateComponent] = [] + + for comp in components: + if(comp == None or not isinstance(comp, dict)): continue + answer.append(TemplateComponent( + comp.get("type"), + comp.get("text"), + TemplateComponentFormat(comp.get("format")), + None, + self.__getButtonList(comp.get("buttons")) + )) + + def __getButtonList(self, buttons: list[dict[str, object]]) -> list[Button]: + + if(buttons == None or not isinstance(buttons, list)): return None + + answer: list[Button] = [] + + for button in buttons: + if(button == None or not isinstance(button, dict)): continue + answer.append(Button( + ButtonType(button.get("type")), + button.get("text"), + button.get("url"), + button.get("phoneNumber"), + None + )) + + return answer \ No newline at end of file diff --git a/moorse/dto/template/template_dto.py b/moorse/dto/template/template_dto.py new file mode 100644 index 0000000..a432efc --- /dev/null +++ b/moorse/dto/template/template_dto.py @@ -0,0 +1,14 @@ +from dto.template.response.single.template_response import TemplateResponse +from dto.moorse_error import MoorseError + +class TemplateDto: + + data: TemplateResponse + errors: list[MoorseError] + + def __init__(self, data: dict[str, object]): + + if(data == None or not isinstance(data, dict)): return + + self.data = TemplateResponse(data.get("data")) + self.errors = data.get("errors") diff --git a/moorse/dto/webhook/response/multiple/webhook_list.py b/moorse/dto/webhook/response/multiple/webhook_list.py new file mode 100644 index 0000000..419bf2a --- /dev/null +++ b/moorse/dto/webhook/response/multiple/webhook_list.py @@ -0,0 +1,15 @@ +from dto.webhook.response.multiple.webhook_list_data import WebhookListData +from dto.moorse_error import MoorseError + +class WebhookList: + + data: WebhookListData = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.data = WebhookListData(data.get('data')) + for error in data.get('errors'): + self.errors.append(MoorseError(error)) \ No newline at end of file diff --git a/moorse/dto/webhook/response/multiple/webhook_list_data.py b/moorse/dto/webhook/response/multiple/webhook_list_data.py new file mode 100644 index 0000000..76ea0c9 --- /dev/null +++ b/moorse/dto/webhook/response/multiple/webhook_list_data.py @@ -0,0 +1,14 @@ +from dto.webhook.response.multiple.webhook_list_element import WebhookListElement + +class WebhookListData: + + content: list[WebhookListElement] = [] + + def __init__(self, data: list[dict[str, object]]): + + if(data == None): return + + for webhoookData in data.get('content'): + self.content.append( + WebhookListElement(webhoookData) + ) \ No newline at end of file diff --git a/moorse/dto/webhook/response/multiple/webhook_list_element.py b/moorse/dto/webhook/response/multiple/webhook_list_element.py new file mode 100644 index 0000000..237bdfe --- /dev/null +++ b/moorse/dto/webhook/response/multiple/webhook_list_element.py @@ -0,0 +1,39 @@ +from enums.webhook.webhook_method import WebhookMethod + +class WebhookListElement: + + id: str = None + client_id: str = None + creation_date: str = None + last_update_date: str = None + + name: str = None + url: str = None + method: str = None + active: bool = None + sended: bool = None + received: bool = None + readed: bool = None + answered: bool = None + retries: int = None + timeout: int = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.id = data.get('id') + self.client_id = data.get('clientId') + self.creation_date = data.get('creationDate') + self.last_update_date = data.get('lastUpdateDate') + + self.name = data.get('name') + self.url = data.get('url') + self.method = data.get('method') + self.active = data.get('active') + self.sended = data.get('sended') + self.received = data.get('received') + self.readed = data.get('readed') + self.answered = data.get('answered') + self.retries = data.get('retries') + self.timeout = data.get('timeout') \ No newline at end of file diff --git a/moorse/dto/webhook/response/webhook_dto.py b/moorse/dto/webhook/response/webhook_dto.py new file mode 100644 index 0000000..2e48ce1 --- /dev/null +++ b/moorse/dto/webhook/response/webhook_dto.py @@ -0,0 +1,17 @@ +from dto.webhook.response.webhook_response import WebhookResponse +from dto.moorse_error import MoorseError + +class WebhookDto: + + data: WebhookResponse = None + errors: list[MoorseError] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.data = WebhookResponse(data.get('data')) + for error in data.get('errors'): + self.errors.append( + MoorseError(error) + ) \ No newline at end of file diff --git a/moorse/dto/webhook/response/webhook_header.py b/moorse/dto/webhook/response/webhook_header.py new file mode 100644 index 0000000..668d65c --- /dev/null +++ b/moorse/dto/webhook/response/webhook_header.py @@ -0,0 +1,19 @@ +class WebhookHeader: + + id: str = None + client_id: str = None + creation_date: str = None + last_update_date: str = None + key: str = None + value: str = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.id = data.get('id') + self.client_id = data.get('clientId') + self.creation_date = data.get('creationDate') + self.last_update_date = data.get('lastUpdateDate') + self.key = data.get('key') + self.value = data.get('value') \ No newline at end of file diff --git a/moorse/dto/webhook/response/webhook_integration.py b/moorse/dto/webhook/response/webhook_integration.py new file mode 100644 index 0000000..f3ceaf9 --- /dev/null +++ b/moorse/dto/webhook/response/webhook_integration.py @@ -0,0 +1,23 @@ +class WebhookIntegration: + + id: str = None + client_id: str = None + creation_date: str = None + last_update_date: str = None + + name: str = None + description: str = None + account_name: str = None + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.id = data.get('id') + self.client_id = data.get('clientId') + self.creation_date = data.get('creationDate') + self.last_update_date = data.get('lastUpdateDate') + + self.name = data.get('name') + self.description = data.get('description') + self.account_name = data.get('accountName') \ No newline at end of file diff --git a/moorse/dto/webhook/response/webhook_response.py b/moorse/dto/webhook/response/webhook_response.py new file mode 100644 index 0000000..4d01c9f --- /dev/null +++ b/moorse/dto/webhook/response/webhook_response.py @@ -0,0 +1,49 @@ +from enums.webhook.webhook_method import WebhookMethod +from dto.webhook.response.webhook_header import WebhookHeader +from dto.webhook.response.webhook_integration import WebhookIntegration + +class WebhookResponse: + + id: str = None + client_id: str = None + creation_date: str = None + last_update_date: str = None + + name: str = None + url: str = None + method: WebhookMethod = None + active: bool = None + sended: bool = None + received: bool = None + readed: bool = None + answered: bool = None + retries: int = None + timeout: int = None + + status_integration: bool = None + + headers: list[WebhookHeader] = [] + integrations: list[WebhookIntegration] = [] + + def __init__(self, data: dict[str, object]): + + if(data == None): return + + self.id = data.get('id') + self.client_id = data.get('clientId') + self.creation_date = data.get('creationDate') + self.last_update_date = data.get('lastUpdateDate') + + self.name = data.get('name') + self.url = data.get('url') + self.method = WebhookMethod(data.get('method').upper()) + self.active = data.get('active') + self.sended = data.get('sended') + self.received = data.get('received') + self.readed = data.get('readed') + self.answered = data.get('answered') + self.retries = data.get('retries') + self.timeout = data.get('timeout') + + self.headers = [WebhookHeader(header) for header in data.get('headers', [])] + self.integrations = [WebhookIntegration(integration) for integration in data.get('integrations', [])] \ No newline at end of file diff --git a/moorse/dto/webhook/webhook_request.py b/moorse/dto/webhook/webhook_request.py new file mode 100644 index 0000000..d55d6ff --- /dev/null +++ b/moorse/dto/webhook/webhook_request.py @@ -0,0 +1,66 @@ +from enums.webhook.webhook_method import WebhookMethod +from dto.pair import Pair + +class WebhookRequest: + + name: str + url: str + method: WebhookMethod + active: bool + integrations: list[str] + headers: list[Pair] + + answered: bool + received: bool + sent: bool + retries: int + timeout: int + + def __init__( + self, + name: str, + url: str, + method: WebhookMethod, + active: bool, + integrations: list[str], + headers: list[Pair], + answered: bool, + received: bool, + sent: bool, + retries: int, + timeout: int + ): + self.name = name + self.url = url + self.method = method + self.active = active + self.integrations = integrations + self.headers = headers + self.answered = answered + self.received = received + self.sent = sent + self.retries = retries + self.timeout = timeout + + def to_json(self): + + headers_list = [] + for header in self.headers: + headers_list.append({ + "key": header.key, + "value": header.value + }) + + return { + 'name': self.name, + 'url': self.url, + 'method': self.method.value, + 'active': self.active, + 'integrations': self.integrations, + 'headers': headers_list, + 'answered': self.answered, + 'received': self.received, + 'sent': self.sent, + 'retries': self.retries, + 'timeout': self.timeout + } \ No newline at end of file diff --git a/moorse/enums/communication_channel.py b/moorse/enums/communication_channel.py new file mode 100644 index 0000000..daba1af --- /dev/null +++ b/moorse/enums/communication_channel.py @@ -0,0 +1,6 @@ +from enum import Enum + +class CommunicationChannel(Enum): + WHATSAPP: str = "whatsapp" + INSTAGRAM: str = "instagram" + SMS: str = "sms" \ No newline at end of file diff --git a/moorse/enums/template/button_type.py b/moorse/enums/template/button_type.py new file mode 100644 index 0000000..a06e188 --- /dev/null +++ b/moorse/enums/template/button_type.py @@ -0,0 +1,6 @@ +from enum import Enum + +class ButtonType(Enum): + QUICK_REPLY = 'QUICK_REPLY' + URL = 'URL' + PHONE_NUMBER = 'PHONE_NUMBER' \ No newline at end of file diff --git a/moorse/enums/template/component/template_component_format.py b/moorse/enums/template/component/template_component_format.py new file mode 100644 index 0000000..89904a9 --- /dev/null +++ b/moorse/enums/template/component/template_component_format.py @@ -0,0 +1,8 @@ +from enum import Enum + +class TemplateComponentFormat(Enum): + + TEXT = "TEXT" + IMAGE = "IMAGE" + DOCUMENT = "DOCUMENT" + VIDEO = "VIDEO" \ No newline at end of file diff --git a/moorse/enums/template/component/template_component_type.py b/moorse/enums/template/component/template_component_type.py new file mode 100644 index 0000000..8087017 --- /dev/null +++ b/moorse/enums/template/component/template_component_type.py @@ -0,0 +1,8 @@ +from enum import Enum + +class TemplateComponentType(Enum): + + BODY = "BODY" + HEADER = "HEADER" + BUTTONS = "BUTTONS" + FOOTER = "FOOTER" \ No newline at end of file diff --git a/moorse/enums/template/template_category.py b/moorse/enums/template/template_category.py new file mode 100644 index 0000000..854d180 --- /dev/null +++ b/moorse/enums/template/template_category.py @@ -0,0 +1,15 @@ +from enum import Enum + +class TemplateCategory(Enum): + + ACCOUNT_UPDATE = 'ACCOUNT_UPDATE' + PAYMENT_UPDATE = 'PAYMENT_UPDATE' + PERSONAL_FINANCE_UPDATE = 'PERSONAL_FINANCE_UPDATE' + SHIPPING_UPDATE = 'SHIPPING_UPDATE' + RESERVATION_UPDATE = 'RESERVATION_UPDATE' + ISSUE_RESOLUTION = 'ISSUE_RESOLUTION' + APPOINTMENT_UPDATE = 'APPOINTMENT_UPDATE' + TRANSPORTATION_UPDATE = 'TRANSPORTATION_UPDATE' + TICKET_UPDATE = 'TICKET_UPDATE' + ALERT_UPDATE = 'ALERT_UPDATE' + AUTO_REPLY = 'AUTO_REPLY' \ No newline at end of file diff --git a/moorse/enums/template/template_language.py b/moorse/enums/template/template_language.py new file mode 100644 index 0000000..bf1447a --- /dev/null +++ b/moorse/enums/template/template_language.py @@ -0,0 +1,20 @@ +from enum import Enum + +class TemplateLanguage(Enum): + + PORTUGUESE_BR = 'pt_BR' + PORTUGUESE_PT = 'pt_PT' + ENGLISH = 'en' + ENGLISH_US = 'en_US' + ENGLISH_GB = 'en_GB' + JAPANESE = 'ja' + SPANISH_AR = 'es_AR' + SPANISH_ES = 'es_ES' + SPANISH_MX = 'es_MX' + CHINESE_CN = 'zh_CN' + CHINESE_HK = 'zh_HK' + CHINESE_TW = 'zh_TW' + DEUTSCH = 'de' + RUSSIAN = 'ru' + FRENCH = 'fr' + KOREAN = 'ko' \ No newline at end of file diff --git a/moorse/enums/template/template_type.py b/moorse/enums/template/template_type.py new file mode 100644 index 0000000..3eb0d07 --- /dev/null +++ b/moorse/enums/template/template_type.py @@ -0,0 +1,6 @@ +from enum import Enum + +class TemplateType(Enum): + + STANDARD = 'STANDARD' + MEDIA_INTERACTIVE = 'MEDIA_INTERACTIVE' \ No newline at end of file diff --git a/moorse/enums/url.py b/moorse/enums/url.py new file mode 100644 index 0000000..f3e6d2f --- /dev/null +++ b/moorse/enums/url.py @@ -0,0 +1,31 @@ +from enum import Enum + +class URL(Enum): + + AUTH_LOGIN = "https://api.moorse.io/oauth/login" + + WEBHOOK = "https://api.moorse.io/v1/webhooks" + SEARCH_WEBHOOK = "https://api.moorse.io/v1/webhooks/{}" + + TEMPLATE = "https://api.moorse.io/v1/templates" + SEARCH_TEMPLATE = "https://api.moorse.io/v1/templates/{}" + + REPORT = "https://api.moorse.io/v1/reports/total-messages?beginDate={}&endDate={}" + REPORT_BY_CHANNEL = "https://api.moorse.io/v1/reports/total-messages-channels?beginDate={}&endDate={}" + REPORT_BY_TIMELINE = "https://api.moorse.io/v1/reports/total-messages-timeline?beginDate={}&endDate={}" + + BILLING = "https://api.moorse.io/v2/whatsapp/{}/credit" + + WHATSAPP_TEXT_MESSAGE = "https://api.moorse.io/v2/whatsapp/{}/send-message" + WHATSAPP_FILE_MESSAGE = "https://api.moorse.io/v2/whatsapp/{}/send-file" + WHATSAPP_LIST_MENU_MESSAGE = "https://api.moorse.io/v2/whatsapp/{}/send-list-menu" + WHATSAPP_BUTTONS_MESSAGE = "https://api.moorse.io/v2/whatsapp/{}/send-buttons" + WHATSAPP_TEMPLATE_MESSAGE = "https://api.moorse.io/v2/whatsapp/{}/send-template" + + SMS_TEXT_MESSAGE = "https://api.moorse.io/v1/sms/{}/send-message" + + INSTAGRAM_TEXT_MESSAGE = "https://api.moorse.io/v1/instagram/{}/send-message" + + INTEGRATION = "https://api.moorse.io/v2/whatsapp" + SEARCH_INTEGRATION = "https://api.moorse.io/v2/whatsapp/{}" + SEARCH_INTEGRATION_STATUS = "https://api.moorse.io/v2/whatsapp/{}/status" \ No newline at end of file diff --git a/moorse/enums/webhook/webhook_method.py b/moorse/enums/webhook/webhook_method.py new file mode 100644 index 0000000..f8becb1 --- /dev/null +++ b/moorse/enums/webhook/webhook_method.py @@ -0,0 +1,5 @@ +from enum import Enum + +class WebhookMethod(Enum): + POST: str = "POST" + GET: str = "GET" \ No newline at end of file diff --git a/moorse/moorse.py b/moorse/moorse.py new file mode 100644 index 0000000..8a318e0 --- /dev/null +++ b/moorse/moorse.py @@ -0,0 +1,58 @@ +from enums.communication_channel import CommunicationChannel +from service.auth_service import AuthService +from service.webhook_service import WebhookService +from service.report_service import ReportService +from service.billing_service import BillingService +from service.message.whatsapp_service import WhatsappService +from service.message.instagram_service import InstagramService +from service.message.sms_service import SmsService +from service.integration_service import IntegrationService +from service.template_service import TemplateService +from dto.message.menu.menu_message_request import MenuMessageRequest +from dto.message.buttons.buttons_message_request import ButtonsMessageRequest +from dto.message.template.template_message_request import TemplateMessageRequest +from dto.message.message_sent_response import MessageSentResponse + +class Moorse: + + auth: AuthService + webhook: WebhookService + report: ReportService + billing: BillingService + template: TemplateService + integration: IntegrationService + __message_sender: object + + channel: CommunicationChannel + + def __init__(self, email: str, password: str, channel: CommunicationChannel): + + self.auth = AuthService(email, password) + self.webhook = WebhookService(self.auth) + self.report = ReportService(self.auth) + self.billing = BillingService(self.auth) + self.template = TemplateService(self.auth) + self.integration = IntegrationService(self.auth) + self.channel = channel + + if(channel.value == CommunicationChannel.WHATSAPP.value): + self.__message_sender = WhatsappService(self.auth) + if(channel.value == CommunicationChannel.INSTAGRAM.value): + self.__message_sender = InstagramService(self.auth) + if(channel.value == CommunicationChannel.SMS.value): + self.__message_sender = SmsService(self.auth) + + def send_text(self, to: str, body: str, integration_id: str) -> MessageSentResponse: + return self.__message_sender.send_text(to, body, integration_id) + + def send_file(self, to: str, body: str, filename: str, integration_id: str, caption: str = None) -> MessageSentResponse: + return self.__message_sender.send_file(to, body, filename, integration_id, caption) + + def send_list_menu(self, menu: MenuMessageRequest, integration_id: str) -> MessageSentResponse: + return self.__message_sender.send_list_menu(menu, integration_id) + + def send_buttons(self, buttons: ButtonsMessageRequest, integration_id: str) -> MessageSentResponse: + return self.__message_sender.send_buttons(buttons, integration_id) + + def send_template(self, template: TemplateMessageRequest, integration_id: str) -> MessageSentResponse: + return self.__message_sender.send_template(template, integration_id) \ No newline at end of file diff --git a/moorse/service/auth_service.py b/moorse/service/auth_service.py new file mode 100644 index 0000000..5c19608 --- /dev/null +++ b/moorse/service/auth_service.py @@ -0,0 +1,48 @@ +from clients.auth_client import AuthClient +from dto.authorization.login_response import LoginResponse +from service.validators.email_validator import EmailValidator + +class AuthService: + + __email: str = None + __password: str = None + __token: str = None + + def __init__(self, email: str, password: str) -> None: + self.__email = email + self.__password = password + + def login(self) -> LoginResponse: + + if(self.__email == None or self.__password == None): + raise Exception("Email and password must be set before log in!") + + response: LoginResponse = AuthClient().login( + self.__email, + self.__password + ) + + self.__token = response.data + + return response + + def set_email(self, email: str) -> None: + if(not EmailValidator().is_valid(email)): raise Exception("You are trying to set an invalid email!") + self.__email = email + + def get_email(self) -> str: + return self.__email + + def set_password(self, password: str) -> None: + self.__password = password + + def get_password(self) -> str: + return self.__password + + def set_token(self, token: str) -> None: + self.__token = token + + def get_token(self) -> str: + if(self.__token == None): + raise Exception("Seems that you token is not set!\nTry to log in first or set the token manually!") + return self.__token diff --git a/moorse/service/billing_service.py b/moorse/service/billing_service.py new file mode 100644 index 0000000..4d200e9 --- /dev/null +++ b/moorse/service/billing_service.py @@ -0,0 +1,13 @@ +from service.auth_service import AuthService +from dto.billing.billing_dto import BillingDto +from clients.billing_client import BillingClient + +class BillingService: + + __auth: AuthService + + def __init__(self, auth: AuthService): + self.__auth = auth + + def get_credits(self, integration_id: str) -> BillingDto: + return BillingClient().get_credits(self.__auth.get_token(), integration_id) \ No newline at end of file diff --git a/moorse/service/integration_service.py b/moorse/service/integration_service.py new file mode 100644 index 0000000..b220d57 --- /dev/null +++ b/moorse/service/integration_service.py @@ -0,0 +1,21 @@ +from service.auth_service import AuthService +from clients.integration_client import IntegrationClient + +class IntegrationService: + + __auth: AuthService + + def __init__(self, auth: AuthService): + self.__auth = auth + + def delete(self, integration_id: str): + return IntegrationClient().delete(self.__auth.get_token(), integration_id) + + def get_one(self, integration_id: str): + return IntegrationClient().get_one(self.__auth.get_token(), integration_id) + + def get_all(self): + return IntegrationClient().get_all(self.__auth.get_token()) + + def get_status(self, integration_id: str): + return IntegrationClient().get_status(self.__auth.get_token(), integration_id) \ No newline at end of file diff --git a/moorse/service/message/instagram_service.py b/moorse/service/message/instagram_service.py new file mode 100644 index 0000000..d5bf4bd --- /dev/null +++ b/moorse/service/message/instagram_service.py @@ -0,0 +1,28 @@ +from service.auth_service import AuthService +from clients.message.instagram_client import InstagramClient +from dto.message.message_sent_response import MessageSentResponse +from dto.message.menu.menu_message_request import MenuMessageRequest +from dto.message.buttons.buttons_message_request import ButtonsMessageRequest +from dto.message.template.template_message_request import TemplateMessageRequest + +class InstagramService: + + __auth: AuthService + + def __init__(self, auth: AuthService): + self.__auth = auth + + def send_text(self, to: str, body: str, integration_id: str) -> MessageSentResponse: + return InstagramClient().send_text(self.__auth.get_token(), integration_id, to, body) + + def send_file(self, to: str, body: str, filename: str, integration_id: str, caption: str = None) -> MessageSentResponse: + raise NotImplementedError("Instagram does not support file messages") + + def send_list_menu(self, menu: MenuMessageRequest, integration_id: str) -> MessageSentResponse: + return NotImplementedError("Instagram does not support list menu messages") + + def send_buttons(self, buttons: ButtonsMessageRequest, integration_id: str) -> MessageSentResponse: + return NotImplementedError("Instagram does not support buttons messages") + + def send_template(self, template: TemplateMessageRequest, integration_id: str) -> MessageSentResponse: + return NotImplementedError("Instagram does not support template messages") \ No newline at end of file diff --git a/moorse/service/message/sms_service.py b/moorse/service/message/sms_service.py new file mode 100644 index 0000000..e1c978f --- /dev/null +++ b/moorse/service/message/sms_service.py @@ -0,0 +1,28 @@ +from service.auth_service import AuthService +from clients.message.sms_client import SmsClient +from dto.message.message_sent_response import MessageSentResponse +from dto.message.menu.menu_message_request import MenuMessageRequest +from dto.message.buttons.buttons_message_request import ButtonsMessageRequest +from dto.message.template.template_message_request import TemplateMessageRequest + +class SmsService: + + __auth: AuthService + + def __init__(self, auth: AuthService): + self.__auth = auth + + def send_text(self, to: str, body: str, integration_id: str) -> MessageSentResponse: + return SmsClient().send_text(self.__auth.get_token(), integration_id, to, body) + + def send_file(self, to: str, body: str, filename: str, integration_id: str, caption: str = None) -> MessageSentResponse: + raise NotImplementedError("SMS does not support file messages") + + def send_list_menu(self, menu: MenuMessageRequest, integration_id: str) -> MessageSentResponse: + return NotImplementedError("SMS does not support list menu messages") + + def send_buttons(self, buttons: ButtonsMessageRequest, integration_id: str) -> MessageSentResponse: + return NotImplementedError("SMS does not support buttons messages") + + def send_template(self, template: TemplateMessageRequest, integration_id: str) -> MessageSentResponse: + return NotImplementedError("SMS does not support template messages") \ No newline at end of file diff --git a/moorse/service/message/whatsapp_service.py b/moorse/service/message/whatsapp_service.py new file mode 100644 index 0000000..6b1b6d7 --- /dev/null +++ b/moorse/service/message/whatsapp_service.py @@ -0,0 +1,28 @@ +from service.auth_service import AuthService +from clients.message.whatsapp_client import WhatsappClient +from dto.message.message_sent_response import MessageSentResponse +from dto.message.menu.menu_message_request import MenuMessageRequest +from dto.message.buttons.buttons_message_request import ButtonsMessageRequest +from dto.message.template.template_message_request import TemplateMessageRequest + +class WhatsappService: + + __auth: AuthService + + def __init__(self, auth: AuthService): + self.__auth = auth + + def send_text(self, to: str, body: str, integration_id: str) -> MessageSentResponse: + return WhatsappClient().send_text(self.__auth.get_token(), to, body, integration_id) + + def send_file(self, to: str, body: str, filename: str, integration_id: str, caption: str = None) -> MessageSentResponse: + return WhatsappClient().send_file(self.__auth.get_token(), to, body, filename, integration_id, caption) + + def send_list_menu(self, menu: MenuMessageRequest, integration_id: str) -> MessageSentResponse: + return WhatsappClient().send_list_menu(self.__auth.get_token(), menu, integration_id) + + def send_buttons(self, buttons: ButtonsMessageRequest, integration_id: str) -> MessageSentResponse: + return WhatsappClient().send_buttons(self.__auth.get_token(), buttons, integration_id) + + def send_template(self, template: TemplateMessageRequest, integration_id: str) -> MessageSentResponse: + return WhatsappClient().send_template(self.__auth.get_token(), template, integration_id) \ No newline at end of file diff --git a/moorse/service/report_service.py b/moorse/service/report_service.py new file mode 100644 index 0000000..facb456 --- /dev/null +++ b/moorse/service/report_service.py @@ -0,0 +1,27 @@ +from dto.reports.standard.messages_report_dto import MessagesReportDto +from dto.reports.channel.messages_by_channel_report_dto import MessagesByChannelReportDto +from dto.reports.timeline.messages_by_timeline_report_dto import MessagesByTimelineReportDto +from clients.report_client import ReportClient +from service.auth_service import AuthService + +class ReportService: + + __auth: AuthService + + def __init__(self, auth): + self.__auth = auth + + def get_messages(self, integration_id: str, begin: str, end: str) -> MessagesReportDto: + return ReportClient().get_messages( + self.__auth.get_token(), begin, end + ) + + def get_messages_by_channel(self, integration_id: str, begin: str, end: str) -> MessagesByChannelReportDto: + return ReportClient().get_messages_by_channel( + self.__auth.get_token(), begin, end + ) + + def get_messages_by_timeline(self, integration_id: str, begin: str, end: str) -> MessagesByTimelineReportDto: + return ReportClient().get_messages_by_timeline( + self.__auth.get_token(), begin, end + ) \ No newline at end of file diff --git a/moorse/service/template_service.py b/moorse/service/template_service.py new file mode 100644 index 0000000..7ab74ac --- /dev/null +++ b/moorse/service/template_service.py @@ -0,0 +1,24 @@ +from service.auth_service import AuthService +from clients.template_client import TemplateClient +from dto.template.request.template_request import TemplateRequest +from dto.template.template_dto import TemplateDto +from dto.template.response.multiple.template_list import TemplateList + +class TemplateService: + + __auth: AuthService + + def __init__(self, auth: AuthService): + self.__auth = auth + + def create(self, webhook: TemplateRequest) -> TemplateDto: + return TemplateClient().create(self.__auth.get_token(), webhook) + + def get_all(self) -> TemplateList: + return TemplateClient().get_all(self.__auth.get_token()) + + def get_one(self, webhook_id: str) -> TemplateDto: + return TemplateClient().get_one(self.__auth.get_token(), webhook_id) + + def delete(self, webhook_id: str) -> TemplateDto: + return TemplateClient().delete(self.__auth.get_token(), webhook_id) \ No newline at end of file diff --git a/moorse/service/validators/email_validator.py b/moorse/service/validators/email_validator.py new file mode 100644 index 0000000..6aeac2c --- /dev/null +++ b/moorse/service/validators/email_validator.py @@ -0,0 +1,11 @@ +class EmailValidator: + + def is_valid(self, email) -> bool: + cnt = 0 + idx = -1 + for i in range(len(email)): + if(email[i] != '@'): continue + idx = i + cnt += 1 + if(cnt != 1 or idx == 0 or idx == len(email) - 1): return False + return True \ No newline at end of file diff --git a/moorse/service/webhook_service.py b/moorse/service/webhook_service.py new file mode 100644 index 0000000..80f33ec --- /dev/null +++ b/moorse/service/webhook_service.py @@ -0,0 +1,25 @@ +from service.auth_service import AuthService +from clients.webhook_client import WebhookClient +from dto.webhook.webhook_request import WebhookRequest + +class WebhookService: + + __auth: AuthService + + def __init__(self, auth: AuthService): + self.__auth = auth + + def create(self, webhook: WebhookRequest): + return WebhookClient().create(self.__auth.get_token(), webhook) + + def get_all(self): + return WebhookClient().getAll(self.__auth.get_token()) + + def get_one(self, webhook_id: str): + return WebhookClient().getOne(self.__auth.get_token(), webhook_id) + + def update(self, webhook_id: str, webhook: WebhookRequest): + return WebhookClient().update(self.__auth.get_token(), webhook_id, webhook) + + def delete(self, webhook_id: str): + return WebhookClient().delete(self.__auth.get_token(), webhook_id) \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9d5f797 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,3 @@ +# Inside of setup.cfg +[metadata] +description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..5e93835 --- /dev/null +++ b/setup.py @@ -0,0 +1,26 @@ +from distutils.core import setup +setup( + name = 'moorse', # How you named your package folder (MyLib) + packages = ['moorse'], # Chose the same as "name" + version = '0.0.1', # Start with a small number and increase it with every change you make + license = 'MIT', # Chose a license from here: https://help.github.com/articles/licensing-a-repository + description = 'A sdk that allows Moorse customers to write some simplified calls to the Moorse resources.', # Give a short description about your library + author = 'Moorse.io', # Type in your name + author_email = 'douglas.alv.sousa@gmail.com', # Type in your E-Mail + url = 'https://moorse.io', # Provide either the link to your github or to your website + download_url = 'https://github.com/user/reponame/archive/v_01.tar.gz', # I explain this later on + keywords = ['DEVELOPMENT KIT', 'MOORSE', 'SDK'], # Keywords that define your package best + install_requires = [], + classifiers=[ + 'Development Status :: 3 - Alpha', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package + 'Intended Audience :: Developers', # Define that your audience are developers + 'Topic :: Software Development :: Build Tools', + 'License :: OSI Approved :: MIT License', # Again, pick a license + 'Programming Language :: Python :: 3', #Specify which pyhton versions that you want to support + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10' + ], +) \ No newline at end of file