function send_notification_v1
Sends in-app notifications to one or more users with optional email delivery, supporting both DocUser objects and user UID strings.
/tf/active/vicechatdev/CDocs single class/utils/notifications.py
940 - 1033
moderate
Purpose
This function provides a unified interface for sending notifications to users in a document management system. It creates in-app notifications in the database and optionally sends corresponding email notifications. It handles both single and multiple recipients, accepts either DocUser objects or user UID strings, retrieves user emails from the database when needed, and supports templated email content with dynamic data substitution.
Source Code
def send_notification(notification_type: str,
users: Union[List[Union[DocUser, str]], DocUser, str],
resource_uid: Optional[str] = None,
resource_type: Optional[str] = None,
message: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
send_email: bool = False,
email_template: Optional[str] = None,
email_data: Optional[Dict[str, Any]] = None) -> List[str]:
"""
Send a notification to one or more users, optionally with email.
Args:
notification_type: Type of notification from NOTIFICATION_TYPES
users: User(s) to notify (DocUser instance(s) or UID(s))
resource_uid: Optional UID of resource this notification is about
resource_type: Optional type of resource
message: Optional message text
details: Optional additional details
send_email: Whether to also send email notification
email_template: Template to use for email (if sending email)
email_data: Data for email template (if sending email)
Returns:
List of created notification UIDs
"""
# Ensure users is a list
if not isinstance(users, list):
users = [users]
# Extract UIDs and emails
user_uids = []
user_emails = []
for user in users:
if isinstance(user, DocUser):
user_uids.append(user.uid)
if user.email:
user_emails.append(user.email)
else:
user_uids.append(user)
# Try to get email from database
result = db.run_query(
"MATCH (u:User {UID: $uid}) RETURN u.Email as email",
{"uid": user}
)
if result and result[0].get('email'):
user_emails.append(result[0]['email'])
# Create in-app notifications
notification_uids = []
for user_uid in user_uids:
notification_uid = create_notification(
notification_type, user_uid, resource_uid,
resource_type, message, details
)
if notification_uid:
notification_uids.append(notification_uid)
# Send email if requested
if send_email and user_emails:
# Get notification info
notification_info = NOTIFICATION_TYPES.get(notification_type, {})
# Prepare subject
subject = notification_info.get('subject', 'Notification from ' + settings.APP_NAME)
# Format subject with details if available
if details:
try:
subject = subject.format(**details)
except KeyError:
pass
# Default to message as subject if formatting fails
if subject == notification_info.get('subject') and message:
subject = message
# Send email
if email_template:
# Merge details and email_data
template_data = {}
if details:
template_data.update(details)
if email_data:
template_data.update(email_data)
# Add message if provided
if message:
template_data['message'] = message
# Send email
send_email(user_emails, subject, email_template, template_data)
return notification_uids
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
notification_type |
str | - | positional_or_keyword |
users |
Union[List[Union[DocUser, str]], DocUser, str] | - | positional_or_keyword |
resource_uid |
Optional[str] | None | positional_or_keyword |
resource_type |
Optional[str] | None | positional_or_keyword |
message |
Optional[str] | None | positional_or_keyword |
details |
Optional[Dict[str, Any]] | None | positional_or_keyword |
send_email |
bool | False | positional_or_keyword |
email_template |
Optional[str] | None | positional_or_keyword |
email_data |
Optional[Dict[str, Any]] | None | positional_or_keyword |
Parameter Details
notification_type: String identifier for the type of notification, must match a key in the NOTIFICATION_TYPES configuration dictionary. This determines the notification category and default subject line.
users: Single user or list of users to notify. Can be DocUser instance(s), user UID string(s), or a mix. The function normalizes this to a list internally.
resource_uid: Optional unique identifier of the resource (document, review, approval, etc.) that this notification relates to. Used for linking notifications to specific resources.
resource_type: Optional string indicating the type of resource (e.g., 'document', 'review', 'approval'). Helps categorize notifications by resource type.
message: Optional custom message text for the notification. If provided and email subject formatting fails, this will be used as the email subject.
details: Optional dictionary containing additional structured data about the notification. Used for subject line formatting and passed to email templates.
send_email: Boolean flag indicating whether to send email notifications in addition to in-app notifications. Defaults to False.
email_template: Optional string identifier for the email template to use when sending emails. Required if send_email is True and you want formatted emails.
email_data: Optional dictionary containing additional data to pass to the email template. Merged with 'details' parameter, with email_data taking precedence on key conflicts.
Return Value
Type: List[str]
Returns a list of strings containing the UIDs of successfully created in-app notifications. Each UID corresponds to one notification created for one user. If notification creation fails for any user, that UID will not be included in the list. An empty list indicates no notifications were created.
Dependencies
loggingosjsonuuidtypingdatetimerebase64email.mime.multipartemail.mime.textemail.mime.applicationsmtplibmsalrequestsCDocsCDocs.configCDocs.models.user_extensionsCDocs.utilsmodels.reviewmodels.approval
Required Imports
from typing import Dict, List, Any, Optional, Union
from CDocs.models.user_extensions import DocUser
from CDocs import db
from CDocs.config import settings
Usage Example
# Example 1: Send simple in-app notification to single user
notification_uids = send_notification(
notification_type='document_updated',
users='user_123',
resource_uid='doc_456',
resource_type='document',
message='Your document has been updated'
)
# Example 2: Send notification with email to multiple users
from CDocs.models.user_extensions import DocUser
user1 = DocUser(uid='user_123', email='user1@example.com')
user2 = DocUser(uid='user_456', email='user2@example.com')
notification_uids = send_notification(
notification_type='review_assigned',
users=[user1, user2],
resource_uid='review_789',
resource_type='review',
message='You have been assigned to review a document',
details={'document_name': 'Project Plan', 'due_date': '2024-01-15'},
send_email=True,
email_template='review_assignment',
email_data={'reviewer_name': 'John Doe', 'document_url': 'https://app.example.com/doc/789'}
)
# Example 3: Mixed user types
notification_uids = send_notification(
notification_type='approval_required',
users=[user1, 'user_789'], # Mix of DocUser and UID string
resource_uid='approval_101',
resource_type='approval',
details={'approver': 'Jane Smith', 'deadline': '2024-01-20'}
)
Best Practices
- Always ensure NOTIFICATION_TYPES dictionary contains the notification_type key before calling this function to avoid missing subject lines
- When using send_email=True, provide email_template for properly formatted emails rather than relying on plain message text
- Be aware of the naming conflict: the parameter 'send_email' (bool) shadows the function 'send_email()' called internally - this is a code smell that should be refactored
- The function silently continues if email retrieval fails for string UIDs, so verify user UIDs exist in database beforehand for critical notifications
- Use 'details' parameter for data that should be available to both in-app notifications and email templates
- Use 'email_data' parameter for email-specific data that shouldn't be stored in the in-app notification
- Check the returned list length to verify all notifications were created successfully
- The function requires create_notification() to be defined elsewhere - ensure this dependency is available
- Subject line formatting uses Python's str.format() with details dict - ensure detail keys match template placeholders
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function send_notification 97.6% similar
-
function create_notification 74.6% similar
-
function notify_approval_v1 67.9% similar
-
function notify_approval 67.3% similar
-
function notify_document_update 65.8% similar