From 292595afc4cc366e9735cca6cd9b89ffcfdcc955 Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Thu, 3 Aug 2023 21:32:46 +0000 Subject: [PATCH] send_custom_email: Add a mode which reads data from JSON. This allows us to not have to keep extending the tool for every one-off use case and set of users; we build a pipeline to generate the appropriate JSON file, write a template which uses the data it provides, and run the tool with them together. --- .../management/commands/send_custom_email.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/zerver/management/commands/send_custom_email.py b/zerver/management/commands/send_custom_email.py index 5e0a116e38..9d4af230c9 100644 --- a/zerver/management/commands/send_custom_email.py +++ b/zerver/management/commands/send_custom_email.py @@ -1,6 +1,7 @@ from argparse import ArgumentParser from typing import Any, Callable, Dict, List, Optional, Union +import orjson from django.conf import settings from django.db.models import Q, QuerySet @@ -39,6 +40,11 @@ class Command(ZulipBaseCommand): action="store_true", help="Send to all organization administrators of sponsored organizations.", ) + targets.add_argument( + "--json-file", + help="Load the JSON file, and send to the users whose ids are the keys in that dict; " + "the context for each email will be extended by each value in the dict.", + ) self.add_user_list_args( targets, help="Email addresses of user(s) to send emails to.", @@ -131,6 +137,18 @@ class Command(ZulipBaseCommand): realm__deactivated=False, realm__in=sponsored_realms, ).distinct("delivery_email") + elif options["json_file"]: + with open(options["json_file"]) as f: + user_data: Dict[str, Dict[str, Union[List[str], str]]] = orjson.loads(f.read()) + users = UserProfile.objects.filter(id__in=[int(user_id) for user_id in user_data]) + + def add_context_from_dict( + context: Dict[str, Union[List[str], str]], user: UserProfile + ) -> None: + context.update(user_data.get(str(user.id), {})) + + add_context = add_context_from_dict + else: realm = self.get_realm(options) users = self.get_users(options, realm, is_bot=False)