prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [announce] Send confirmation to caller after all channels announced
  When Sopel is in many channels, announces are likely to be rate-limited. This makes it hard to know, for example, when it's safe to shut down the bot if announce is being used to broadcast an upgrade notice.
  
  It's an easy fix, and I'll open a PR for it tomorrow if there are no objections.
  
  I am as-yet undecided whether it's best to use `bot.reply()` or `bot.notice()` for this (or even `bot.msg()` via PM to the caller), but I'll think about it between now and when I open the PR, and it can always be changed before merging.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `sopel/modules/announce.py`
  Content:
  ```
  1 # coding=utf-8
  2 """
  3 announce.py - Send a message to all channels
  4 Copyright © 2013, Elad Alfassa, <elad@fedoraproject.org>
  5 Licensed under the Eiffel Forum License 2.
  6 
  7 """
  8 from __future__ import unicode_literals, absolute_import, print_function, division
  9 
  10 from sopel.module import commands, example
  11 
  12 
  13 @commands('announce')
  14 @example('.announce Some important message here')
  15 def announce(bot, trigger):
  16     """
  17     Send an announcement to all channels the bot is in
  18     """
  19     if not trigger.admin:
  20         bot.reply('Sorry, I can\'t let you do that')
  21         return
  22     for channel in bot.channels:
  23         bot.msg(channel, '[ANNOUNCEMENT] %s' % trigger.group(2))
  24
  ```
  --- 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/sopel/modules/announce.py b/sopel/modules/announce.py
  --- a/sopel/modules/announce.py
  +++ b/sopel/modules/announce.py
  @@ -21,3 +21,4 @@
           return
       for channel in bot.channels:
           bot.msg(channel, '[ANNOUNCEMENT] %s' % trigger.group(2))
  +    bot.reply('Announce complete.')
  
verification_info: {"golden_diff": "diff --git a/sopel/modules/announce.py b/sopel/modules/announce.py\n--- a/sopel/modules/announce.py\n+++ b/sopel/modules/announce.py\n@@ -21,3 +21,4 @@\n         return\n     for channel in bot.channels:\n         bot.msg(channel, '[ANNOUNCEMENT] %s' % trigger.group(2))\n+    bot.reply('Announce complete.')\n", "issue": "[announce] Send confirmation to caller after all channels announced\nWhen Sopel is in many channels, announces are likely to be rate-limited. This makes it hard to know, for example, when it's safe to shut down the bot if announce is being used to broadcast an upgrade notice.\n\nIt's an easy fix, and I'll open a PR for it tomorrow if there are no objections.\n\nI am as-yet undecided whether it's best to use `bot.reply()` or `bot.notice()` for this (or even `bot.msg()` via PM to the caller), but I'll think about it between now and when I open the PR, and it can always be changed before merging.\n\n", "before_files": [{"content": "# coding=utf-8\n\"\"\"\nannounce.py - Send a message to all channels\nCopyright \u00a9 2013, Elad Alfassa, <elad@fedoraproject.org>\nLicensed under the Eiffel Forum License 2.\n\n\"\"\"\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nfrom sopel.module import commands, example\n\n\n@commands('announce')\n@example('.announce Some important message here')\ndef announce(bot, trigger):\n    \"\"\"\n    Send an announcement to all channels the bot is in\n    \"\"\"\n    if not trigger.admin:\n        bot.reply('Sorry, I can\\'t let you do that')\n        return\n    for channel in bot.channels:\n        bot.msg(channel, '[ANNOUNCEMENT] %s' % trigger.group(2))\n", "path": "sopel/modules/announce.py"}], "after_files": [{"content": "# coding=utf-8\n\"\"\"\nannounce.py - Send a message to all channels\nCopyright \u00a9 2013, Elad Alfassa, <elad@fedoraproject.org>\nLicensed under the Eiffel Forum License 2.\n\n\"\"\"\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nfrom sopel.module import commands, example\n\n\n@commands('announce')\n@example('.announce Some important message here')\ndef announce(bot, trigger):\n    \"\"\"\n    Send an announcement to all channels the bot is in\n    \"\"\"\n    if not trigger.admin:\n        bot.reply('Sorry, I can\\'t let you do that')\n        return\n    for channel in bot.channels:\n        bot.msg(channel, '[ANNOUNCEMENT] %s' % trigger.group(2))\n    bot.reply('Announce complete.')\n", "path": "sopel/modules/announce.py"}]}