Skip to content

Instantly share code, notes, and snippets.

@marco79cgn
Last active September 24, 2023 11:25
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marco79cgn/1184e77b39fdf7ba510ac8650afe0674 to your computer and use it in GitHub Desktop.
Save marco79cgn/1184e77b39fdf7ba510ac8650afe0674 to your computer and use it in GitHub Desktop.
Bash script that checks whether an Apple product is available for pickup at your nearest Apple Store and sends a push notification if it gets available again (via ntfy.sh)
#!/bin/bash
partNo=$1
storeId=$2
notifyUrl=https://ntfy.sh/$3
FILE=$4/${partNo/\//-}-$storeId
if [ ! -f "$FILE" ]; then
echo "$FILE does not exist."
echo -n "1" > $FILE
fi
productName=""
function curlItem {
apiResult=$(/usr/bin/curl -s "https://www.apple.com/de/shop/fulfillment-messages?store=${storeId}&little=false&parts.0=${partNo}&purchaseOption=fullPrice&mts.0=regular&mts.1=sticky&fts=true")
productName=$(echo -n ${apiResult} | jq -r ".body.content.pickupMessage.stores[0].partsAvailability.\"${partNo}\".messageTypes.regular.storePickupProductTitle")
storeAvailability=$(echo -n ${apiResult} | jq -r ".body.content.pickupMessage.stores[0].partsAvailability.\"${partNo}\".pickupDisplay" | grep -i -w "available" | wc -l)
printf "Store ${storeId}: ${storeAvailability}"
if [ "$storeAvailability" -eq "1" ]; then
previousState=$(<$FILE)
if [[ "$previousState" == 0 ]]; then
sendPush
echo -n "1" > $FILE
exit
fi
else
echo -n "0" > $FILE
fi
}
function sendPush {
result=$(/usr/bin/curl -s -X POST -H "Title: Apple Store" -H "Click: https://store.apple.com/de/xc/product/$partNo" -H "Tags: apple" -d "${productName} ist jetzt verfügbar! (Tap to order)" $notifyUrl)
}
responsedata=$(curlItem)
echo $responsedata
@marco79cgn
Copy link
Author

marco79cgn commented Oct 19, 2021

UPDATE: 24.09.2023
The script is now completely universal and doesn't have to be edited anymore. It works with any given apple product id (→ partNo). The script checks the availability and persists the current state in a file. As soon as a product was unavailable before and gets purchasable again, the script will send a push notification.

Setup

  • copy the script and paste it into a file, e.g. iphone-availability.sh
  • make the file executable: chmod +x iphone-availability.sh
  • install the notify app and create a new topic for your notifications. choose a unique topic name, something like "my-secret-apple-alerts-395920" and subscribe to it (be aware that everyone who knows the topic name can write on it!)
  • create a temp folder where the previous state will be stored (e.g. /Users/marco/dev/temp)
  • run the script in your Terminal/Shell/Bash providing four parameters:
    1. Apple partNo (e.g. MU7A3ZD/A)
    2. Store ID (like R559 for Apple Store Köln Schildergasse)
    3. ntfy topic name
    4. temp folder
      ./iphone-availability.sh "MU7A3ZD/A" "R559" "my-secret-apple-alerts-395920" "/Users/marco/dev/temp"
  • optional: run the script e.g. every 2 minutes via crontab
    */2 * * * * /bin/bash /home/pi/scripts/iphone-availability.sh "MU7A3ZD/A" "R559" "my-secret-apple-alerts-395920" "/Users/marco/dev/temp" &>/dev/null &

That's it. You'll receive a push notification every time a product was out of stock and then gets purchasable again. Once you click on the push notification on your iOS device, you will be redirected to the Apple Store directly.

Store IDs

R559 → Köln Schildergasse
R520 → Köln Rheincenter
R331 → Düsseldorf
R403 → Centro Oberhausen
R434 → Sulzbach MTZ
R352 → Frankfurt (Große Bockenheimer Straße)
R455 → Hannover
R519 → Sindelfingen
R396 → Hamburg Jungfernstieg
R366 → Hamburg Alstertal
R431 → Augsburg City Galerie
R521 → München OEZ
R045 → München Rosenstraße
R430 → Dresden Altmarkt-Galerie
R358 → Berlin Kurfürstendamm

Product IDs (aka partNo)

iPhone 15 Pro (Titan):
Natur 128 GB → MTUX3ZD/A
Natur 256 GB → MTV53ZD/A
Natur 512 GB → MTV93ZD/A
Natur 1 TB → MTVF3ZD/A
Blau 128 GB → MTV03ZD/A
Blau 256 GB → MTV63ZD/A
Blau 512 GB → MTVA3ZD/A
Blau 1 TB → MTVG3ZD/A
Weiß 128 GB → MTUW3ZD/A
Weiß 256 GB → MTV43ZD/A
Weiß 512 GB → MTV83ZD/A
Weiß 1 TB → MTVD3ZD/A
Schwarz 128 GB → MTUV3ZD/A
Schwarz 256 GB → MTV13ZD/A
Schwarz 512 GB → MTV73ZD/A
Schwarz 1 TB → MTVC3ZD/A

iPhone 15 Pro Max (Titan):
Natur 256 GB → MU793ZD/A
Natur 512 GB → MU7E3ZD/A
Natur 1 TB → MU7J3ZD/A
Blau 256 GB → MU7A3ZD/A
Blau 512 GB → MU7F3ZD/A
Blau 1 TB → MU7K3ZD/A
Weiß 256 GB → MU783ZD/A
Weiß 512 GB → MU7D3ZD/A
Weiß 1 TB → MU7H3ZD/A
Schwarz 256 GB → MU773ZD/A
Schwarz 512 GB → MU7C3ZD/A
Schwarz 1 TB → MU7G3ZD/A

@confluencepoint
Copy link

Was wäre der einfachste Weg um an andere Links für Produkte zu kommen?

@marco79cgn
Copy link
Author

marco79cgn commented Nov 1, 2021

Auf dem iPhone selbst geht es am einfachsten über die Apple Store app. Produkt öffnen, dann oben rechts auf den share button drücken. Im kopierten Link steht dann die Produkt Nummer am Ende der URL. Die muss dann im Skript oben hinter "parts.0=" eingefügt werden.

Beispiel:
AirPods (3. Generation)

Link aus Apple Store app:
https://store.apple.com/de/xc/product/MME73ZM/A

@Manu8D
Copy link

Manu8D commented Sep 22, 2023

Vielen Dank für das Script! Ich habe damit eben erfolgreich mein iPhone zur Abholung für morgen bestellt. Eine kleine Anmerkung: Bei mir hat das Script auf dem Raspberry Pi dauerhaft angeschlagen, weil "grep -i "available" auch "unavailable" gefunden hat. Mit "grep -i -w "available" hat es dann aber funktioniert.

@marco79cgn
Copy link
Author

marco79cgn commented Sep 22, 2023

@Manu8D
Ach spannend, Danke für‘s Feedback und natürlich Glückwunsch zum Kauf.

Ich hatte mich kürzlich erst gefragt, wie mein 2 Jahre alter Code eigentlich funktionieren kann aus genau dem Grund, den du genannt hast. Aber bei mir funktioniert er tatsächlich so, weil die Anführungszeichen explizit Teil der Ausgabe und des greps sind. Daher matcht „available“ nicht auf „unavailable“. Anders wäre es, wenn ich jq -r (raw) machen würde, denn dann werden die Anführungszeichen unterdrückt. Ich teste nochmal mit deiner Lösung und passe dann das Skript an, wenn‘s klappt.

//EDIT:
Skript ist angepasst!

@marco79cgn
Copy link
Author

Update 24.09.2023

Das Skript ist jetzt komplett universell benutzbar und muss nicht mehr editiert werden. Beim Aufruf müssen die benötigten 4 Parameter lediglich mitgegeben werden: partNo storeId notifyTopic tempFolder

Zum Beispiel für das iPhone 15 Pro Max 256 GB Titan Blau im Apple Store Köln Schildergasse:
./apple-availability-check.sh "MU7A3ZD/A" "R559" "my-secret-apple-alerts-395920" "/Users/marco/dev/temp"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment