Skip to content

Commit f648be1

Browse files
committed
til: sync steamdeck screenshots to immich
1 parent a042bf5 commit f648be1

File tree

3 files changed

+138
-2
lines changed

3 files changed

+138
-2
lines changed

content/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-google-drive/index.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,5 @@ Finally I booted back into Game mode, took a screenshot there as well with `Stea
119119

120120
Success!
121121

122-
*Update 2023-02-19*: There is now also a [TIL on how to do the same for Google Photos](/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-google-photos/).
122+
*Update 2023-02-19*: There is now also a [TIL on how to do the same for Google Photos](/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-google-photos/).
123+
*Update 2025-03-25*: And now there's also a [TIL on how to do the same for Immich](/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-immich/).

content/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-google-photos.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ REMOTE_DIR='album/Steamdeck'
3737

3838
That was all.
3939

40-
Obviously the same can be done with any of the other sync targets that `rclone` supports, of which [there are many](https://rclone.org/overview/). For ownCloud or NextCloud it looks like [WebDAV](https://rclone.org/webdav/) is the right option to choose.
40+
Obviously the same can be done with any of the other sync targets that `rclone` supports, of which [there are many](https://rclone.org/overview/). For ownCloud or NextCloud it looks like [WebDAV](https://rclone.org/webdav/) is the right option to choose.
41+
42+
*Update 2025-03-25*: There's now also a [TIL on how to do the same for Immich](/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-immich/).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
title: "How to automatically sync screenshots from the Steamdeck to Immich"
3+
date: 2025-03-25
4+
tags:
5+
- steamdeck
6+
- immich
7+
- bash
8+
- linux
9+
---
10+
11+
As part of [my ongoing effort to reduce my dependency on US services](https://chaos.social/@foosel/114105591362840338), I just moved my photos
12+
from Google Photos to a self-hosted [immich](https://immich.app/) instance (which I btw can only recommend so far).
13+
14+
You might remember from [a previous TIL](/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-google-photos/)
15+
that I had my Steamdeck configured to push my screenshots into a custom album on Google Photos. Obviously I had to change that now as well,
16+
but sadly couldn't use the existing [rclone](https://rclone.org/)-based setup for it.
17+
18+
My first idea was to utilize [immich-go](https://github.com/simulot/immich-go), as I have just successfully used that for the
19+
three day long import of over 50000 pictures from my Google Photos takeout into immich. But that turned out to not be the right tool here: in order to not even try to
20+
upload already existing files it will fetch an asset list from immich first, and while that really improves performance for large batch imports,
21+
it takes way too long for uploading a single new screenshot.
22+
23+
So instead I went with something self-built which utilizes [immich's API](https://immich.app/docs/api/).
24+
25+
## A custom upload script
26+
27+
The first part is this little bash script that will take a file as input, upload it to a pre-configured immich instance and also add it to a
28+
pre-defined album (which already has to exist). This lives in `~/.local/bin/immich-upload.sh`:
29+
30+
``` bash
31+
#!/bin/bash
32+
set -e
33+
34+
IMMICH_SERVER="https://immich.example.com"
35+
IMMICH_KEY="your api key goes here"
36+
IMMICH_ALBUM="your album id goes here"
37+
38+
INPUT="$1"
39+
if [ "$INPUT" == "" ]; then
40+
echo "immich-upload.sh <file>"
41+
exit 0
42+
fi
43+
44+
file_modified=$(stat -c %Y "$INPUT" | date --iso-8601=seconds)
45+
name=$(basename "$INPUT")
46+
47+
# ---
48+
49+
echo "Uploading $INPUT to immich..."
50+
51+
upload=$(curl -sL --request POST "$IMMICH_SERVER/api/assets" \
52+
-H "Content-Type: multipart/form-data" \
53+
-H "Accept: application/json" \
54+
-H "X-API-Key: $IMMICH_KEY" \
55+
-F "deviceId=\"curl/steamdeck\"" \
56+
-F "deviceAssetId=\"$name-$file_modified\"" \
57+
-F "fileCreatedAt=\"$file_modified\"" \
58+
-F "fileModifiedAt=\"$file_modified\"" \
59+
-F "assetData=@\"$INPUT\"")
60+
61+
id=$(echo "$upload" | jq -r .id)
62+
63+
echo "Uploaded file, asset id is $id"
64+
65+
# ---
66+
67+
echo "Adding file to album $IMMICH_ALBUM..."
68+
69+
payload=$(jq -n --arg id $id '{ids:[$ARGS.named.id]}')
70+
album=$(curl -sL --request PUT "$IMMICH_SERVER/api/albums/$IMMICH_ALBUM/assets" \
71+
-H "Content-Type: application/json" \
72+
-H "Accept: application/json" \
73+
-H "X-API-Key: $IMMICH_KEY" \
74+
-d "$payload")
75+
76+
echo "... done"
77+
```
78+
79+
## Reacting to new screenshots
80+
81+
I use [watchexec](https://github.com/watchexec/watchexec) to listen for changes in my custom screenshot folder
82+
([see this TIL post on how to set that up](/til/how-to-automatically-sync-screenshots-from-the-steamdeck-to-google-photos/))
83+
and calling the upload script with the correct file name. I downloaded a release build of `watchexec` and threw it into `~/.local/bin`, then created another
84+
script `~/.local/bin/sync-screenshots` that takes care of setting all of the correct parameters[^1]:
85+
86+
``` bash
87+
#!/usr/bin/env bash
88+
89+
WATCHEXEC="${HOME}/.local/bin/watchexec"
90+
FOLDER="${HOME}/.steam_screenshots"
91+
92+
${WATCHEXEC} --exts jpg,png,mp4 --fs-events create --emit-events-to environment -w $FOLDER -o queue -p -v -- '/home/deck/.local/bin/immich-upload.sh "$WATCHEXEC_COMMON_PATH/$WATCHEXEC_CREATED_PATH"'
93+
```
94+
95+
## Putting it all together
96+
97+
Finally, a new systemd unit in `~/.config/systemd/user/sync-screenshots.service` takes care of starting this bash script and keeping it running:
98+
99+
```
100+
[Unit]
101+
Description=Sync Steam Screenshots
102+
103+
[Service]
104+
ExecStart=%h/.local/bin/sync-screenshots
105+
Restart=on-failure
106+
RestartSec=5
107+
108+
[Install]
109+
WantedBy=default.target
110+
```
111+
112+
I enabled and started that:
113+
114+
``` bash
115+
systemctl --user enable sync-screenshots
116+
systemctl --user start sync-screenshots
117+
```
118+
119+
Then I took a screenshot and confirmed that the script had run:
120+
121+
```
122+
Mar 25 15:17:03 steamdeck sync_screenshots[77135]: [Running: /home/deck/.local/bin/immich-upload.sh "$WATCHEXEC_COMMON_PATH/$WATCHEXEC_CREATED_PATH"]
123+
Mar 25 15:17:03 steamdeck sync_screenshots[77188]: Uploading /home/deck/.steam_screenshots/7_20250325151703_1.png to immich...
124+
Mar 25 15:17:04 steamdeck sync_screenshots[77188]: Uploaded file, asset id is 141dc605-edef-48f1-83b5-00bd9d72b13e
125+
Mar 25 15:17:04 steamdeck sync_screenshots[77188]: Adding file to album 0ce35e68-a564-4e26-921e-c486cd9e4725...
126+
Mar 25 15:17:05 steamdeck sync_screenshots[77188]: ... done
127+
Mar 25 15:17:05 steamdeck sync_screenshots[77135]: [Command was successful]
128+
```
129+
130+
And indeed, upon checking my immich instance, I was also looking at the freshly uploaded screenshot. Mission accomplished!
131+
132+
[^1]: It's currently reacting to newly added `jpg`, `png` or `mp4` files. The latter is in preparation of hopefully another toolchain to automatically convert clips from
133+
[Steam's game recorder](https://store.steampowered.com/gamerecording) that will automatically push its results into the screenshot folder as well, but that's only an idea for now.

0 commit comments

Comments
 (0)