[
  {
    "path": "AirtagAlex.sh",
    "content": "#!/bin/bash\n\nITEMS_FILE=\"./Items.data\"\nCSV_FILE=\"./Airtags.csv\"\nCSV_HEADER=\"datetime,name,serialnumber,producttype,productindentifier,vendoridentifier,antennapower,systemversion,batterystatus,locationpositiontype,locationlatitude,locationlongitude,locationtimestamp,locationverticalaccuracy,locationhorizontalaccuracy,locationfloorlevel,locationaltitude,locationisinaccurate,locationisold,locationfinished,addresslabel,addressstreetaddress,addresscountrycode,addressstatecode,addressadministrativearea,addressstreetname,addresslocality,addresscountry,addressareaofinteresta,addressareaofinterestb\"\n\ncopy_items_data() {\n\techo \"Creating a copy of Items.data to prevent potential file corruption\"\n\tif ! cp -p ~/Library/Caches/com.apple.findmy.fmipcore/Items.data \"$ITEMS_FILE\"; then\n\t    echo \"Failed to copy Items.data file. Please ensure Terminal has 'Full Disk Access' in the 'Privacy & Security' section in macOS Preferences\" >&2\n\t    exit 1\n\tfi\n}\n\ncreate_csv_file() {\n\techo \"Checking if $CSV_FILE exists\"\n\tif [ ! -f \"$CSV_FILE\" ]; then\n\t    echo \"$CSV_FILE does not exist, creating one\"\n\t    if ! echo \"$CSV_HEADER\" >> \"$CSV_FILE\"; then\n\t        echo \"Failed to create $CSV_FILE. Please ensure the destination directory is writable.\" >&2\n\t        exit 1\n\t    fi\n\tfi\n}\n\nwhile true; do\n\tcopy_items_data\n\tcreate_csv_file\n\n\techo \"Checking number of Airtags to process\"\n\tairtagsnumber=$(jq \".[].serialNumber\" \"$ITEMS_FILE\" | wc -l)\n\techo \"Number of Airtags to process: $airtagsnumber\"\n\tairtagsnumber=$((airtagsnumber-1))\n\n\tfor j in $(seq 0 \"$airtagsnumber\"); do\n\techo \"Processing airtag number $j\"\n\n\tdatetime=$(date +\"%Y-%m-%d  %T\")\n\n\tserialnumber=$(jq \".[$j].serialNumber\" \"$ITEMS_FILE\")\n\tname=$(jq \".[$j].name\" \"$ITEMS_FILE\")\n\tproducttype=$(jq \".[$j].productType.type\" \"$ITEMS_FILE\")\n\tproductindentifier=$(jq \".[$j].productType.productInformation.productIdentifier\" \"$ITEMS_FILE\")\n\tvendoridentifier=$(jq \".[$j].productType.productInformation.vendorIdentifier\" \"$ITEMS_FILE\")\n\tantennapower=$(jq \".[$j].productType.productInformation.antennaPower\" \"$ITEMS_FILE\")\n\tsystemversion=$(jq \".[$j].systemVersion\" \"$ITEMS_FILE\")\n\tbatterystatus=$(jq \".[$j].batteryStatus\" \"$ITEMS_FILE\")\n\tlocationpositiontype=$(jq \".[$j].location.positionType\" \"$ITEMS_FILE\")\n\tlocationlatitude=$(jq \".[$j].location.latitude\" \"$ITEMS_FILE\")\n\tlocationlongitude=$(jq \".[$j].location.longitude\" \"$ITEMS_FILE\")\n\tlocationtimestamp=$(jq \".[$j].location.timeStamp\" \"$ITEMS_FILE\")\n\tlocationverticalaccuracy=$(jq \".[$j].location.verticalAccuracy // 0\" \"$ITEMS_FILE\")\n\tlocationhorizontalaccuracy=$(jq \".[$j].location.horizontalAccuracy // 0\" \"$ITEMS_FILE\")\n\tlocationfloorlevel=$(jq \".[$j].location.floorlevel // 0\" \"$ITEMS_FILE\")\n\tlocationaltitude=$(jq \".[$j].location.altitude // 0\" \"$ITEMS_FILE\")\n\tlocationisinaccurate=$(jq \".[$j].location.isInaccurate\" \"$ITEMS_FILE\" | awk '{ print \"\\\"\"$0\"\\\"\" }')\n\tlocationisold=$(jq \".[$j].location.isOld\" \"$ITEMS_FILE\" | awk '{ print \"\\\"\"$0\"\\\"\" }' )\n\tlocationfinished=$(jq \".[$j].location.locationFinished\" \"$ITEMS_FILE\" | awk '{ print \"\\\"\"$0\"\\\"\" }' )\n\taddresslabel=$(jq \".[$j].address.label // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddressstreetaddress=$(jq \".[$j].address.streetAddress // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddresscountrycode=$(jq \".[$j].address.countryCode // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddressstatecode=$(jq \".[$j].address.stateCode // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddressadministrativearea=$(jq \".[$j].address.administrativeArea // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddressstreetname=$(jq \".[$j].address.streetName // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddresslocality=$(jq \".[$j].address.locality // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddresscountry=$(jq \".[$j].address.country // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddressareaofinteresta=$(jq \".[$j].address.areaOfInterest[0] // \\\"\\\"\" \"$ITEMS_FILE\")\n\taddressareaofinterestb=$(jq \".[$j].address.areaOfInterest[1] // \\\"\\\"\" \"$ITEMS_FILE\")\n\n\techo \"Writing data to $CSV_FILE\"\n\techo \"$datetime\",\"$name\",\"$serialnumber\",\"$producttype\",\"$productindentifier\",\"$vendoridentifier\",\"$antennapower\",\"$systemversion\",\"$batterystatus\",\"$locationpositiontype\",\"$locationlatitude\",\"$locationlongitude\",\"$locationtimestamp\",\"$locationverticalaccuracy\",\"$locationhorizontalaccuracy\",\"$locationfloorlevel\",\"$locationaltitude\",\"$locationisinaccurate\",\"$locationisold\",\"$locationfinished\",\"$addresslabel\",\"$addressstreetaddress\",\"$addresscountrycode\",\"$addressstatecode\",\"$addressadministrativearea\",\"$addressstreetname\",\"$addresslocality\",\"$addresscountry\",\"$addressareaofinteresta\",\"$addressareaofinterestb\" >> \"$CSV_FILE\"\n\n\tdone\n\techo -e \"Checking again in 1 minute...\\n\"\n\tsleep 60\n\ndone"
  },
  {
    "path": "README.md",
    "content": "# AirtagAlex\n\n!!This script will NOT work on MAC's that have a Sonoma version thats newer then 14.3.1. Apple started encrypting the data after this version!!\n\nGet all metadata from the Airtags (lat, lon, geocoding information, precision range, battery status).\nThis script is a very basic script to write the data to a CSV for processing in Excel or Numbers. I am sure many rewrites will be done by other folks but anyone with some programming experience will have a good starting point with this script. \n\nClick below to see the youtube video and a step by step guide;\n\n[![Click here for the youtube video](https://img.youtube.com/vi/9VQ-_ztG9aM/0.jpg)](https://www.youtube.com/watch?v=9VQ-_ztG9aM)\n\n\n## Instructions\n\n* Install brew (https://brew.sh/)\n* Install the jq utility (`brew install jq`)\n* Clone this repo by typing `git clone https://github.com/icepick3000/AirtagAlex.git`\n* Make the shell file executable by typing `chmod 700 AirtagAlex.sh`\n  \nYou can start the script by typing:\n  \n`./AirtagAlex.sh`\n  \nThe output will look something like this:\n\n```\nCreate a copy of the Items.data file to prevent changes while the script is running\nCheck if Airtags.csv exists\nCheck how many Airtags to process\nNumber of Airtags to process:       4\nProcessing airtag number 0\nWrite the data to the Airtags.csv file\nProcessing airtag number 1\nWrite the data to the Airtags.csv file\nProcessing airtag number 2\nWrite the data to the Airtags.csv file\nProcessing airtag number 3\nWrite the data to the Airtags.csv file\nSleep for 1 minute (60 seconds)\n```\n  \nThe results in CSV format can be found in the same directory!\n    \nTo see all my Airtag adventures check out my channel at https://www.youtube.com/c/AirtagAlex\n    \nIf this script was of use to you a referal in your video or project would be highly appreciated. \n\n## Troubleshooting\nIf you receive an `operation not permitted` error when running the script, please ensure that `Terminal` has `Full Disk Access` in the `Privacy & Security` settings in macOS.\n\nThis is because of the file permissions on the `Items.data` file. Please propose an alternative or better way to do this if it's possible.\n"
  }
]