Repository: Cog-Creators/Red-DiscordBot

Issue:
[Streams] twitch channel no longer exists and removed
### What Red version are you using?

3.4.9

### Cog name

Streams

### Command name

streamalert twitch

### What did you expect to happen?

After i added the stream, it should announce everytime a stream is up

### What actually happened?

the stream was recognized as no longer exists and removed from list 

### How can we reproduce this error?

1. [p]streamalert twitch salmoninthebox
2. wait and check logs i suppose

### Anything else?

i checked all other streamalerts from other streams in other servers and they seem to be fine


Discussion:

Resolving patch:
diff --git a/redbot/cogs/streams/streams.py b/redbot/cogs/streams/streams.py
--- a/redbot/cogs/streams/streams.py
+++ b/redbot/cogs/streams/streams.py
@@ -528,9 +528,10 @@ async def with_mention(self, ctx: commands.Context, *, message: str):
         """Set stream alert message when mentions are enabled.
 
         Use `{mention}` in the message to insert the selected mentions.
-        Use `{stream}` in the message to insert the channel or user name.
+        Use `{stream}` in the message to insert the channel or username.
+        Use `{stream.display_name}` in the message to insert the channel's display name (on Twitch, this may be different from `{stream}`).
 
-        For example: `[p]streamset message mention {mention}, {stream} is live!`
+        For example: `[p]streamset message mention {mention}, {stream.display_name} is live!`
         """
         guild = ctx.guild
         await self.config.guild(guild).live_message_mention.set(message)
@@ -541,9 +542,10 @@ async def with_mention(self, ctx: commands.Context, *, message: str):
     async def without_mention(self, ctx: commands.Context, *, message: str):
         """Set stream alert message when mentions are disabled.
 
-        Use `{stream}` in the message to insert the channel or user name.
+        Use `{stream}` in the message to insert the channel or username.
+        Use `{stream.display_name}` in the message to insert the channel's display name (on Twitch, this may be different from `{stream}`).
 
-        For example: `[p]streamset message nomention {stream} is live!`
+        For example: `[p]streamset message nomention {stream.display_name} is live!`
         """
         guild = ctx.guild
         await self.config.guild(guild).live_message_nomention.set(message)
@@ -801,13 +803,18 @@ async def check_streams(self):
                                 content = content.replace(
                                     "{stream.name}", str(stream.name)
                                 )  # Backwards compatibility
+                                content = content.replace(
+                                    "{stream.display_name}", str(stream.display_name)
+                                )
                                 content = content.replace("{stream}", str(stream.name))
                                 content = content.replace("{mention}", mention_str)
                             else:
-                                content = _("{mention}, {stream} is live!").format(
+                                content = _("{mention}, {display_name} is live!").format(
                                     mention=mention_str,
-                                    stream=escape(
-                                        str(stream.name), mass_mentions=True, formatting=True
+                                    display_name=escape(
+                                        str(stream.display_name),
+                                        mass_mentions=True,
+                                        formatting=True,
                                     ),
                                 )
                         else:
@@ -819,11 +826,16 @@ async def check_streams(self):
                                 content = content.replace(
                                     "{stream.name}", str(stream.name)
                                 )  # Backwards compatibility
+                                content = content.replace(
+                                    "{stream.display_name}", str(stream.display_name)
+                                )
                                 content = content.replace("{stream}", str(stream.name))
                             else:
-                                content = _("{stream} is live!").format(
-                                    stream=escape(
-                                        str(stream.name), mass_mentions=True, formatting=True
+                                content = _("{display_name} is live!").format(
+                                    display_name=escape(
+                                        str(stream.display_name),
+                                        mass_mentions=True,
+                                        formatting=True,
                                     )
                                 )
                         await self._send_stream_alert(stream, channel, embed, content)
diff --git a/redbot/cogs/streams/streamtypes.py b/redbot/cogs/streams/streamtypes.py
--- a/redbot/cogs/streams/streamtypes.py
+++ b/redbot/cogs/streams/streamtypes.py
@@ -65,6 +65,10 @@ def __init__(self, **kwargs):
         self.messages = kwargs.pop("messages", [])
         self.type = self.__class__.__name__
 
+    @property
+    def display_name(self) -> Optional[str]:
+        return self.name
+
     async def is_online(self):
         raise NotImplementedError()
 
@@ -299,12 +303,21 @@ class TwitchStream(Stream):
 
     def __init__(self, **kwargs):
         self.id = kwargs.pop("id", None)
+        self._display_name = None
         self._client_id = kwargs.pop("token", None)
         self._bearer = kwargs.pop("bearer", None)
         self._rate_limit_resets: set = set()
         self._rate_limit_remaining: int = 0
         super().__init__(**kwargs)
 
+    @property
+    def display_name(self) -> Optional[str]:
+        return self._display_name or self.name
+
+    @display_name.setter
+    def display_name(self, value: str) -> None:
+        self._display_name = value
+
     async def wait_for_rate_limit_reset(self) -> None:
         """Check rate limits in response header and ensure we're following them.
 
@@ -378,7 +391,7 @@ async def is_online(self):
                 final_data["view_count"] = user_profile_data["view_count"]
 
             stream_data = stream_data["data"][0]
-            final_data["user_name"] = self.name = stream_data["user_name"]
+            final_data["user_name"] = self.display_name = stream_data["user_name"]
             final_data["game_name"] = stream_data["game_name"]
             final_data["thumbnail_url"] = stream_data["thumbnail_url"]
             final_data["title"] = stream_data["title"]


Test patch: