Repository: zulip/zulip

Issue:
Script to auto-generate message screenshots on /for/research
<!-- Issue description -->

At present, we manually generate screenshots on /for/research (and other landing pages), which makes them difficult to maintain. The UI in these screenshots is currently quite out of date. We should write a script to automate how the message screenshots are generated.

The script should be structured so that it's easy to:

- Extend it to screenshots on other pages. (Some will require a content pass, so let's get one page done first.)
- Update character names, channel names, topic names, and message content without having to think much about the code.

Notes:
- Use `tools/generate-integration-docs-screenshot` as a starting point. `zilencer/management/commands/add_mock_conversation.py` may also be helpful, but does not currently run.
- Keep the message content, topics and channels the same as we have in the screenshots now. You can use placeholders for the profile images; I expect we'll update those. The senders should not be bots, of course.
- This is just for the message screenshots, not the streams (a.k.a. channels) and topics screenshot, which we'll be redoing separately in Figma. 
 
<details>
<summary>
Screenshots to update
</summary>

![image](https://github.com/zulip/zulip/assets/2090066/3e2cecce-e8ce-4fb6-9689-6d7f963971b6)
![image](https://github.com/zulip/zulip/assets/2090066/c6dcaaac-d0bd-4f54-8c31-3c258a8d4cb9)


</details>


Discussion:
Hello @zulip/server-misc members, this issue was labeled with the "area: portico" label, so you may want to check it out!

<!-- areaLabelAddition -->

@roanster007 Are you interested in picking up this one? Assigning it to you for now, but feel free to unassign yourself if it doesn't seem like a good fit.

Resolving patch:
diff --git a/zerver/actions/message_send.py b/zerver/actions/message_send.py
--- a/zerver/actions/message_send.py
+++ b/zerver/actions/message_send.py
@@ -1794,6 +1794,8 @@ def _internal_prep_message(
     mention_backend: Optional[MentionBackend] = None,
     limit_unread_user_ids: Optional[Set[int]] = None,
     disable_external_notifications: bool = False,
+    forged: bool = False,
+    forged_timestamp: Optional[float] = None,
 ) -> Optional[SendMessageRequest]:
     """
     Create a message object and checks it, but doesn't send it or save it to the database.
@@ -1822,6 +1824,8 @@ def _internal_prep_message(
             mention_backend=mention_backend,
             limit_unread_user_ids=limit_unread_user_ids,
             disable_external_notifications=disable_external_notifications,
+            forged=forged,
+            forged_timestamp=forged_timestamp,
         )
     except JsonableError as e:
         logging.exception(
@@ -1842,6 +1846,8 @@ def internal_prep_stream_message(
     *,
     email_gateway: bool = False,
     limit_unread_user_ids: Optional[Set[int]] = None,
+    forged: bool = False,
+    forged_timestamp: Optional[float] = None,
 ) -> Optional[SendMessageRequest]:
     """
     See _internal_prep_message for details of how this works.
@@ -1856,6 +1862,8 @@ def internal_prep_stream_message(
         content=content,
         email_gateway=email_gateway,
         limit_unread_user_ids=limit_unread_user_ids,
+        forged=forged,
+        forged_timestamp=forged_timestamp,
     )
 
 


Test patch:
diff --git a/zerver/tests/test_integrations.py b/zerver/tests/test_integrations.py
--- a/zerver/tests/test_integrations.py
+++ b/zerver/tests/test_integrations.py
@@ -62,7 +62,7 @@ def test_no_missing_screenshot_path(self) -> None:
         message = (
             '"{path}" does not exist for webhook {webhook_name}.\n'
             "Consider updating zerver.lib.integrations.DOC_SCREENSHOT_CONFIG\n"
-            'and running "tools/generate-integration-docs-screenshot" to keep the screenshots up-to-date.'
+            'and running "tools/screenshots/generate-integration-docs-screenshot" to keep the screenshots up-to-date.'
         )
         for integration_name in DOC_SCREENSHOT_CONFIG:
             configs = DOC_SCREENSHOT_CONFIG[integration_name]