django-unicom 25.3.45.dev1__tar.gz → 25.3.45.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/PKG-INFO +3 -3
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/README.md +2 -2
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/PKG-INFO +3 -3
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/_version.py +2 -2
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/send_email_message.py +17 -2
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/template_renderer.py +59 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/.cursor/rules/match_codebase_style.mdc +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/.cursor/rules/preserve_comments_and_irrelevant_code.mdc +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/.cursor/rules/require_context_before_changes.mdc +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/Dockerfile +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/MANIFEST.in +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/Makefile +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/conftest.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/data/definitions/bots/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/data/definitions/tools/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/SOURCES.txt +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/dependency_links.txt +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/requires.txt +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/top_level.txt +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/docker-compose.yaml +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/entrypoint.sh +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/internal-channel-modernization.md +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/manage.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/pyproject.toml +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/pytest.ini +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/requirements.txt +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/scripts/reacher_validate.sh +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/setup.cfg +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/setup.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_cross_platform_buttons.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_email_authentication.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_email_live.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_email_request_processing.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_telegram_live.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_webchat.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_webchat_branching.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/utils.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/todo.md +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/apps.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/migrations/0001_initial.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/migrations/0002_tool_bot_tools.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/migrations/0003_encryptedcredential.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/migrations/0004_credentialfielddefinition_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/migrations/0005_alter_credentialfielddefinition_key.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/migrations/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/models.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/services/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/services/credentials.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/services/llm_handler.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/services/tool_exceptions.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/services/tool_result_handler.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/templatetags/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/templatetags/unibot_extras.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/tests.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/urls.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/views.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/account_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/channel_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/chat_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/draft_message_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/email_inline_image_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/filters.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/member_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/message_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/message_template_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/request_admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/apps.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/consumers/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/consumers/webchat_consumer.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/management/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/management/commands/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/management/commands/mail_inbox_listen.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/management/commands/run_as_llm_chat.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/management/commands/send_scheduled_messages.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/management/commands/start_imap_listeners.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0001_initial.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0002_emailinlineimage.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0003_alter_emailinlineimage_email_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0004_messagetemplateinlineimage.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0005_emailinlineimage_hash_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0006_channel_created_at_channel_created_by_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0007_message_imap_uid.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0008_add_all_members_group.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0009_add_tool_call_types.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0010_request_initial_request_request_llm_calls_count_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0011_toolcall_add_message_reference.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0012_message_response_to_tool_call_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0013_callbackexecution.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0014_rename_authorized_user_to_intended_account.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0015_simplify_callback_execution.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0016_callbackexecution_tool_call.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0017_add_chat_metadata.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0018_message_bounce_details_message_bounce_reason_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0019_draftmessage_skip_reacher_validation.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0020_message_provider_message_id.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0021_message_open_count.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0022_toolcall_result_status.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0023_toolcall_progress_updates_for_user.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/account.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/account_chat.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/callback_execution.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/channel.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/chat.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/constants.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/draft_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/fields.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/member.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/member_group.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/message_template.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/request.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/request_category.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/tool_call.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/update.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/chat_summary.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/crossplatform/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/crossplatform/reply_to_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/crossplatform/scheduler.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/crossplatform/send_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/decode_base64_image.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/IMAP_thread_manager.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/email_tracking.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/listen_to_IMAP.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/quote_filter.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/replace_cid_images_with_base64.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/save_email_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/validate_email_config.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/get_public_origin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/html_inline_images.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/internal/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/internal/generate_text_message_data.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/internal/save_internal_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/internal/send_internal_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/llm/README.md +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/llm/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/llm/tool_calls.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/answer_callback_query.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/create_inline_keyboard.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/download_file.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/edit_telegram_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/escape_markdown.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/get_file_path.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/handle_telegram_callback.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/save_telegram_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/send_telegram_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/set_telegram_webhook.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/start_typing_in_telegram.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/stop_typing_in_telegram.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/webchat/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/webchat/generate_chat_title.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/webchat/get_or_create_account.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/webchat/migrate_guest_to_user.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/webchat/save_webchat_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/webchat/send_webchat_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/whatsapp/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/whatsapp/get_template.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/whatsapp/save_whatsapp_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/whatsapp/save_whatsapp_message_status.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/whatsapp/send_whatsapp_message.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/signals.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/css/bootstrap_scoped.css +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/css/draft_message_mobile.css +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/js/channel_config.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/js/tinymce_ai_template.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/js/tinymce_init.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/components/chat-list.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/components/media-preview.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/components/message-input.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/components/message-item.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/components/message-list.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/components/voice-recorder.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/utils/api-client.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/utils/datetime-formatter.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/utils/font-awesome-loader.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/utils/realtime-client.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/webchat-component.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/webchat-styles.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/static/unicom/webchat/webchat-with-sidebar.js +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/chat/change_list.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/chat/compose.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/chat_history.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/forms/email_message_form.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/forms/text_message_form.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/includes/ai_template_modal.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/includes/loading_indicators.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/includes/message_actions_menu.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/admin/unicom/messagetemplate/change_form.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/code_templates/category_processor.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templates/unicom/webchat_demo.html +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templatetags/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/templatetags/unicom_tags.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/tests/test_email_tracking_unsubscribe.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/tests/test_template_renderer_context.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/tests/test_template_renderer_unicom.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/urls.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/chat_history_view.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/compose_view.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/email_tracking.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/inline_image.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/message_template.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/telegram_webhook.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/webchat_demo_view.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/webchat_views.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/views/whatsapp_webhook.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/apps.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/asgi.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/callback_handlers.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/bots/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/bots/assistant_bot.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/tools/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/tools/cross_platform_buttons.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/tools/get_system_info.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/tools/interactive_menu.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/tools/interval_alarm.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/tools/ip_lookup.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/definitions/tools/simple_timer.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/settings.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/test_button_handlers.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/urls.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom_project/wsgi.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/admin.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/apps.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/forms.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/management/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/management/commands/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/management/commands/refresh_contact_cache.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/management/commands/send_scheduled_communications.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/management/commands/sync_getprospect_saved_contacts.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0001_initial.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0002_alter_communicationmessage_unique_together_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0003_remove_template_add_content.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0004_alter_contact_email.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0005_contact_user_alter_communication_status_summary.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0006_contact_email_bounce_type_contact_email_bounced_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0007_auto_enroll_and_status.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0008_rename_unicrm_msg_status_sched_idx_unicrm_comm_status_2f3c8e_idx_and_more.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0009_remove_unused_draft_field.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0010_communication_evergreen_refreshed_at.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0011_add_unique_constraints_to_company.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0012_company_attributes_company_industry.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0013_contact_insight_id.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0014_contact_gp_fields.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0015_contact_history_unsubscribe_all.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0016_add_unsubscribe_template_variable.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0017_unsubscribe_link_html_variable.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0018_communication_mailing_list.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0019_communication_follow_up_for_segment_for_followup.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0020_communication_skip_antispam_guards.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/0021_fix_unsubscribe_counts.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/migrations/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/models.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/seed_data.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/audience.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/audience_preview.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/communication_dispatcher.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/communication_enrollment.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/communication_runner.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/communication_scheduler.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/contact_interaction_cache.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/disk_usage_monitor.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/disk_usage_monitor_runner.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/getprospect_email_poller.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/lead_search.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/red_alerts.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/save_new_leads_callbacks.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/template_renderer.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/unsubscribe_links.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/services/user_contact_sync.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/signals.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/templatetags/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/templatetags/unicrm_extras.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/__init__.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_communication_compose_view.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_communication_dispatcher.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_communication_scheduler.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_contact_interactions.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_disk_usage_monitor.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_disk_usage_monitor_runner.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_red_alerts.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_retry_delivery_api.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_template_renderer.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_unsubscribe_view.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/tests/test_user_contact_sync.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/urls.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/views.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/views_api.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/views_communication.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/views_lead_search.py +0 -0
- {django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicrm/views_public.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-unicom
|
|
3
|
-
Version: 25.3.45.
|
|
3
|
+
Version: 25.3.45.dev3
|
|
4
4
|
Summary: Unified communication layer for Django (Telegram, WhatsApp, Email)
|
|
5
5
|
Home-page: https://github.com/meena-erian/unicom
|
|
6
6
|
Author: Meena (Menas) Erian
|
|
@@ -630,12 +630,12 @@ channel.send_message({
|
|
|
630
630
|
'to': ['a@example.com'],
|
|
631
631
|
'subject': 'Hello',
|
|
632
632
|
'html': '<p>Hello {{ variables.name }}</p>',
|
|
633
|
-
'render_template': True, # enable rendering
|
|
633
|
+
'render_template': True, # enable rendering (admin email compose & scheduled drafts set this for you)
|
|
634
634
|
'render_variables': {'name': 'Alice'}, # merged into variables.*
|
|
635
635
|
# Optionally pass a custom render_context if you want to add more fields
|
|
636
636
|
})
|
|
637
637
|
```
|
|
638
|
-
If you omit `render_template`/context/variables, the HTML is sent as-is.
|
|
638
|
+
If you omit `render_template`/context/variables, the HTML is sent as-is. The Django admin email composer and scheduled drafts already enable rendering by default; you only need to pass the flag when sending programmatically.
|
|
639
639
|
|
|
640
640
|
### Draft Messages & Scheduling
|
|
641
641
|
|
|
@@ -586,12 +586,12 @@ channel.send_message({
|
|
|
586
586
|
'to': ['a@example.com'],
|
|
587
587
|
'subject': 'Hello',
|
|
588
588
|
'html': '<p>Hello {{ variables.name }}</p>',
|
|
589
|
-
'render_template': True, # enable rendering
|
|
589
|
+
'render_template': True, # enable rendering (admin email compose & scheduled drafts set this for you)
|
|
590
590
|
'render_variables': {'name': 'Alice'}, # merged into variables.*
|
|
591
591
|
# Optionally pass a custom render_context if you want to add more fields
|
|
592
592
|
})
|
|
593
593
|
```
|
|
594
|
-
If you omit `render_template`/context/variables, the HTML is sent as-is.
|
|
594
|
+
If you omit `render_template`/context/variables, the HTML is sent as-is. The Django admin email composer and scheduled drafts already enable rendering by default; you only need to pass the flag when sending programmatically.
|
|
595
595
|
|
|
596
596
|
### Draft Messages & Scheduling
|
|
597
597
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-unicom
|
|
3
|
-
Version: 25.3.45.
|
|
3
|
+
Version: 25.3.45.dev3
|
|
4
4
|
Summary: Unified communication layer for Django (Telegram, WhatsApp, Email)
|
|
5
5
|
Home-page: https://github.com/meena-erian/unicom
|
|
6
6
|
Author: Meena (Menas) Erian
|
|
@@ -630,12 +630,12 @@ channel.send_message({
|
|
|
630
630
|
'to': ['a@example.com'],
|
|
631
631
|
'subject': 'Hello',
|
|
632
632
|
'html': '<p>Hello {{ variables.name }}</p>',
|
|
633
|
-
'render_template': True, # enable rendering
|
|
633
|
+
'render_template': True, # enable rendering (admin email compose & scheduled drafts set this for you)
|
|
634
634
|
'render_variables': {'name': 'Alice'}, # merged into variables.*
|
|
635
635
|
# Optionally pass a custom render_context if you want to add more fields
|
|
636
636
|
})
|
|
637
637
|
```
|
|
638
|
-
If you omit `render_template`/context/variables, the HTML is sent as-is.
|
|
638
|
+
If you omit `render_template`/context/variables, the HTML is sent as-is. The Django admin email composer and scheduled drafts already enable rendering by default; you only need to pass the flag when sending programmatically.
|
|
639
639
|
|
|
640
640
|
### Draft Messages & Scheduling
|
|
641
641
|
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '25.3.45.
|
|
32
|
-
__version_tuple__ = version_tuple = (25, 3, 45, '
|
|
31
|
+
__version__ = version = '25.3.45.dev3'
|
|
32
|
+
__version_tuple__ = version_tuple = (25, 3, 45, 'dev3')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -20,6 +20,8 @@ from unicom.services.html_inline_images import html_shortlinks_to_base64_images,
|
|
|
20
20
|
from unicom.services.template_renderer import (
|
|
21
21
|
render_template as render_unicom_template,
|
|
22
22
|
build_unicom_message_context,
|
|
23
|
+
extract_variable_keys,
|
|
24
|
+
compute_crm_variables,
|
|
23
25
|
)
|
|
24
26
|
|
|
25
27
|
logger = logging.getLogger(__name__)
|
|
@@ -281,9 +283,19 @@ def send_email_message(channel: Channel, params: dict, user: User=None):
|
|
|
281
283
|
|
|
282
284
|
# Optionally render templates for non-CRM use-cases when explicitly requested.
|
|
283
285
|
render_context = params.get('render_context')
|
|
284
|
-
render_variables = params.get('render_variables')
|
|
286
|
+
render_variables = params.get('render_variables') or {}
|
|
285
287
|
render_requested = params.get('render_template') or render_context or render_variables
|
|
286
288
|
if render_requested and html_content:
|
|
289
|
+
crm_variables: dict[str, object] = {}
|
|
290
|
+
requested_keys = extract_variable_keys(html_content)
|
|
291
|
+
if requested_keys:
|
|
292
|
+
# Use first To address (if any) to resolve contact for CRM variables.
|
|
293
|
+
primary_email = None
|
|
294
|
+
to_addrs_for_crm = params.get('to') or to_addrs
|
|
295
|
+
if to_addrs_for_crm:
|
|
296
|
+
primary_email = (to_addrs_for_crm[0] or '').strip()
|
|
297
|
+
crm_variables = compute_crm_variables(requested_keys, primary_email)
|
|
298
|
+
|
|
287
299
|
base_context = render_context or build_unicom_message_context(
|
|
288
300
|
params=params,
|
|
289
301
|
channel={
|
|
@@ -297,10 +309,13 @@ def send_email_message(channel: Channel, params: dict, user: User=None):
|
|
|
297
309
|
'email': getattr(user, 'email', None),
|
|
298
310
|
} if user else {},
|
|
299
311
|
)
|
|
312
|
+
merged_variables = {}
|
|
313
|
+
merged_variables.update(crm_variables)
|
|
314
|
+
merged_variables.update(render_variables)
|
|
300
315
|
render_result = render_unicom_template(
|
|
301
316
|
html_content,
|
|
302
317
|
base_context=base_context,
|
|
303
|
-
variables=
|
|
318
|
+
variables=merged_variables,
|
|
304
319
|
)
|
|
305
320
|
if render_result.errors:
|
|
306
321
|
logger.warning("Template rendering errors: %s", "; ".join(render_result.errors))
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/template_renderer.py
RENAMED
|
@@ -7,6 +7,7 @@ import re
|
|
|
7
7
|
from urllib.parse import unquote
|
|
8
8
|
|
|
9
9
|
from django.utils import timezone
|
|
10
|
+
from django.db import IntegrityError
|
|
10
11
|
from jinja2 import StrictUndefined, TemplateError
|
|
11
12
|
from jinja2.sandbox import SandboxedEnvironment
|
|
12
13
|
|
|
@@ -138,3 +139,61 @@ def build_unicom_message_context(
|
|
|
138
139
|
if extra:
|
|
139
140
|
ctx.update(extra)
|
|
140
141
|
return ctx
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
_VARIABLE_PLACEHOLDER_RE = re.compile(r"\{\{\s*variables\.([^\s\}]+)\s*\}\}")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def extract_variable_keys(template_html: str | None) -> set[str]:
|
|
148
|
+
"""
|
|
149
|
+
Return the set of variable keys referenced as {{ variables.* }} in the template.
|
|
150
|
+
"""
|
|
151
|
+
if not template_html:
|
|
152
|
+
return set()
|
|
153
|
+
unprotected = unprotect_tinymce_markup(template_html)
|
|
154
|
+
return {m.group(1) for m in _VARIABLE_PLACEHOLDER_RE.finditer(unprotected)}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _load_crm_models():
|
|
158
|
+
"""
|
|
159
|
+
Dynamically load CRM models if unicrm is installed; otherwise return (None, None).
|
|
160
|
+
"""
|
|
161
|
+
try:
|
|
162
|
+
from django.apps import apps
|
|
163
|
+
Contact = apps.get_model('unicrm', 'Contact')
|
|
164
|
+
TemplateVariable = apps.get_model('unicrm', 'TemplateVariable')
|
|
165
|
+
if Contact is None or TemplateVariable is None:
|
|
166
|
+
return None, None
|
|
167
|
+
return Contact, TemplateVariable
|
|
168
|
+
except Exception:
|
|
169
|
+
return None, None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def compute_crm_variables(keys: set[str], contact_email: str | None) -> Dict[str, Any]:
|
|
173
|
+
"""
|
|
174
|
+
Best-effort evaluation of CRM TemplateVariables for a contact resolved by email.
|
|
175
|
+
Safe to call when unicrm is not installed (returns {}).
|
|
176
|
+
"""
|
|
177
|
+
if not keys or not contact_email:
|
|
178
|
+
return {}
|
|
179
|
+
Contact, TemplateVariable = _load_crm_models()
|
|
180
|
+
if Contact is None or TemplateVariable is None:
|
|
181
|
+
return {}
|
|
182
|
+
contact = Contact.objects.filter(email__iexact=contact_email).first()
|
|
183
|
+
if not contact:
|
|
184
|
+
try:
|
|
185
|
+
contact, _ = Contact.objects.get_or_create(
|
|
186
|
+
email=contact_email,
|
|
187
|
+
defaults={'email': contact_email},
|
|
188
|
+
)
|
|
189
|
+
except IntegrityError:
|
|
190
|
+
contact = Contact.objects.filter(email__iexact=contact_email).first()
|
|
191
|
+
if not contact:
|
|
192
|
+
return {}
|
|
193
|
+
results: Dict[str, Any] = {}
|
|
194
|
+
for variable in TemplateVariable.objects.filter(is_active=True, key__in=keys):
|
|
195
|
+
try:
|
|
196
|
+
results[variable.key] = variable.get_callable()(contact)
|
|
197
|
+
except Exception as exc: # pragma: no cover - defensive
|
|
198
|
+
results[variable.key] = f"<error: {exc}>"
|
|
199
|
+
return results
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/.cursor/rules/match_codebase_style.mdc
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/data/definitions/tools/__init__.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/requires.txt
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/django_unicom.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_cross_platform_buttons.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_email_authentication.py
RENAMED
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/tests/test_email_request_processing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/migrations/0002_tool_bot_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/services/tool_exceptions.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/services/tool_result_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unibot/templatetags/unibot_extras.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/draft_message_admin.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/email_inline_image_admin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/admin/message_template_admin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/consumers/webchat_consumer.py
RENAMED
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/management/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0002_emailinlineimage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/migrations/0007_message_imap_uid.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/models/callback_execution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/crossplatform/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/crossplatform/scheduler.py
RENAMED
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/decode_base64_image.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/email_tracking.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/listen_to_IMAP.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/email/quote_filter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/get_public_origin.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/html_inline_images.py
RENAMED
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/internal/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/download_file.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/telegram/get_file_path.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_unicom-25.3.45.dev1 → django_unicom-25.3.45.dev3}/unicom/services/webchat/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|