commit ffcf283b6fd44962be93e993c3f65c4da7a7c00b Author: mvivlad Date: Wed Feb 19 16:15:22 2025 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba0430d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f674238 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Odoo base_telegram +Odoo Telegram API +Menu: Settings / Technical / Parameters / Telegram API Connections + +## Add new connection +- Open the chat with [@BotFather](https://t.me/BotFather) +- Enter the command **/newbot** to create a bot +- Save received **token** (like: 1234567890:ABcdeFghKLMNopqrs_TUvWxyz) +- Create a group where the created bot should post messages +- Add the bot to the group +- Grant the bot admin access in the group +- Send a test message in the group, ensure that the bot can read it +- Save **Chat ID** from test message + +![Telegram API new connection form](chat_bot_config_form.png "Telegram API new connection form") + +## Send message to Telegram +``env["base.telegram"].browse(1).send_message('Test')`` + +## Send message from project.task by template +`` +self = env["base.telegram"].browse(1) +obj = env['project.task'].browse(4) +self.with_context(lang=env.user.lang if env.user.lang else 'ru_RU', tz=env.user.tz if env.user.tz else 'Europe/Moscow').send_template('base_telegram.message_new_task', obj) +`` diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..9b42961 --- /dev/null +++ b/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/__manifest__.py b/__manifest__.py new file mode 100644 index 0000000..ec9d51a --- /dev/null +++ b/__manifest__.py @@ -0,0 +1,28 @@ +# Copyright 2025 Boant +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + 'name': 'Telegram API', + "version": "17.0.0.0.0", + 'category': 'Technical', + "author": "Boant", + "license": "LGPL-3", + "development_status": "Production/Stable", + "maintainers": ["mvivlad"], + "website": "https://boant.ru", + 'depends': [ + 'base', + 'mail', + 'base_automation', + ], + 'data': [ + 'security/ir.model.access.csv', + 'data/ir_ui_view_templates.xml', + 'wizard/create_notify_new_object.xml', + 'views/base_telegram_view.xml', + 'views/base_telegram_templates.xml', + 'views/base_telegram_menu_views.xml', + ], + 'installable': True, + 'application': False, +} diff --git a/data/ir_ui_view_templates.xml b/data/ir_ui_view_templates.xml new file mode 100644 index 0000000..e3b96c4 --- /dev/null +++ b/data/ir_ui_view_templates.xml @@ -0,0 +1,16 @@ + + + + Message template for New Project Task + qweb + + base_telegram.message_new_task + Subject: +Task # +Created: +Partner: +Mobile: +Email: + + + diff --git a/i18n/ru.po b/i18n/ru.po new file mode 100644 index 0000000..6d482c1 --- /dev/null +++ b/i18n/ru.po @@ -0,0 +1,389 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_telegram +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-02-19 07:54+0000\n" +"PO-Revision-Date: 2025-02-19 07:54+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.create_from_chat_id_wizard_view +msgid "" +"No record for this model" +msgstr "" +"Нет записей для этой Модели" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "@BotFather" +msgstr "@BotFather" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__action_server_id_domain +msgid "Action Server Id Domain" +msgstr "Домен Серверного действия" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__action_code +msgid "Action python code" +msgstr "Python код Действия" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__test_active +msgid "Activate Preview" +msgstr "Проверить текст извещения" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Add the bot to the group" +msgstr "Добавьте бота в группу" + +#. module: base_telegram +#: model:ir.actions.act_window,name:base_telegram.action_base_telegram_api_view +msgid "Base Telegram API" +msgstr "Telegram API" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__token +msgid "Bot Token" +msgstr "Token бота" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__chat_id +msgid "Bot and chat to send messages" +msgstr "Бот и чат для отправки сообщений" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__chat_id +#: model_terms:ir.ui.view,arch_db:base_telegram.get_updates +msgid "Chat ID" +msgstr "Chat ID" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Click the button Get Chat ID on this form" +msgstr "Нажмите кнопку Получить Chat ID на этой форме" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.create_from_chat_id_wizard_view +msgid "Close" +msgstr "Закрыть" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__code +msgid "Code Name" +msgstr "Код соединения" + +#. module: base_telegram +#: model:ir.ui.menu,name:base_telegram.menu_base_telegram_list +msgid "Connections List" +msgstr "Список соединений" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.get_updates +msgid "Content" +msgstr "Содержимое" + +#. module: base_telegram +#: model:ir.model,name:base_telegram.model_wizard_create_notify_new_object +msgid "Create Automation to send message to Telegram about new object" +msgstr "Создание Автоматизации для отправки сообщения в Telegram о новом объекте (Задача, Лид и пр.)" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Create Notification" +msgstr "Создать Уведомление" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Create a group where the created bot should post messages" +msgstr "Создайте группу, в которую должен писать созданный бот" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.create_from_chat_id_wizard_view +msgid "Create and Edit" +msgstr "Создать и Изменить" + +#. module: base_telegram +#: model:ir.actions.act_window,name:base_telegram.create_from_chat_id_wizard_action +#: model_terms:ir.ui.view,arch_db:base_telegram.create_from_chat_id_wizard_view +msgid "Create new object notification by Telegram bot" +msgstr "Создание Уведомлений о новых объектах ботом Telegram" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__create_uid +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__create_uid +msgid "Created by" +msgstr "Создал" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__create_date +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__create_date +msgid "Created on" +msgstr "Создан" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.message_new_task +msgid "Created:" +msgstr "Создан:" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Creating a Telegram Bot:" +msgstr "Создание бота Telegram:" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__display_name +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__display_name +msgid "Display Name" +msgstr "Отображаемое имя" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.message_new_task +msgid "Email:" +msgstr "Email:" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "" +"Enter the Chat ID value from the table of read messages into the " +"Chat ID field" +msgstr "" +"Внесите в поле Chat ID значение из таблицы прочитанных сообщений" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "" +"Enter the command /newbot to create a bot. Follow the instructions " +"provided by @BotFather" +msgstr "" +"Введите команду /newbot, чтобы создать бота. Следуйте инструкциям @BotFather" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.get_updates +msgid "Event" +msgstr "Событие" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Get Chat ID" +msgstr "Получить Chat ID" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Grant the bot admin access in the group" +msgstr "Предоставьте боту доступ администратора в группу" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__id +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__id +msgid "ID" +msgstr "ID" + +#. module: base_telegram +#: model:ir.model.fields,help:base_telegram.field_wizard_create_notify_new_object__template_xml_id +msgid "ID of the view defined in xml file" +msgstr "xml_id представления" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__write_uid +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__write_uid +msgid "Last Updated by" +msgstr "Обновил" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__write_date +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__write_date +msgid "Last Updated on" +msgstr "Обновлено" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__messages_html +msgid "Messages for Bot" +msgstr "Сообщения для бота" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.message_new_task +msgid "Mobile:" +msgstr "Мобильный:" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__res_model_id +msgid "Model" +msgstr "Модель" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_base_telegram_api__name +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__name +msgid "Name" +msgstr "Наименование" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__test_no_record +msgid "No Record" +msgstr "Нет записей" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "" +"Once completed, record the received token in the corresponding field.
\n" +"In the chat with @BotFather, look for the text:
\n" +"Use this token to access the HTTP API:
\n" +"1234567890:ABcdeFghKLMNopqrs_TUvWxyz\n" +"
" +msgstr "" +"По завершении запишите полученный token в одноименное поле.
\n" +"В чате @BotFather ищите текст:
\n" +"Use this token to access the HTTP API:
\n" +"1234567890:ABcdeFghKLMNopqrs_TUvWxyz\n" +"
" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Open the chat with" +msgstr "Откройте чат с" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.message_new_task +msgid "Partner:" +msgstr "Партнер:" + +#. module: base_telegram +#: model:ir.model.fields,help:base_telegram.field_wizard_create_notify_new_object__chat_id +msgid "Select Bot and chat to send messages" +msgstr "Выберите Бота и Чат для отправки сообщений" + +#. module: base_telegram +#: model:ir.model.fields,help:base_telegram.field_wizard_create_notify_new_object__res_model_id +msgid "Select Model where new object will be monitored" +msgstr "Выберите Модель для отслеживания новых объектов" + +#. module: base_telegram +#: model:ir.model.fields,help:base_telegram.field_wizard_create_notify_new_object__template_id +msgid "Select QWeb Template to compose message" +msgstr "Выберите QWeb шаблон для формирования сообщения" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Send Test Message" +msgstr "Отправить тестовое сообщение" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.view_base_telegram_api_form +msgid "Send a test message in the group, ensure that the bot can read it" +msgstr "Отправить тестовое сообщение в группу, убедитесь в наличии у бота прав читать сообщения" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__action_server_id +msgid "Server action to send message" +msgstr "Серверное действие для отправки сообщения" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.message_new_task +msgid "Subject:" +msgstr "Тема:" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.message_new_task +msgid "Task #" +msgstr "Задача #" + +#. module: base_telegram +#: model:ir.model,name:base_telegram.model_base_telegram_api +msgid "Telegram API" +msgstr "Telegram API" + +#. module: base_telegram +#: model:ir.ui.menu,name:base_telegram.menu_base_telegram +msgid "Telegram API Connections" +msgstr "Соединения Telegram API" + +#. module: base_telegram +#: model_terms:ir.actions.act_window,help:base_telegram.action_base_telegram_api_view +msgid "Telegram Chats List" +msgstr "Список чатов Telegram" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__template_id +msgid "Template" +msgstr "Шаблон" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__template_id_domain +msgid "Template Id Domain" +msgstr "Домен для поиска Шаблонов" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__test_lang +msgid "Template Preview Language" +msgstr "Язык предпросмотра" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__template_arch +msgid "Template arch" +msgstr "Код (arch) шаблона" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__template_xml_id +msgid "Template xml_id" +msgstr "xml_id шаблона" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__test_preview +msgid "Test Preview" +msgstr "Предпросмотр активирован" + +#. module: base_telegram +#: model:ir.model.fields,field_description:base_telegram.field_wizard_create_notify_new_object__test_record_ref +msgid "Test Record" +msgstr "Тестовая запись" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.create_from_chat_id_wizard_view +msgid "Test Record:" +msgstr "Тестовая запись:" + +#. module: base_telegram +#. odoo-python +#: code:addons/base_telegram/models/base_telegram.py:0 +#, python-format +msgid "Test from Odoo" +msgstr "Тест из Odoo" + +#. module: base_telegram +#: model:ir.model.fields,help:base_telegram.field_wizard_create_notify_new_object__template_arch +msgid "" +"This field should be used when accessing view arch. It will use translation.\n" +" Note that it will read `arch_db` or `arch_fs` if in dev-xml mode." +msgstr "" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.get_updates +msgid "Time" +msgstr "Время" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.get_updates +msgid "new chat member" +msgstr "новый участнник чата" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.get_updates +msgid "no messages" +msgstr "нет сообщений" + +#. module: base_telegram +#: model_terms:ir.ui.view,arch_db:base_telegram.create_from_chat_id_wizard_view +msgid "or" +msgstr "или" diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..5ac87d1 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1 @@ +from . import base_telegram diff --git a/models/base_telegram.py b/models/base_telegram.py new file mode 100644 index 0000000..97822c3 --- /dev/null +++ b/models/base_telegram.py @@ -0,0 +1,76 @@ +from odoo import api, fields, models, _ +import requests +import json +from odoo.tools import html2plaintext +import logging + +_logger = logging.getLogger(__name__) +class TelegramAPI(models.Model): + _name = "base_telegram.api" + _description = "Telegram API" + + code = fields.Char(string='Code Name', index=True) + name = fields.Char(string='Name') + chat_id = fields.Char(string='Chat ID') + token = fields.Char(string='Bot Token') + messages_html = fields.Html(string='Messages for Bot', compute='_compute_messages_html', store=False, readonly=True) + + @api.onchange('token') + def _compute_messages_html(self): + for rec in self: + result = rec.get_updates() if rec.token else [] + rec.messages_html = self.render_template('base_telegram.get_updates', {'result': result} if result else {}) + + def get_url(self, command): + return "https://api.telegram.org/bot{token}/{command}".format(token = self.token, command = command) + + def send_message(self, message): + cnt = 0 + for chat in self: + #url = "https://api.telegram.org/bot{token}/sendMessage".format(token = chat.token) + url = chat.get_url('sendMessage') + info = { + 'chat_id': chat.chat_id, + 'text': message, + 'parse_mode': 'HTML' + } + try: + response = requests.post(url, data=info) + #response.raise_for_status() + cnt += 1 + except requests.exceptions.RequestException as e: + _logger.info(f"Error: {e}") + return cnt + + def send_template(self, template, obj, data = dict()): + return self.send_message(str( + self.with_context( + lang=self.env.user.lang if self.env.user.lang else 'ru_RU', + tz=self.env.user.tz if self.env.user.tz else 'Europe/Moscow' + ).render_template(template, data) + )) + + def get_updates(self): + url = self.get_url('getUpdates') + try: + response = requests.post(url, data='') + except requests.exceptions.RequestException as e: + _logger.info(f"Error: {e}") + return json.loads(response.content).get('result',[]) if response and response.content else [] + + def render_template(self, template, obj = False, data = dict()): + if not data: + data = dict() + data['object'] = obj + data['html2plaintext'] = html2plaintext + return self.env['ir.qweb']._render(template, data, lang='ru_RU') + + def button_get_messages(self): + self.get_updates() + self._compute_messages_html() + return True + + def button_send_test(self): + self.send_message(_('Test from Odoo')) + return True + diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv new file mode 100644 index 0000000..cb9eaa5 --- /dev/null +++ b/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_base_telegram_api,access_base_telegram_api,model_base_telegram_api,,1,1,1,1 +access_wizard_create_notify_new_object,access_wizard_create_notify_new_object,model_wizard_create_notify_new_object,,1,1,1,1 diff --git a/static/description/chat_bot_config_form.png b/static/description/chat_bot_config_form.png new file mode 100644 index 0000000..1d2cdc3 Binary files /dev/null and b/static/description/chat_bot_config_form.png differ diff --git a/static/description/icon.png b/static/description/icon.png new file mode 100644 index 0000000..67c63f5 Binary files /dev/null and b/static/description/icon.png differ diff --git a/static/description/index.html b/static/description/index.html new file mode 100644 index 0000000..c1dc966 --- /dev/null +++ b/static/description/index.html @@ -0,0 +1,374 @@ + + + + +Telegram API + + + +
+

