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.
This commit is contained in:
Alex Vandiver 2023-08-03 21:32:46 +00:00 committed by Tim Abbott
parent 95b0ab31be
commit 292595afc4
1 changed files with 18 additions and 0 deletions

View File

@ -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)