Skip to content

Instantly share code, notes, and snippets.

@yodaluca23
Last active October 3, 2024 00:58
Show Gist options
  • Save yodaluca23/f31b3d8cdc4b63a7d17db3f4454ecb85 to your computer and use it in GitHub Desktop.
Save yodaluca23/f31b3d8cdc4b63a7d17db3f4454ecb85 to your computer and use it in GitHub Desktop.
Discord Webhook Ping when Apple AppStore App update
# Thank you to https://github.com/asdfzxcvbn/update-notifier for figuring out how to force the iTunes API, to not use cache.
import os
import requests
import subprocess
import json
# Configurations
version_file = "app_version.txt" # The text file where the version number will be saved will be prefixed with the apps BundleID
webhook_url = "DISCORDWEBHOOK" # Your Discord webhook URL
app_bundleID = "com.google.ios.youtube" # The BundleID for the app you want updates for. You can get the BundleID from here https://armconverter.com/appinfo
role_to_ping = "@everyone" # Can be "@everyone", "@here", "<@UserID>", or "<@&RoleID>"
# Function to prefix BundleID to Version File
def prefixBundleID(version_file, bundle_id):
version_file = f"{bundle_id}- {version_file}"
return version_file
# Function to get the app details from the iTunes API
def get_app_details(bundle_id):
url = f"https://itunes.apple.com/lookup?bundleId={bundle_id}&limit=1&noCache=1"
response = subprocess.run(["curl", "-s", url], capture_output=True, text=True)
if response.returncode != 0:
raise Exception("Failed to fetch app details from iTunes API")
app_details = json.loads(response.stdout)
return app_details['results'][0]['version'], app_details['results'][0]['trackName'], app_details['results'][0]['trackViewUrl'], app_details['results'][0]['artworkUrl512']
# Function to read the saved version from the file
def read_saved_version():
if os.path.exists(version_file):
with open(version_file, 'r') as file:
return file.read().strip()
return None
# Function to save the new version to the file
def save_version(version):
with open(version_file, 'w') as file:
file.write(version)
# Function to send a Discord notification
def send_discord_notification(app_name, version, download_URL, icon, role):
mention_type = determine_mention_type(role)
data = {
"content": f"{role_to_ping} New \"{app_name}\" Update Available: {version}\n{download_URL}",
"username": f"{app_name} Update Notification",
"avatar_url": f"{icon}",
"allowed_mentions": {
"parse": []
}
}
if mention_type == "role":
data["allowed_mentions"]["parse"] = ["roles"]
elif mention_type == "user":
data["allowed_mentions"]["parse"] = ["users"]
elif mention_type == "everyone":
data["allowed_mentions"]["parse"] = ["everyone"]
elif mention_type == "here":
data["allowed_mentions"]["parse"] = ["here"]
headers = {
"Content-Type": "application/json"
}
response = requests.post(webhook_url, json=data, headers=headers)
if response.status_code != 204:
raise Exception(f"Failed to send Discord notification, status code: {response.status_code}")
# Determine the type of mention
def determine_mention_type(role):
if role.startswith("<@&") and role.endswith(">"):
return "role"
elif role.startswith("<@") and role.endswith(">"):
return "user"
elif role == "@everyone":
return "everyone"
elif role == "@here":
return "here"
else:
raise ValueError("Invalid role_to_ping format")
# Main logic
def main():
global version_file
version_file = prefixBundleID(version_file, app_bundleID)
try:
current_version, app_name, download_URL, app_icon = get_app_details(app_bundleID)
app_name = app_name.split(' -', 1)[0].split(':', 1)[0]
saved_version = read_saved_version()
current_version_parts = [int(x) for x in current_version.split('.')]
saved_version_parts = [int(x) for x in saved_version.split('.')]
if current_version_parts > saved_version_parts:
send_discord_notification(app_name, current_version, download_URL, app_icon, role_to_ping)
save_version(current_version)
print(f"New version detected and saved: {current_version}")
else:
print(f"No new version. Current version is: {current_version}")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment