diff --git a/discord_rss_bot/custom_message.py b/discord_rss_bot/custom_message.py
new file mode 100644
index 0000000..c8f1441
--- /dev/null
+++ b/discord_rss_bot/custom_message.py
@@ -0,0 +1,95 @@
+from reader import Entry, Feed, Reader, TagNotFoundError
+
+from discord_rss_bot.settings import get_reader
+
+
+def try_to_replace(custom_message: str, template: str, replace_with: str) -> str:
+    """Try to replace a tag in custom_message.
+
+    Args:
+        custom_message: The custom_message to replace tags in.
+        feed: The feed to get the tags from.
+        entry: The entry to get the tags from.
+        tag: The tag to replace.
+
+    Returns:
+        Returns the custom_message with the tag replaced.
+    """
+    if not template:
+        return custom_message
+    if not replace_with:
+        return custom_message
+    try:
+        print(f"custom_message: {custom_message}")
+        print(f"template: {template}")
+        print(f"replace_with: {replace_with}")
+        return custom_message.replace(template, replace_with)
+    except TypeError:
+        return custom_message
+
+
+def replace_tags(feed: Feed, entry: Entry) -> str:
+    """Replace tags in custom_message.
+
+    Args:
+        feed: The feed to get the tags from.
+        entry: The entry to get the tags from.
+
+    Returns:
+        Returns the custom_message with the tags replaced.
+    """
+    custom_reader: Reader = get_reader()
+    custom_message: str = get_custom_message(feed=feed, custom_reader=custom_reader)
+
+    list_of_replacements = [
+        {"{{feed_author}}": feed.author},
+        {"{{feed_added}}": feed.added},
+        {"{{feed_last_exception}}": feed.last_exception},
+        {"{{feed_last_updated}}": feed.last_updated},
+        {"{{feed_link}}": feed.link},
+        {"{{feed_subtitle}}": feed.subtitle},
+        {"{{feed_title}}": feed.title},
+        {"{{feed_updated}}": feed.updated},
+        {"{{feed_updates_enabled}}": str(feed.updates_enabled)},
+        {"{{feed_url}}": feed.url},
+        {"{{feed_user_title}}": feed.user_title},
+        {"{{feed_version}}": feed.version},
+        {"{{entry_added}}": entry.added},
+        {"{{entry_author}}": entry.author},
+        {"{{entry_content}}": entry.content},
+        {"{{entry_id}}": entry.id},
+        {"{{entry_important}}": str(entry.important)},
+        {"{{entry_link}}": entry.link},
+        {"{{entry_published}}": entry.published},
+        {"{{entry_read}}": str(entry.read)},
+        {"{{entry_read_modified}}": entry.read_modified},
+        {"{{entry_summary}}": entry.summary},
+        {"{{entry_title}}": entry.title},
+        {"{{entry_updated}}": entry.updated},
+    ]
+
+    for replacement in list_of_replacements:
+        for template, replace_with in replacement.items():
+            custom_message: str = try_to_replace(custom_message, template, replace_with)
+
+    print(f"custom_message: {custom_message}")
+    return custom_message
+
+
+def get_custom_message(custom_reader: Reader, feed: Feed) -> str:
+    """Get custom_message tag from feed.
+
+    Args:
+        custom_reader: What Reader to use.
+        feed: The feed to get the tag from.
+
+    Returns:
+        Returns the contents from the custom_message tag.
+    """
+    try:
+        custom_message: str = custom_reader.get_tag(feed, "custom_message")  # type: ignore
+    except TagNotFoundError:
+        custom_message: str = ""
+    except ValueError:
+        custom_message: str = ""
+    return custom_message
diff --git a/discord_rss_bot/feeds.py b/discord_rss_bot/feeds.py
index c22cf56..e789772 100644
--- a/discord_rss_bot/feeds.py
+++ b/discord_rss_bot/feeds.py
@@ -4,10 +4,10 @@ from discord_webhook import DiscordWebhook
 from reader import Entry, Feed, Reader
 from requests import Response
 
-from discord_rss_bot import settings
+from discord_rss_bot import custom_message, settings
 from discord_rss_bot.filter.blacklist import should_be_skipped
-from discord_rss_bot.settings import get_reader
 from discord_rss_bot.filter.whitelist import has_white_tags, should_be_sent
+from discord_rss_bot.settings import get_reader
 
 
 def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = None, do_once: bool = False) -> None:
@@ -50,6 +50,11 @@ def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = Non
 
         webhook: DiscordWebhook = DiscordWebhook(url=webhook_url, content=webhook_message, rate_limit_retry=True)
 
