diff --git a/README.md b/README.md
index ff48c2979c1c0c91025981b389211a3ac4ce9552..c81a04249273efada791fa48e6531f42730f36e5 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,7 @@ Přes CRON je třeba na pozadí spouštět Django `manage.py` commandy:
 * `publish_scheduled_pages` - publikuje naplánované stránky (každou hodinu)
 * `update_callendars` - stáhne a aktualizuje kalendáře (několikrát denně)
 * `update_main_timeline_articles` - aktualizuje články na `pirati.cz` z `https://piratipracuji.cz/api/`
+* `update_mastodon_feed` - aktualizuje tooty podle nastavení na různých aplikacích
 * `update_redmine_issues` - aktualizuje programované body MS a KS stránek napojených na Redmine (několikrát denně)
 * `update_tweets` - aktualizuje tweety podle nastavení na Homepage pirati.cz - vyžaduje mít v .env TWITTER_BEARER_TOKEN, parametr --days určuje stáří tweetů (default 1)
 * `update_instagram` - aktualizuje Instagramové posty na Homepage pirati.cz - vyžaduje mít v .env `INSTAGRAM_APP_ID` a `INSTAGRAM_APP_SECRET`.
diff --git a/shared/management/comands/update_mastodon_feed.py b/shared/management/comands/update_mastodon_feed.py
new file mode 100644
index 0000000000000000000000000000000000000000..ed66096baef302fe4e972d1378b76173131c3127
--- /dev/null
+++ b/shared/management/comands/update_mastodon_feed.py
@@ -0,0 +1,11 @@
+from django.core.management.base import BaseCommand
+
+from shared.services import MastodonFeedDownloadService
+
+
+class Command(BaseCommand):
+    def handle(self, *args, **options):
+        ads = MastodonFeedDownloadService()
+        ads.perform_update()
+
+        self.stdout.write("\nUpdate of mastodon finished!")
diff --git a/shared/models.py b/shared/models.py
index bb652dfd77351d0fc132dc7b3e12daf87e73138e..99fd4165964e2d8ba83dc9c825ce96f015599243 100644
--- a/shared/models.py
+++ b/shared/models.py
@@ -1,5 +1,5 @@
+import hashlib
 import logging
-from time import time
 
 from attr import dataclass
 from django.core.files.temp import NamedTemporaryFile
@@ -15,15 +15,12 @@ from wagtail.models import Page
 from shared.blocks import (
     DEFAULT_CONTENT_BLOCKS,
     FooterLinksBlock,
-    ImageCreatorMixin,
     MenuItemBlock,
     MenuParentBlock,
 )
 
 logger = logging.getLogger(__name__)
 
-FIVE_MINUTES_IN_SECONDS = 300
-
 
 @dataclass
 class MastodonImage:
@@ -66,12 +63,26 @@ class MastodonUser:
     preferredUsername: str
 
 
-class Mastodon(ImageCreatorMixin, models.Model):
+class MastodonImageMixin(models.Model):
+    image = models.ImageField(null=True, blank=True, upload_to="mastodon/")
+
+    def download_image(self, url, name):
+        response = request("GET", url, stream=True)
+        response.raw.decode_content = True
+        # Taken from: https://gist.github.com/anderser/2172888
+        temporary_stored_image = NamedTemporaryFile(delete=True)
+        temporary_stored_image.write(response.content)
+        temporary_stored_image.flush()
+        self.image.save(name, temporary_stored_image)
+
+    class Meta:
+        abstract = True
+
+
+class Mastodon(MastodonImageMixin, models.Model):
     url = models.URLField()
     toots = models.JSONField(encoder=DjangoJSONEncoder, null=True)
     summary = models.TextField(null=True, blank=True)
-    user_image = models.ImageField(null=True, blank=True, upload_to="mastodon_users/")
-    timestamp = models.FloatField()
 
     def download_toots(self):
         """
@@ -89,31 +100,41 @@ class Mastodon(ImageCreatorMixin, models.Model):
         full_url = self.url + ".json"
         return request("GET", full_url).json()
 
-    def parse_url(self, now: float):
+    def parse_url(self):
         toots: MastodonToots = self.download_toots()
         user: MastodonUser = self.download_user()
 
-        # Taken from: https://gist.github.com/anderser/2172888
-        temporary_stored_image = NamedTemporaryFile(delete=True)
-        temporary_stored_image.write(user.icon.url)
-        temporary_stored_image.flush()
-        self.user_image.save(f"{user.preferredUsername}.jpg", temporary_stored_image)
+        self.download_image(f"{user.preferredUsername}.jpg", user["icon"]["url"])
+
+        for toot in toots["orderedItems"]:
+            if toot["attachment"] != None:
+                for attachment in toot["attachment"]:
+                    mastodon_attachment: MastodonAttachment = (
+                        MastodonAttachment.objects.create(mastodon=self)
+                    )
+                    mastodon_attachment.download_image(
+                        attachment["url"],
+                        hashlib.md5(attachment["url"].encode("ascii")).hexdigest(),
+                    )
+                    attachment["url"] = mastodon_attachment.image.url
 
         self.toots = toots.orderedItems
         self.summary = user.summary
-        self.timestamp = now
 
     def refresh_toots(self):
-        now = time()
-        if self.timestamp != None and now - self.timestamp < FIVE_MINUTES_IN_SECONDS:
-            return
         try:
-            self.parse_url(now)
+            self.parse_url()
             self.save()
         except:
             logger.error("Mastodon refresh failed for %s", self.url, exc_info=True)
 
 
+class MastodonAttachment(MastodonImageMixin, models.Model):
+    mastodon = models.ForeignKey(
+        Mastodon, null=True, blank=True, on_delete=models.PROTECT
+    )
+
+
 class MastodonFeedMixin(models.Model):
     mastodon_feed = models.URLField(
         verbose_name="Mastodon feed",
@@ -132,7 +153,7 @@ class MastodonFeedMixin(models.Model):
                 if self.mastodon is not None
                 else Mastodon.objects.create(url=self.calendar_url)
             )
-            mastodon.parse_url(time())
+            mastodon.parse_url()
         except:
             raise ValidationError("Update mastodonu se nepovedl")
 
diff --git a/shared/services.py b/shared/services.py
new file mode 100644
index 0000000000000000000000000000000000000000..533439504f595b7621ffada83d4764e45038027a
--- /dev/null
+++ b/shared/services.py
@@ -0,0 +1,15 @@
+import logging
+from typing import TYPE_CHECKING
+
+from shared.models import Mastodon
+
+if TYPE_CHECKING:
+    pass
+
+logger = logging.getLogger()
+
+
+class MastodonFeedDownloadService:
+    def perform_update(self):
+        for mastodon in Mastodon.objects.all():
+            mastodon.refresh_toots()