We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Do not unfurl links and media by default in Slack notifications
## Problem
<!-- Describe a problem solved by this feature; or delete the section entirely. -->
Recent provider DAG errors have caused notifications containing images to be sent to Slack. For example, a recent data refresh error notification embedded the image that was being processed when the error was encountered. @sarayourfriend pointed out that while these messages have historically been harmless, it's possible that this could happen with NSFW content.

## Description
<!-- Describe the feature and how it solves the problem. -->
We have a PR to at least help this situation in the Catalog by [preventing links and media from unfurling](https://github.com/WordPress/openverse-catalog/pull/743) in Slack notifications. We should add the same functionality to the Slack utility in the ingestion server.

We should be able to do this the same way as it is done in the catalog, by using the `unfurl_links` and `unfurl_media` options in the payload [here](https://github.com/WordPress/openverse-api/blob/main/ingestion_server/ingestion_server/slack.py#L48). For reference, [this is where it is done in the Catalog](https://github.com/WordPress/openverse-catalog/blob/main/openverse_catalog/dags/common/slack.py#L97). 

## Additional context
<!-- Add any other context about the feature here; or delete the section entirely. -->
In the Catalog we expose `unfurl_links` and `unfurl_media` as arguments in the Slack utility, so it is possible to set them to `True/False` as needed for an individual message. This _might_ be nice to have, but I don't believe it is currently necessary.

## Implementation
<!-- Replace the [ ] with [x] to check the box. -->
- [ ] 🙋 I would be interested in implementing this feature.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ingestion_server/ingestion_server/slack.py`
Content:
```
1 import logging
2 import os
3 from enum import Enum
4 
5 import requests
6 from decouple import config
7 
8 
9 log = logging.getLogger(__name__)
10 SLACK_WEBHOOK = "SLACK_WEBHOOK"
11 LOG_LEVEL = "SLACK_LOG_LEVEL"
12 
13 
14 class Level(Enum):
15     VERBOSE = 0
16     INFO = 1
17     ERROR = 2
18 
19 
20 def _message(text: str, summary: str = None, level: Level = Level.INFO) -> None:
21     """
22     Send a Slack message to a channel specified by a Slack webhook variable.
23 
24     A message is only sent if the SLACK_WEBHOOK environment variable is undefined,
25     and the environment is configured to log at this level.
26     """
27     environment = config("ENVIRONMENT", default="local")
28 
29     if not (webhook := os.getenv(SLACK_WEBHOOK)):
30         log.debug(
31             f"{SLACK_WEBHOOK} variable not defined, skipping slack message: {text}"
32         )
33         return
34     # If no log level is configured in the environment, log everything by default.
35     os_level = Level[os.getenv(LOG_LEVEL, Level.VERBOSE.name)]
36     if level.value < os_level.value:
37         log.debug(
38             f"Slack logging level for {environment} set to {os_level.name}, skipping \
39             slack message with priority {level.name}: {text}"
40         )
41         return
42     if not summary:
43         if "\n" in text:
44             summary = "Ingestion server message"
45         else:
46             summary = text
47 
48     data = {
49         "blocks": [{"text": {"text": text, "type": "mrkdwn"}, "type": "section"}],
50         "text": summary,
51         "username": f"Data Refresh Notification | {environment.upper()}",
52         "icon_emoji": "arrows_counterclockwise",
53     }
54     try:
55         requests.post(webhook, json=data)
56     except Exception as err:
57         log.exception(f"Unable to issue slack message: {err}")
58         pass
59 
60 
61 def verbose(text: str, summary: str = None) -> None:
62     _message(text, summary, level=Level.VERBOSE)
63 
64 
65 def info(text: str, summary: str = None) -> None:
66     _message(text, summary, level=Level.INFO)
67 
68 
69 def error(text: str, summary: str = None) -> None:
70     _message(text, summary, level=Level.ERROR)
71
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ingestion_server/ingestion_server/slack.py b/ingestion_server/ingestion_server/slack.py
--- a/ingestion_server/ingestion_server/slack.py
+++ b/ingestion_server/ingestion_server/slack.py
@@ -50,6 +50,8 @@
         "text": summary,
         "username": f"Data Refresh Notification | {environment.upper()}",
         "icon_emoji": "arrows_counterclockwise",
+        "unfurl_links": False,
+        "unfurl_media": False,
     }
     try:
         requests.post(webhook, json=data)

{"golden_diff": "diff --git a/ingestion_server/ingestion_server/slack.py b/ingestion_server/ingestion_server/slack.py\n--- a/ingestion_server/ingestion_server/slack.py\n+++ b/ingestion_server/ingestion_server/slack.py\n@@ -50,6 +50,8 @@\n         \"text\": summary,\n         \"username\": f\"Data Refresh Notification | {environment.upper()}\",\n         \"icon_emoji\": \"arrows_counterclockwise\",\n+        \"unfurl_links\": False,\n+        \"unfurl_media\": False,\n     }\n     try:\n         requests.post(webhook, json=data)\n", "issue": "Do not unfurl links and media by default in Slack notifications\n## Problem\r\n<!-- Describe a problem solved by this feature; or delete the section entirely. -->\r\nRecent provider DAG errors have caused notifications containing images to be sent to Slack. For example, a recent data refresh error notification embedded the image that was being processed when the error was encountered. @sarayourfriend pointed out that while these messages have historically been harmless, it's possible that this could happen with NSFW content.\r\n\r\n## Description\r\n<!-- Describe the feature and how it solves the problem. -->\r\nWe have a PR to at least help this situation in the Catalog by [preventing links and media from unfurling](https://github.com/WordPress/openverse-catalog/pull/743) in Slack notifications. We should add the same functionality to the Slack utility in the ingestion server.\r\n\r\nWe should be able to do this the same way as it is done in the catalog, by using the `unfurl_links` and `unfurl_media` options in the payload [here](https://github.com/WordPress/openverse-api/blob/main/ingestion_server/ingestion_server/slack.py#L48). For reference, [this is where it is done in the Catalog](https://github.com/WordPress/openverse-catalog/blob/main/openverse_catalog/dags/common/slack.py#L97). \r\n\r\n## Additional context\r\n<!-- Add any other context about the feature here; or delete the section entirely. -->\r\nIn the Catalog we expose `unfurl_links` and `unfurl_media` as arguments in the Slack utility, so it is possible to set them to `True/False` as needed for an individual message. This _might_ be nice to have, but I don't believe it is currently necessary.\r\n\r\n## Implementation\r\n<!-- Replace the [ ] with [x] to check the box. -->\r\n- [ ] \ud83d\ude4b I would be interested in implementing this feature.\r\n\n", "before_files": [{"content": "import logging\nimport os\nfrom enum import Enum\n\nimport requests\nfrom decouple import config\n\n\nlog = logging.getLogger(__name__)\nSLACK_WEBHOOK = \"SLACK_WEBHOOK\"\nLOG_LEVEL = \"SLACK_LOG_LEVEL\"\n\n\nclass Level(Enum):\n    VERBOSE = 0\n    INFO = 1\n    ERROR = 2\n\n\ndef _message(text: str, summary: str = None, level: Level = Level.INFO) -> None:\n    \"\"\"\n    Send a Slack message to a channel specified by a Slack webhook variable.\n\n    A message is only sent if the SLACK_WEBHOOK environment variable is undefined,\n    and the environment is configured to log at this level.\n    \"\"\"\n    environment = config(\"ENVIRONMENT\", default=\"local\")\n\n    if not (webhook := os.getenv(SLACK_WEBHOOK)):\n        log.debug(\n            f\"{SLACK_WEBHOOK} variable not defined, skipping slack message: {text}\"\n        )\n        return\n    # If no log level is configured in the environment, log everything by default.\n    os_level = Level[os.getenv(LOG_LEVEL, Level.VERBOSE.name)]\n    if level.value < os_level.value:\n        log.debug(\n            f\"Slack logging level for {environment} set to {os_level.name}, skipping \\\n            slack message with priority {level.name}: {text}\"\n        )\n        return\n    if not summary:\n        if \"\\n\" in text:\n            summary = \"Ingestion server message\"\n        else:\n            summary = text\n\n    data = {\n        \"blocks\": [{\"text\": {\"text\": text, \"type\": \"mrkdwn\"}, \"type\": \"section\"}],\n        \"text\": summary,\n        \"username\": f\"Data Refresh Notification | {environment.upper()}\",\n        \"icon_emoji\": \"arrows_counterclockwise\",\n    }\n    try:\n        requests.post(webhook, json=data)\n    except Exception as err:\n        log.exception(f\"Unable to issue slack message: {err}\")\n        pass\n\n\ndef verbose(text: str, summary: str = None) -> None:\n    _message(text, summary, level=Level.VERBOSE)\n\n\ndef info(text: str, summary: str = None) -> None:\n    _message(text, summary, level=Level.INFO)\n\n\ndef error(text: str, summary: str = None) -> None:\n    _message(text, summary, level=Level.ERROR)\n", "path": "ingestion_server/ingestion_server/slack.py"}], "after_files": [{"content": "import logging\nimport os\nfrom enum import Enum\n\nimport requests\nfrom decouple import config\n\n\nlog = logging.getLogger(__name__)\nSLACK_WEBHOOK = \"SLACK_WEBHOOK\"\nLOG_LEVEL = \"SLACK_LOG_LEVEL\"\n\n\nclass Level(Enum):\n    VERBOSE = 0\n    INFO = 1\n    ERROR = 2\n\n\ndef _message(text: str, summary: str = None, level: Level = Level.INFO) -> None:\n    \"\"\"\n    Send a Slack message to a channel specified by a Slack webhook variable.\n\n    A message is only sent if the SLACK_WEBHOOK environment variable is undefined,\n    and the environment is configured to log at this level.\n    \"\"\"\n    environment = config(\"ENVIRONMENT\", default=\"local\")\n\n    if not (webhook := os.getenv(SLACK_WEBHOOK)):\n        log.debug(\n            f\"{SLACK_WEBHOOK} variable not defined, skipping slack message: {text}\"\n        )\n        return\n    # If no log level is configured in the environment, log everything by default.\n    os_level = Level[os.getenv(LOG_LEVEL, Level.VERBOSE.name)]\n    if level.value < os_level.value:\n        log.debug(\n            f\"Slack logging level for {environment} set to {os_level.name}, skipping \\\n            slack message with priority {level.name}: {text}\"\n        )\n        return\n    if not summary:\n        if \"\\n\" in text:\n            summary = \"Ingestion server message\"\n        else:\n            summary = text\n\n    data = {\n        \"blocks\": [{\"text\": {\"text\": text, \"type\": \"mrkdwn\"}, \"type\": \"section\"}],\n        \"text\": summary,\n        \"username\": f\"Data Refresh Notification | {environment.upper()}\",\n        \"icon_emoji\": \"arrows_counterclockwise\",\n        \"unfurl_links\": False,\n        \"unfurl_media\": False,\n    }\n    try:\n        requests.post(webhook, json=data)\n    except Exception as err:\n        log.exception(f\"Unable to issue slack message: {err}\")\n        pass\n\n\ndef verbose(text: str, summary: str = None) -> None:\n    _message(text, summary, level=Level.VERBOSE)\n\n\ndef info(text: str, summary: str = None) -> None:\n    _message(text, summary, level=Level.INFO)\n\n\ndef error(text: str, summary: str = None) -> None:\n    _message(text, summary, level=Level.ERROR)\n", "path": "ingestion_server/ingestion_server/slack.py"}]}