+        if custom_message.get_custom_message(reader, entry.feed) != "":
+            print("Custom message found, replacing tags.")
+            webhook.content = custom_message.replace_tags(entry=entry, feed=entry.feed)
+
+        print(f"Webhook content: {webhook.content}")
         if feed is not None and has_white_tags(reader, feed):
             # Only send the entry if it is whitelisted, otherwise, mark it as read and continue.
             if should_be_sent(reader, entry):
diff --git a/discord_rss_bot/main.py b/discord_rss_bot/main.py
index f8663c5..c351501 100644
--- a/discord_rss_bot/main.py
+++ b/discord_rss_bot/main.py
@@ -12,6 +12,7 @@ from reader import Entry, EntryCounts, EntrySearchCounts, EntrySearchResult, Fee
 from starlette.responses import RedirectResponse
 
 from discord_rss_bot.custom_filters import encode_url, entry_is_blacklisted, entry_is_whitelisted
+from discord_rss_bot.custom_message import get_custom_message
 from discord_rss_bot.feeds import send_to_discord
 from discord_rss_bot.filter.blacklist import get_blacklist_content, get_blacklist_summary, get_blacklist_title
 from discord_rss_bot.filter.whitelist import get_whitelist_content, get_whitelist_summary, get_whitelist_title
@@ -115,6 +116,8 @@ async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()):
     """
     clean_feed_url: str = feed_url.strip()
 
+    # TODO: Check if the feed is valid, if not return an error or fix it.
+    # For example, if the feed is missing the protocol, add it.
     reader.add_feed(clean_feed_url)
     reader.update_feed(clean_feed_url)
 
@@ -304,6 +307,62 @@ async def get_blacklist(feed_url: str, request: Request):
     return templates.TemplateResponse("blacklist.html", context)  # type: ignore
 
 
+@app.post("/custom")
+async def set_custom(custom_message: str = Form(""), feed_url: str = Form()):
+    """
+    Set the custom message, this is used when sending the message.
+
+    Args:
+        custom_message: The custom message.
+        feed_url: The feed we should set the custom message for.
+
+        Returns:
+            Redirect to the feed.
+    """
+
+    # Add the custom_message to the feed.
+    if custom_message:
+        reader.set_tag(feed_url, "custom_message", custom_message)
+        print(f"Set custom message for {feed_url} to {custom_message}")
+    else:
+        print(f"Removing custom message for {feed_url}")
+        reader.delete_tag(feed_url, "custom_message", missing_ok=True)
+
+    # Clean URL is used to redirect to the feed page.
+    clean_url: str = urllib.parse.quote(feed_url)
+
+    return RedirectResponse(url=f"/feed/?feed_url={clean_url}", status_code=303)
+
+
+@app.get("/custom", response_class=HTMLResponse)
+async def get_custom(feed_url: str, request: Request):
+    """Get the custom message. This is used when sending the message to Discord.
+
+    Args:
+        feed_url: What feed we should get the custom message for.
+        request: The HTTP request.
+
+    Returns:
+        custom.html
+    """
+
+    # Make feed_url a valid URL.
+    url: str = urllib.parse.unquote(feed_url)
+
+    feed: Feed = reader.get_feed(url)
+
+    # Get previous data, this is used when creating the form.
+    custom_message: str = get_custom_message(reader, feed)
+
+    # Get the first entry, this is used to show the user what the custom message will look like.
+    first_entry: Entry = reader.get_entries(feed=feed, limit=1)
+    for entry in first_entry:
+        first_entry = entry
+
+    context = {"request": request, "feed": feed, "custom_message": custom_message, "entry": first_entry}
+    return templates.TemplateResponse("custom.html", context)  # type: ignore
+
+
 @app.get("/add", response_class=HTMLResponse)
 def get_add(request: Request):
     """
diff --git a/discord_rss_bot/templates/custom.html b/discord_rss_bot/templates/custom.html
new file mode 100644
index 0000000..e88d5a8
--- /dev/null
+++ b/discord_rss_bot/templates/custom.html
@@ -0,0 +1,70 @@
+{% extends "base.html" %}(
+{% block title %} | Custom message{% endblock %}
+{% block content %}
+    <div class="p-2 border border-dark">
+        <form action="/custom" method="post">
+            <!-- Feed URL -->
+            <div class="row pb-2">
+
+                <div class="col-sm-12">
+                    <div class="form-text">
+                        <ul class="list-inline">
+                            <li>You can modify the message that is sent to Discord.</li>
+                            <br>
+                            <li><code>{% raw %}{{feed_url}}{% endraw %}</code> will be replaced with the feed URL. You can use <code>\n</code> for new lines.</li>
+                            <br>
+                            <li><code>{% raw %}{{feed_author}}{% endraw %}</code> - {{feed.author}}</li>
+                            <li><code>{% raw %}{{feed_added}}{% endraw %}</code> - {{feed.added}}</li>
+                            <li><code>{% raw %}{{feed_last_exception}}{% endraw %}</code> - {{feed.last_exception}}</li>
+                            <li><code>{% raw %}{{feed_last_updated}}{% endraw %}</code> - {{feed.last_updated}}</li>
+                            <li><code>{% raw %}{{feed_link}}{% endraw %}</code> - {{feed.link}}</li>
+                            <li><code>{% raw %}{{feed_subtitle}}{% endraw %}</code> - {{feed.subtitle}}</li>
+                            <li><code>{% raw %}{{feed_title}}{% endraw %}</code> - {{feed.title}}</li>
+                            <li><code>{% raw %}{{feed_updated}}{% endraw %}</code> - {{feed.updated}}</li>
+                            <li><code>{% raw %}{{feed_updates_enabled}}{% endraw %}</code> - {{feed.updates_enabled}}</li>
+                            <li><code>{% raw %}{{feed_url}}{% endraw %}</code> - {{feed.url}}</li>
+                            <li><code>{% raw %}{{feed_user_title}}{% endraw %}</code> - {{feed.user_title}}</li>
+                            <li><code>{% raw %}{{feed_version}}{% endraw %}</code> - {{feed.version}}</li>
+                            <br>
+                            <li><code>{% raw %}{{entry_added}}{% endraw %}</code> - {{entry.added}}</li>
+                            <li><code>{% raw %}{{entry_author}}{% endraw %}</code> - {{entry.author}}</li>
+                            <li><code>{% raw %}{{entry_content}}{% endraw %}</code> - {{entry.content[0].value}}</li>
+                            <li><code>{% raw %}{{entry_id}}{% endraw %}</code> - {{entry.id}}</li>
+                            <li><code>{% raw %}{{entry_important}}{% endraw %}</code> - {{entry.important}}</li>
+                            <li><code>{% raw %}{{entry_link}}{% endraw %}</code> - {{entry.link}}</li>
+                            <li><code>{% raw %}{{entry_published}}{% endraw %}</code> - {{entry.published}}</li>
+                            <li><code>{% raw %}{{entry_read}}{% endraw %}</code> - {{entry.read}}</li>
+                            <li><code>{% raw %}{{entry_read_modified}}{% endraw %}</code> - {{entry.read_modified}}</li>
+                            <li><code>{% raw %}{{entry_summary}}{% endraw %}</code> - {{entry.summary}}</li>
+                            <li><code>{% raw %}{{entry_title}}{% endraw %}</code> - {{entry.title}}</li>
+                            <li><code>{% raw %}{{entry_updated}}{% endraw %}</code> - {{entry.updated}}</li>
+                        </ul>
+                        <ul class="list-inline">
+                            <li>Examples:</li>
+                            <li><code>{% raw %}Hello {{entry_author}}\n{{feed_title}}\n{{entry_read}}{% endraw %}</code></li> 
+                            <br>
+                            <li>Will become:</li>
+                            <li><code style="white-space: pre-line">
+                                Hello {{entry.author}}
+                                {{feed.title}} 
+                                {{entry.read}}
+                            </code></li>
+                        </ul>
+                    </div>
+
+                    <label for="custom_message" class="col-sm-6 col-form-label">Message</label>
+                    <input name="custom_message" type="text" class="form-control bg-dark border-dark text-muted"
+                           id="custom_message" value="{% if custom_message %}{{ custom_message }}{% endif %}">
+                </div>
+            </div>
+
+            <!-- Add a hidden feed_url field to the form -->
+            <input type="hidden" name="feed_url" value="{{ feed.url }}">
+
+            <!-- Submit button -->
+            <div class="d-md-flex">
+                <button class="btn btn-dark btn-sm">Update message</button>
+            </div>
+        </form>
+    </div>
+{% endblock %}
\ No newline at end of file
diff --git a/discord_rss_bot/templates/feed.html b/discord_rss_bot/templates/feed.html
index f5fee11..48efc1f 100644
--- a/discord_rss_bot/templates/feed.html
+++ b/discord_rss_bot/templates/feed.html
@@ -26,6 +26,7 @@
         {% endif %}
         <a class="text-muted" href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a>
         <a class="text-muted" href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a>
+        <a class="text-muted" href="/custom?feed_url={{ feed.url|encode_url }}">Custom message</a>
 
     </div>
     {% for entry in entries %}
@@ -46,7 +47,8 @@
             {% if entry.published %}
                 @ {{ entry.published.strftime('%Y-%m-%d, %T') }}
             {% endif %}
-
+            
+            {# TODO: Only show one if both are the same #}
             {% if entry.summary %}
                 <details>
                     <summary>Summary</summary>