# discord-ext-track-edits
A [discord.py](https://github.com/Rapptz/discord.py) extension that implements
edit tracking for prefix commands, inspired by [poise](https://github.com/serenity-rs/poise):
- When user edits their message, automatically update bot response
- When user deletes their message, automatically delete corresponding
bot response, if it exists.
## Usage
The extension contains an `EditTrackerCog` and an `EditTrackableContext`. They must
be used together for edit tracking to work.
Responses will be tracked only when you explicitly `.reply()` to the invocation message.
```python
from datetime import timedelta
from typing import Type, Union
from typing_extensions import override
import discord
from discord.ext import commands
from discord.ext.track_edits import EditTrackerCog, EditTrackableContext
class Bot(commands.Bot):
async def setup_hook(self) -> None:
await self.add_cog(
EditTrackerCog(
self,
max_duration=timedelta(minutes=5),
execute_untracked_edits=True,
ignore_edits_if_not_yet_responded=False,
),
)
@override
async def get_context(
self,
origin: Union[discord.Message, discord.Interaction],
*,
cls: Type[EditTrackableContext] = EditTrackableContext,
) -> EditTrackableContext:
return await super().get_context(origin, cls=cls)
# your usual bot setup code here
```
## Cog options
- `max_duration`: How long to track bot responses for. If set to `None`, bot
responses will be tracked indefinitely until the process is shut down.
(default: 5 minutes)
- `execute_untracked_edits`: Whether to execute a command that was previously
untracked, for example, when the user makes a typo and edits it into a valid
invocation. (default: `True`)
- `ignore_edits_if_not_yet_responded`: Whether to ignore edits on messages
that have not been responded to. This happens if the edits happens before the
command has sent a response, or if the command does not respond at all.
(default: `False`)
## Command options
Command options are supplied through the `extras` dictionary:
```python
@commands.command(extras={"invoke_on_edit": False})
async def cmd(ctx):
...
```
- `invoke_on_edit`: Whether to rerun the command if an existing invocation
message is edited (default: `True`)
- `track_deletion`: Whether to delete the bot response if an existing invocation
message is deleted (default: `True`)
- `reuse_response`: Whether to post subsequent responses as edits to the original
response (default: `True`)
Raw data
{
"_id": null,
"home_page": null,
"name": "discord-ext-track-edits",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "discord, edit tracking, extension, discord-ext",
"author": "beerpsi",
"author_email": "beerpsi <beerpsi@duck.com>",
"download_url": "https://files.pythonhosted.org/packages/f8/b4/57667590a515544527c763c1436a8570d563ddd0e0c047fddab00a9ed92c/discord_ext_track_edits-0.1.2.tar.gz",
"platform": null,
"description": "# discord-ext-track-edits\n\nA [discord.py](https://github.com/Rapptz/discord.py) extension that implements\nedit tracking for prefix commands, inspired by [poise](https://github.com/serenity-rs/poise):\n- When user edits their message, automatically update bot response\n- When user deletes their message, automatically delete corresponding\nbot response, if it exists.\n\n## Usage\n\nThe extension contains an `EditTrackerCog` and an `EditTrackableContext`. They must\nbe used together for edit tracking to work.\n\nResponses will be tracked only when you explicitly `.reply()` to the invocation message.\n\n```python\nfrom datetime import timedelta\nfrom typing import Type, Union\nfrom typing_extensions import override\n\nimport discord\nfrom discord.ext import commands\nfrom discord.ext.track_edits import EditTrackerCog, EditTrackableContext\n\nclass Bot(commands.Bot):\n async def setup_hook(self) -> None:\n await self.add_cog(\n EditTrackerCog(\n self,\n max_duration=timedelta(minutes=5),\n execute_untracked_edits=True,\n ignore_edits_if_not_yet_responded=False,\n ),\n )\n\n @override\n async def get_context(\n self,\n origin: Union[discord.Message, discord.Interaction],\n *,\n cls: Type[EditTrackableContext] = EditTrackableContext,\n ) -> EditTrackableContext:\n return await super().get_context(origin, cls=cls)\n\n# your usual bot setup code here\n```\n\n## Cog options\n- `max_duration`: How long to track bot responses for. If set to `None`, bot\nresponses will be tracked indefinitely until the process is shut down.\n(default: 5 minutes)\n- `execute_untracked_edits`: Whether to execute a command that was previously\nuntracked, for example, when the user makes a typo and edits it into a valid\ninvocation. (default: `True`)\n- `ignore_edits_if_not_yet_responded`: Whether to ignore edits on messages\nthat have not been responded to. This happens if the edits happens before the\ncommand has sent a response, or if the command does not respond at all.\n(default: `False`)\n\n## Command options\nCommand options are supplied through the `extras` dictionary:\n\n```python\n@commands.command(extras={\"invoke_on_edit\": False})\nasync def cmd(ctx):\n ...\n```\n\n- `invoke_on_edit`: Whether to rerun the command if an existing invocation\nmessage is edited (default: `True`)\n- `track_deletion`: Whether to delete the bot response if an existing invocation\nmessage is deleted (default: `True`)\n- `reuse_response`: Whether to post subsequent responses as edits to the original\nresponse (default: `True`)\n",
"bugtrack_url": null,
"license": null,
"summary": "A discord.py extension for automatic edit tracking",
"version": "0.1.2",
"project_urls": {
"Homepage": "https://github.com/beer-psi/discord-ext-track-edits",
"Issues": "https://github.com/beer-psi/discord-ext-track-edits/issues",
"Repository": "https://github.com/beer-psi/discord-ext-track-edits.git"
},
"split_keywords": [
"discord",
" edit tracking",
" extension",
" discord-ext"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c8fbfaca49c9840cd34b24b7c5e3770ea224b8f30b8893ddb70bbedf4141baec",
"md5": "a151c6de4270adb2bf2a00d313b36f59",
"sha256": "7cbee63305fa9706d301acc0f9c91680a547ea1898347222ed61b99393c332e2"
},
"downloads": -1,
"filename": "discord_ext_track_edits-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a151c6de4270adb2bf2a00d313b36f59",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 7990,
"upload_time": "2025-07-31T17:54:35",
"upload_time_iso_8601": "2025-07-31T17:54:35.383136Z",
"url": "https://files.pythonhosted.org/packages/c8/fb/faca49c9840cd34b24b7c5e3770ea224b8f30b8893ddb70bbedf4141baec/discord_ext_track_edits-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f8b457667590a515544527c763c1436a8570d563ddd0e0c047fddab00a9ed92c",
"md5": "77daa07ec90251fca86687157c2b17c2",
"sha256": "d18094719026573b00a5ea0d001ed846f42ade50232cd05fbdf97ca8de7abbb6"
},
"downloads": -1,
"filename": "discord_ext_track_edits-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "77daa07ec90251fca86687157c2b17c2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 6565,
"upload_time": "2025-07-31T17:54:37",
"upload_time_iso_8601": "2025-07-31T17:54:37.378183Z",
"url": "https://files.pythonhosted.org/packages/f8/b4/57667590a515544527c763c1436a8570d563ddd0e0c047fddab00a9ed92c/discord_ext_track_edits-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-31 17:54:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "beer-psi",
"github_project": "discord-ext-track-edits",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "discord-ext-track-edits"
}