prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Cannot react with a custom emoji to a bot message 
  Attempting to react to a bot message with a custom emoji appears to work but if you refresh the page it's gone. Inspecting the network requests reveals that the request to add the reaction fails with a 400 Bad Request error `Reaction doesn't exist.`.
  
  This can be easily reproduced with the Notification Bot. Note that the `zulip` reaction works since it's not really a custom emoji, but you can reproduce the problem with any other custom emoji.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `zerver/views/reactions.py`
  Content:
  ```
  1 from typing import Optional
  2 
  3 from django.http import HttpRequest, HttpResponse
  4 from django.utils.translation import ugettext as _
  5 
  6 from zerver.decorator import REQ, has_request_variables
  7 from zerver.lib.actions import do_add_reaction, do_remove_reaction
  8 from zerver.lib.emoji import check_emoji_request, emoji_name_to_emoji_code
  9 from zerver.lib.message import access_message
  10 from zerver.lib.request import JsonableError
  11 from zerver.lib.response import json_success
  12 from zerver.models import Message, Reaction, UserMessage, UserProfile
  13 
  14 
  15 def create_historical_message(user_profile: UserProfile, message: Message) -> None:
  16     # Users can see and react to messages sent to streams they
  17     # were not a subscriber to; in order to receive events for
  18     # those, we give the user a `historical` UserMessage objects
  19     # for the message.  This is the same trick we use for starring
  20     # messages.
  21     UserMessage.objects.create(user_profile=user_profile,
  22                                message=message,
  23                                flags=UserMessage.flags.historical | UserMessage.flags.read)
  24 
  25 @has_request_variables
  26 def add_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int,
  27                  emoji_name: str=REQ(),
  28                  emoji_code: Optional[str]=REQ(default=None),
  29                  reaction_type: Optional[str]=REQ(default=None)) -> HttpResponse:
  30     message, user_message = access_message(user_profile, message_id)
  31 
  32     if emoji_code is None:
  33         # The emoji_code argument is only required for rare corner
  34         # cases discussed in the long block comment below.  For simple
  35         # API clients, we allow specifying just the name, and just
  36         # look up the code using the current name->code mapping.
  37         emoji_code = emoji_name_to_emoji_code(message.sender.realm,
  38                                               emoji_name)[0]
  39 
  40     if reaction_type is None:
  41         reaction_type = emoji_name_to_emoji_code(message.sender.realm,
  42                                                  emoji_name)[1]
  43 
  44     if Reaction.objects.filter(user_profile=user_profile,
  45                                message=message,
  46                                emoji_code=emoji_code,
  47                                reaction_type=reaction_type).exists():
  48         raise JsonableError(_("Reaction already exists."))
  49 
  50     query = Reaction.objects.filter(message=message,
  51                                     emoji_code=emoji_code,
  52                                     reaction_type=reaction_type)
  53     if query.exists():
  54         # If another user has already reacted to this message with
  55         # same emoji code, we treat the new reaction as a vote for the
  56         # existing reaction.  So the emoji name used by that earlier
  57         # reaction takes precedence over whatever was passed in this
  58         # request.  This is necessary to avoid a message having 2
  59         # "different" emoji reactions with the same emoji code (and
  60         # thus same image) on the same message, which looks ugly.
  61         #
  62         # In this "voting for an existing reaction" case, we shouldn't
  63         # check whether the emoji code and emoji name match, since
  64         # it's possible that the (emoji_type, emoji_name, emoji_code)
  65         # triple for this existing rection xmay not pass validation
  66         # now (e.g. because it is for a realm emoji that has been
  67         # since deactivated).  We still want to allow users to add a
  68         # vote any old reaction they see in the UI even if that is a
  69         # deactivated custom emoji, so we just use the emoji name from
  70         # the existing reaction with no further validation.
  71         emoji_name = query.first().emoji_name
  72     else:
  73         # Otherwise, use the name provided in this request, but verify
  74         # it is valid in the user's realm (e.g. not a deactivated
  75         # realm emoji).
  76         check_emoji_request(message.sender.realm, emoji_name,
  77                             emoji_code, reaction_type)
  78 
  79     if user_message is None:
  80         create_historical_message(user_profile, message)
  81 
  82     do_add_reaction(user_profile, message, emoji_name, emoji_code, reaction_type)
  83 
  84     return json_success()
  85 
  86 @has_request_variables
  87 def remove_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int,
  88                     emoji_name: Optional[str]=REQ(default=None),
  89                     emoji_code: Optional[str]=REQ(default=None),
  90                     reaction_type: str=REQ(default="unicode_emoji")) -> HttpResponse:
  91     message, user_message = access_message(user_profile, message_id)
  92 
  93     if emoji_code is None:
  94         if emoji_name is None:
  95             raise JsonableError(_('At least one of the following arguments '
  96                                   'must be present: emoji_name, emoji_code'))
  97         # A correct full Zulip client implementation should always
  98         # pass an emoji_code, because of the corner cases discussed in
  99         # the long block comments elsewhere in this file.  However, to
  100         # make it easy for simple API clients to use the reactions API
  101         # without needing the mapping between emoji names and codes,
  102         # we allow instead passing the emoji_name and looking up the
  103         # corresponding code using the current data.
  104         emoji_code = emoji_name_to_emoji_code(message.sender.realm, emoji_name)[0]
  105 
  106     if not Reaction.objects.filter(user_profile=user_profile,
  107                                    message=message,
  108                                    emoji_code=emoji_code,
  109                                    reaction_type=reaction_type).exists():
  110         raise JsonableError(_("Reaction doesn't exist."))
  111 
  112     # Unlike adding reactions, while deleting a reaction, we don't
  113     # check whether the provided (emoji_type, emoji_code) pair is
  114     # valid in this realm.  Since there's a row in the database, we
  115     # know it was valid when the user added their reaction in the
  116     # first place, so it is safe to just remove the reaction if it
  117     # exists.  And the (reaction_type, emoji_code) pair may no longer be
  118     # valid in legitimate situations (e.g. if a realm emoji was
  119     # deactivated by an administrator in the meantime).
  120     do_remove_reaction(user_profile, message, emoji_code, reaction_type)
  121 
  122     return json_success()
  123
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/zerver/views/reactions.py b/zerver/views/reactions.py
  --- a/zerver/views/reactions.py
  +++ b/zerver/views/reactions.py
  @@ -73,7 +73,7 @@
           # Otherwise, use the name provided in this request, but verify
           # it is valid in the user's realm (e.g. not a deactivated
           # realm emoji).
  -        check_emoji_request(message.sender.realm, emoji_name,
  +        check_emoji_request(user_profile.realm, emoji_name,
                               emoji_code, reaction_type)
   
       if user_message is None:
  
verification_info: {"golden_diff": "diff --git a/zerver/views/reactions.py b/zerver/views/reactions.py\n--- a/zerver/views/reactions.py\n+++ b/zerver/views/reactions.py\n@@ -73,7 +73,7 @@\n         # Otherwise, use the name provided in this request, but verify\n         # it is valid in the user's realm (e.g. not a deactivated\n         # realm emoji).\n-        check_emoji_request(message.sender.realm, emoji_name,\n+        check_emoji_request(user_profile.realm, emoji_name,\n                             emoji_code, reaction_type)\n \n     if user_message is None:\n", "issue": "Cannot react with a custom emoji to a bot message \nAttempting to react to a bot message with a custom emoji appears to work but if you refresh the page it's gone. Inspecting the network requests reveals that the request to add the reaction fails with a 400 Bad Request error `Reaction doesn't exist.`.\r\n\r\nThis can be easily reproduced with the Notification Bot. Note that the `zulip` reaction works since it's not really a custom emoji, but you can reproduce the problem with any other custom emoji.\n", "before_files": [{"content": "from typing import Optional\n\nfrom django.http import HttpRequest, HttpResponse\nfrom django.utils.translation import ugettext as _\n\nfrom zerver.decorator import REQ, has_request_variables\nfrom zerver.lib.actions import do_add_reaction, do_remove_reaction\nfrom zerver.lib.emoji import check_emoji_request, emoji_name_to_emoji_code\nfrom zerver.lib.message import access_message\nfrom zerver.lib.request import JsonableError\nfrom zerver.lib.response import json_success\nfrom zerver.models import Message, Reaction, UserMessage, UserProfile\n\n\ndef create_historical_message(user_profile: UserProfile, message: Message) -> None:\n    # Users can see and react to messages sent to streams they\n    # were not a subscriber to; in order to receive events for\n    # those, we give the user a `historical` UserMessage objects\n    # for the message.  This is the same trick we use for starring\n    # messages.\n    UserMessage.objects.create(user_profile=user_profile,\n                               message=message,\n                               flags=UserMessage.flags.historical | UserMessage.flags.read)\n\n@has_request_variables\ndef add_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int,\n                 emoji_name: str=REQ(),\n                 emoji_code: Optional[str]=REQ(default=None),\n                 reaction_type: Optional[str]=REQ(default=None)) -> HttpResponse:\n    message, user_message = access_message(user_profile, message_id)\n\n    if emoji_code is None:\n        # The emoji_code argument is only required for rare corner\n        # cases discussed in the long block comment below.  For simple\n        # API clients, we allow specifying just the name, and just\n        # look up the code using the current name->code mapping.\n        emoji_code = emoji_name_to_emoji_code(message.sender.realm,\n                                              emoji_name)[0]\n\n    if reaction_type is None:\n        reaction_type = emoji_name_to_emoji_code(message.sender.realm,\n                                                 emoji_name)[1]\n\n    if Reaction.objects.filter(user_profile=user_profile,\n                               message=message,\n                               emoji_code=emoji_code,\n                               reaction_type=reaction_type).exists():\n        raise JsonableError(_(\"Reaction already exists.\"))\n\n    query = Reaction.objects.filter(message=message,\n                                    emoji_code=emoji_code,\n                                    reaction_type=reaction_type)\n    if query.exists():\n        # If another user has already reacted to this message with\n        # same emoji code, we treat the new reaction as a vote for the\n        # existing reaction.  So the emoji name used by that earlier\n        # reaction takes precedence over whatever was passed in this\n        # request.  This is necessary to avoid a message having 2\n        # \"different\" emoji reactions with the same emoji code (and\n        # thus same image) on the same message, which looks ugly.\n        #\n        # In this \"voting for an existing reaction\" case, we shouldn't\n        # check whether the emoji code and emoji name match, since\n        # it's possible that the (emoji_type, emoji_name, emoji_code)\n        # triple for this existing rection xmay not pass validation\n        # now (e.g. because it is for a realm emoji that has been\n        # since deactivated).  We still want to allow users to add a\n        # vote any old reaction they see in the UI even if that is a\n        # deactivated custom emoji, so we just use the emoji name from\n        # the existing reaction with no further validation.\n        emoji_name = query.first().emoji_name\n    else:\n        # Otherwise, use the name provided in this request, but verify\n        # it is valid in the user's realm (e.g. not a deactivated\n        # realm emoji).\n        check_emoji_request(message.sender.realm, emoji_name,\n                            emoji_code, reaction_type)\n\n    if user_message is None:\n        create_historical_message(user_profile, message)\n\n    do_add_reaction(user_profile, message, emoji_name, emoji_code, reaction_type)\n\n    return json_success()\n\n@has_request_variables\ndef remove_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int,\n                    emoji_name: Optional[str]=REQ(default=None),\n                    emoji_code: Optional[str]=REQ(default=None),\n                    reaction_type: str=REQ(default=\"unicode_emoji\")) -> HttpResponse:\n    message, user_message = access_message(user_profile, message_id)\n\n    if emoji_code is None:\n        if emoji_name is None:\n            raise JsonableError(_('At least one of the following arguments '\n                                  'must be present: emoji_name, emoji_code'))\n        # A correct full Zulip client implementation should always\n        # pass an emoji_code, because of the corner cases discussed in\n        # the long block comments elsewhere in this file.  However, to\n        # make it easy for simple API clients to use the reactions API\n        # without needing the mapping between emoji names and codes,\n        # we allow instead passing the emoji_name and looking up the\n        # corresponding code using the current data.\n        emoji_code = emoji_name_to_emoji_code(message.sender.realm, emoji_name)[0]\n\n    if not Reaction.objects.filter(user_profile=user_profile,\n                                   message=message,\n                                   emoji_code=emoji_code,\n                                   reaction_type=reaction_type).exists():\n        raise JsonableError(_(\"Reaction doesn't exist.\"))\n\n    # Unlike adding reactions, while deleting a reaction, we don't\n    # check whether the provided (emoji_type, emoji_code) pair is\n    # valid in this realm.  Since there's a row in the database, we\n    # know it was valid when the user added their reaction in the\n    # first place, so it is safe to just remove the reaction if it\n    # exists.  And the (reaction_type, emoji_code) pair may no longer be\n    # valid in legitimate situations (e.g. if a realm emoji was\n    # deactivated by an administrator in the meantime).\n    do_remove_reaction(user_profile, message, emoji_code, reaction_type)\n\n    return json_success()\n", "path": "zerver/views/reactions.py"}], "after_files": [{"content": "from typing import Optional\n\nfrom django.http import HttpRequest, HttpResponse\nfrom django.utils.translation import ugettext as _\n\nfrom zerver.decorator import REQ, has_request_variables\nfrom zerver.lib.actions import do_add_reaction, do_remove_reaction\nfrom zerver.lib.emoji import check_emoji_request, emoji_name_to_emoji_code\nfrom zerver.lib.message import access_message\nfrom zerver.lib.request import JsonableError\nfrom zerver.lib.response import json_success\nfrom zerver.models import Message, Reaction, UserMessage, UserProfile\n\n\ndef create_historical_message(user_profile: UserProfile, message: Message) -> None:\n    # Users can see and react to messages sent to streams they\n    # were not a subscriber to; in order to receive events for\n    # those, we give the user a `historical` UserMessage objects\n    # for the message.  This is the same trick we use for starring\n    # messages.\n    UserMessage.objects.create(user_profile=user_profile,\n                               message=message,\n                               flags=UserMessage.flags.historical | UserMessage.flags.read)\n\n@has_request_variables\ndef add_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int,\n                 emoji_name: str=REQ(),\n                 emoji_code: Optional[str]=REQ(default=None),\n                 reaction_type: Optional[str]=REQ(default=None)) -> HttpResponse:\n    message, user_message = access_message(user_profile, message_id)\n\n    if emoji_code is None:\n        # The emoji_code argument is only required for rare corner\n        # cases discussed in the long block comment below.  For simple\n        # API clients, we allow specifying just the name, and just\n        # look up the code using the current name->code mapping.\n        emoji_code = emoji_name_to_emoji_code(message.sender.realm,\n                                              emoji_name)[0]\n\n    if reaction_type is None:\n        reaction_type = emoji_name_to_emoji_code(message.sender.realm,\n                                                 emoji_name)[1]\n\n    if Reaction.objects.filter(user_profile=user_profile,\n                               message=message,\n                               emoji_code=emoji_code,\n                               reaction_type=reaction_type).exists():\n        raise JsonableError(_(\"Reaction already exists.\"))\n\n    query = Reaction.objects.filter(message=message,\n                                    emoji_code=emoji_code,\n                                    reaction_type=reaction_type)\n    if query.exists():\n        # If another user has already reacted to this message with\n        # same emoji code, we treat the new reaction as a vote for the\n        # existing reaction.  So the emoji name used by that earlier\n        # reaction takes precedence over whatever was passed in this\n        # request.  This is necessary to avoid a message having 2\n        # \"different\" emoji reactions with the same emoji code (and\n        # thus same image) on the same message, which looks ugly.\n        #\n        # In this \"voting for an existing reaction\" case, we shouldn't\n        # check whether the emoji code and emoji name match, since\n        # it's possible that the (emoji_type, emoji_name, emoji_code)\n        # triple for this existing rection xmay not pass validation\n        # now (e.g. because it is for a realm emoji that has been\n        # since deactivated).  We still want to allow users to add a\n        # vote any old reaction they see in the UI even if that is a\n        # deactivated custom emoji, so we just use the emoji name from\n        # the existing reaction with no further validation.\n        emoji_name = query.first().emoji_name\n    else:\n        # Otherwise, use the name provided in this request, but verify\n        # it is valid in the user's realm (e.g. not a deactivated\n        # realm emoji).\n        check_emoji_request(user_profile.realm, emoji_name,\n                            emoji_code, reaction_type)\n\n    if user_message is None:\n        create_historical_message(user_profile, message)\n\n    do_add_reaction(user_profile, message, emoji_name, emoji_code, reaction_type)\n\n    return json_success()\n\n@has_request_variables\ndef remove_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int,\n                    emoji_name: Optional[str]=REQ(default=None),\n                    emoji_code: Optional[str]=REQ(default=None),\n                    reaction_type: str=REQ(default=\"unicode_emoji\")) -> HttpResponse:\n    message, user_message = access_message(user_profile, message_id)\n\n    if emoji_code is None:\n        if emoji_name is None:\n            raise JsonableError(_('At least one of the following arguments '\n                                  'must be present: emoji_name, emoji_code'))\n        # A correct full Zulip client implementation should always\n        # pass an emoji_code, because of the corner cases discussed in\n        # the long block comments elsewhere in this file.  However, to\n        # make it easy for simple API clients to use the reactions API\n        # without needing the mapping between emoji names and codes,\n        # we allow instead passing the emoji_name and looking up the\n        # corresponding code using the current data.\n        emoji_code = emoji_name_to_emoji_code(message.sender.realm, emoji_name)[0]\n\n    if not Reaction.objects.filter(user_profile=user_profile,\n                                   message=message,\n                                   emoji_code=emoji_code,\n                                   reaction_type=reaction_type).exists():\n        raise JsonableError(_(\"Reaction doesn't exist.\"))\n\n    # Unlike adding reactions, while deleting a reaction, we don't\n    # check whether the provided (emoji_type, emoji_code) pair is\n    # valid in this realm.  Since there's a row in the database, we\n    # know it was valid when the user added their reaction in the\n    # first place, so it is safe to just remove the reaction if it\n    # exists.  And the (reaction_type, emoji_code) pair may no longer be\n    # valid in legitimate situations (e.g. if a realm emoji was\n    # deactivated by an administrator in the meantime).\n    do_remove_reaction(user_profile, message, emoji_code, reaction_type)\n\n    return json_success()\n", "path": "zerver/views/reactions.py"}]}