Telegram API

+

Odoo base_telegram

+

Odoo Telegram API +Menu: Settings / Technical / Parameters / Telegram API Connections

+

Add new connection

+
    +
  • Open the chat with @BotFather
  • +
  • Enter the command /newbot to create a bot
  • +
  • Save received token (like: 1234567890:ABcdeFghKLMNopqrs_TUvWxyz)
  • +
  • Create a group where the created bot should post messages
  • +
  • Add the bot to the group
  • +
  • Grant the bot admin access in the group
  • +
  • Send a test message in the group, ensure that the bot can read it
  • +
  • Save Chat ID from test message
  • +
+

Telegram API new connection form

+

Send message to Telegram

+

env["base.telegram"].browse(1).send_message('Test')

+

Send message from project.task by template

+

self = env["base.telegram"].browse(1) +obj = env['project.task'].browse(4) +self.with_context(lang=env.user.lang if env.user.lang else 'ru_RU', tz=env.user.tz if env.user.tz else 'Europe/Moscow').send_template('base_telegram.message_new_task', obj)

+
+ + diff --git a/views/base_telegram_menu_views.xml b/views/base_telegram_menu_views.xml new file mode 100644 index 0000000..eee8375 --- /dev/null +++ b/views/base_telegram_menu_views.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/views/base_telegram_templates.xml b/views/base_telegram_templates.xml new file mode 100644 index 0000000..021182b --- /dev/null +++ b/views/base_telegram_templates.xml @@ -0,0 +1,33 @@ + + + + diff --git a/views/base_telegram_view.xml b/views/base_telegram_view.xml new file mode 100644 index 0000000..b4b720a --- /dev/null +++ b/views/base_telegram_view.xml @@ -0,0 +1,74 @@ + + + + + Base Telegram API + ir.actions.act_window + base_telegram.api + tree,form,kanban + + {} + +

+ Telegram Chats List +

+
+
+ + + base_telegram.api.tree + base_telegram.api + + + + + + + + + + + + base_telegram.api.form + base_telegram.api + +
+
+
+ + + + + + + + + +
Creating a Telegram Bot: +
    +
  • Open the chat with @BotFather
  • +
  • Enter the command /newbot to create a bot. Follow the instructions provided by @BotFather
  • +
  • Once completed, record the received token in the corresponding field.
    +In the chat with @BotFather, look for the text:
    +Use this token to access the HTTP API:
    +1234567890:ABcdeFghKLMNopqrs_TUvWxyz +
  • +
  • Create a group where the created bot should post messages
  • +
  • Add the bot to the group
  • +
  • Grant the bot admin access in the group
  • +
  • Send a test message in the group, ensure that the bot can read it
  • +
  • Click the button Get Chat ID by test message on this form
  • +
  • Enter the Chat ID value from the table of read messages into the Chat ID field
  • +
+
+
+
+ +
+
+
+
+
diff --git a/wizard/__init__.py b/wizard/__init__.py new file mode 100644 index 0000000..34f6620 --- /dev/null +++ b/wizard/__init__.py @@ -0,0 +1 @@ +from . import create_notify_new_object diff --git a/wizard/create_notify_new_object.py b/wizard/create_notify_new_object.py new file mode 100644 index 0000000..351cdd4 --- /dev/null +++ b/wizard/create_notify_new_object.py @@ -0,0 +1,116 @@ +from odoo import fields, models, api +from odoo.exceptions import AccessError, MissingError, UserError, ValidationError + + +class WizardCreateNotifyNewObject(models.TransientModel): + _name = "wizard.create.notify.new.object" + _description = "Create Automation to send message to Telegram about new object" + + @api.model + def _selection_target_model(self): + return [(model.model, model.name) for model in self.env['ir.model'].sudo().search([])] + + @api.model + def _selection_languages(self): + return self.env['res.lang'].get_installed() + + name = fields.Char(required=True) + chat_id = fields.Many2one('base_telegram.api', string='Bot and chat to send messages', required=True, + help="Select Bot and chat to send messages") + res_model_id = fields.Many2one('ir.model', string='Model', required=True, + help="Select Model where new object will be monitored") + template_id_domain = fields.Char(compute="_compute_template_id_domain") + template_id = fields.Many2one('ir.ui.view', string='Template', domain="template_id_domain", + help="Select QWeb Template to compose message") + template_xml_id = fields.Char(string='Template xml_id', related='template_id.xml_id') + template_arch = fields.Text(string='Template arch', related='template_id.arch') + action_server_id_domain = fields.Char(compute="_compute_action_server_id") + action_server_id = fields.Many2one('ir.actions.server', string='Server action to send message', required=True, domain="action_server_id_domain") + action_code = fields.Text(string='Action python code', compute='_compute_action_code', compute_sudo=True, readonly=True) + test_active = fields.Boolean(string='Activate Preview') + test_record_ref = fields.Reference( + string='Test Record', + compute='_compute_test_record_ref', + compute_sudo=False, readonly=False, + selection='_selection_target_model', + store=True + ) + test_lang = fields.Selection(_selection_languages, string='Template Preview Language') + test_no_record = fields.Boolean('No Record', compute='_compute_no_record') + test_preview = fields.Text('Test Preview', compute='_compute_template_preview') + + @api.depends('res_model_id') + def _compute_template_id_domain(self): + for rec in self: + domain = [('model', '=', rec.res_model_id.model if rec.res_model_id else False), ('type', '=', 'qweb')] + rec.template_id_domain = domain + + @api.depends('res_model_id') + def _compute_action_server_id(self): + for rec in self: + domain = [('model_id', '=', rec.res_model_id.id if rec.res_model_id else False), ('state', '=', 'code')] + rec.action_server_id_domain = domain + + @api.depends('action_server_id') + def _compute_action_code(self): + for rec in self: + if rec.action_server_id: + rec.action_code = rec.action_server_id.code + else: + rec.action_code = False + + @api.depends('res_model_id') + def _compute_test_record_ref(self): + for rec in self: + if rec.res_model_id: + res = self.env[rec.res_model_id.model].search([], limit=1) + else: + res = False + rec.test_record_ref = f'{str(rec.res_model_id.model)},{res.id}' if res else False + + @api.depends('test_record_ref') + def _compute_no_record(self): + for rec in self: + rec.test_no_record = False if rec.test_record_ref else True + + @api.depends('test_record_ref','template_id') + def _compute_template_preview(self): + for rec in self: + if rec.chat_id and rec.test_record_ref and rec.test_record_ref.id and rec.template_id: + try: + rec.test_preview = rec.chat_id.with_context( + lang=rec.test_lang + ).render_template(rec.template_xml_id, rec.test_record_ref) + except UserError as e: + rec.test_preview = f"Error: {e}" + else: + rec.test_preview = False + + def create_by_chat_id(self): + self.ensure_one() + + chat_ids = self.env.context.get("active_ids", []) + assert len(chat_ids) == 1 + + chat_id = chat_ids[0] + + rule_obj = self.env["base.automation"] + automation = rule_obj.create( + { + "name": self.name, + "model_id": self.res_model_id.id, + "trigger": 'on_create_or_write', + "trigger_field_ids": self.env['ir.model.fields'].search([('model_id','=',self.res_model_id.id),('name','=','create_date')]), + "action_server_ids": self.action_server_id.ids, + } + ) + return { + "context": self.env.context, + "name": "Automation Rule", + "view_type": "form", + "view_mode": "form", + "res_model": "base.automation", + "res_id": automation.id, + "target": "current", + "type": "ir.actions.act_window", + } diff --git a/wizard/create_notify_new_object.xml b/wizard/create_notify_new_object.xml new file mode 100644 index 0000000..ae042c3 --- /dev/null +++ b/wizard/create_notify_new_object.xml @@ -0,0 +1,60 @@ + + + + Create new object notification by Telegram bot + wizard.create.notify.new.object + +
+
+ + + + + +
+ + + + + + + + + + + + + +
+
+
+
+
+ + + Create new object notification by Telegram bot + wizard.create.notify.new.object + form + new + + + {'default_chat_id':active_id} + +