Need help with Custom Scripts and historyid

Sonarr version (exact version):
Mono version (if Sonarr is not running on Windows):
OS: Ubuntu 24.04 LTS, but running in docker (release-fffea1f by hotio)
Debug logs: Check in the description of the issue
Description of issue:

Hello :). I need help with figuring out how to work with historyid’s in Sonarr’s Custom Scripts. I have tried looking through the API documentation and Custom Scripts documentation, but I’m kind of stumped.

The (working) Radarr version of the script
So I have made this script for Radarr, that checks every file on Import, if it has a danish audio track. If it doesn’t, it’ll delete the file and mark the download as failed, triggering a new search. It works great at this point:

I tried making the script work for Sonarr as well. I tried using the corresponding API calls and adjusting it with its own variables from the Custom Scripts documentation.

But I simply can’t get it to grab the historyId of the file/download it’s trying to import.

The (non-working) Sonarr version of the script
For reference, here’s the Sonarr script that I’m using, where I tried using the same methods and functions as much as possible, from the Radarr script:

The script correctsly detects if there’s a danish audio track or not, and it’ll delete the file, but it seems Sonarr works differently than Radarr from this point on.

Radarr can successfully grab the historyId “On Import”, while Sonarr for some reason can’t?

Successful run log from Radarr
Here’s a log from a successful Radarr run with the script (downloading a movie without a danish audio track): (trace log, huge)

In the log, we can see it fetches movie file, deletes it, finding historyId and then marking it as failed, and then initiates a new search.

Non-succesful run log from Sonarr
But here’s a run from the Sonarr script, using the exact same function for grabbing the historyId, where it can’t find it:

My guess is that Sonarr and Radarr works slightly differently with importing files? Radarr seems to generate the historyId earlier, while Sonarr seems to generate it later, so the script can’t find it before it’s done executing its main loop. I also might’ve just botched the execution loop in the Sonarr script.

Maybe Sonarr only generates the historyId upon the script exiting/completing? Again, not sure.

What I’ve tried so far:

  1. Adding a retry function to the find_history_record_id() function:
  • This only had the result, that Sonarr “hangs” on import, where it’ll just wait to actually import the file, until the retries have completed
  1. Adding a sleep function after the file has been deleted
  • This did not work, for some reason. It still can’t find the download id. It again just seems to wait for 5 seconds, before it imports the file. This means there still won’t be a historyId generated.
  1. Tried creating a simple bash script, that just has the find_history_record_id() function (for Sonarr):
  • This confirms that the historyId can’t be grabbed, if the download “just” is in the queue.
  • It has to get imported, otherwise it won’t return a historyId.
  • After importing, it’ll give the historyId.
  • You can check it with e.g. ./ SABnzbd_nzo_downloadIdHere

Answering other questions

  1. Why don’t you just filter out languages via custom formats?
  • Since danish is a quite “small” language, almost no indexers will register the language correctly. This means it’s quite unreliable.
  1. How about a download profile, that only downloads releases using scene-based or p2p tags for language?
  • That’s what I’m already doing. I’m using DANiSH and NORDiC, but sometimes people upload wrong stuff to both usenet and torrent indexers, which also makes this method slightly unreliable.
  1. Have you tried making a script for this on SABnzbd instead?
  • Yes, and I have one working, but this means I can’t use qBittorrent, since I can’t seem to figure out how to make a similar one for qBittorrent.

I’m stumped on how to continue from here.
I know it’s a huge ask to look through all this log and code, but if anyone finds it interesting, or feeling charitable and helpful, I would appreciate any help :slight_smile:

Kind regards,

History is paged and by default you’re only going to get 10 records. You’re also ignoring the filtering that is available.

You’ll want probably want to filter by eventTypes=1 (grabbed) and downloadId=X so you only get the grab event.

Thanks for taking the time to help me out.

So something like this?

find_history_record_id() {
    local download_id="$1"
    local history_records
    local history_id

    history_records=$(curl -s -H "X-Api-Key: $SONARR_API_KEY" "$SONARR_API_URL/history?eventType=1&downloadId=$download_id")

    history_id=$(echo "$history_records" | jq -r '.records[0].id')

    if [[ -z "$history_id" ]]; then
        log_info "Error: No history record found for download ID: $download_id"
        return 1

    echo "$history_id"
    return 0

I’ll test it out a bit later, and edit this post with the results.

Hmm. I might just not be understanding what I’m doing, but it’s not working with that function update:

Using this script, which just uses the function, and then ./ SABnzbd_nzo_m3r77vff gives the correct historyId, but only after Sonarr has imported the file, and the script has exited:

(before import/in sabnzbd queue)
user@server:~/downloads/jsonTest$ ./ SABnzbd_nzo_m3r77vff

(after import)
user@server:~/downloads/jsonTest$ ./ SABnzbd_nzo_m3r77vff

Using eventType=1 in the history_records gives null every time it seems. Even if the download is in queue, and registered in Sonarr. Have no eventType set in the curl command still results in the same issue, the historyId is not “generated” before the import has been completed, and the script seemingly has exited.

I can find the historyId with the above script (without the eventType=1) immediately after the import has been completed, and the script has exited.

Edit 2:
Here’s the (updated) Sonarr script in full, as of this writing:
(without eventType=1, tried both with and without, same result in my case)

Reproducing steps?

  1. Have the script ready – link here
  2. Enable the in Sonarr. (SettingsConnect → Add Custom Script → Select On Import and On Upgrade) – link here
  3. Enable tracelogging in Sonarr, clear logs
  4. Add a nzb file to SABnzbd, anything without a danish audio track will do. Obviously choose the download category that Sonarr registers.
  5. Update the queue in Sonarr
  6. Pause SABnzbd
  7. Check your tracelogs for the downloadId, will be SABnzbd_nzo_*. In my case, it’s SABnzbd_nzo_j4hgc6ft.
  8. Test the find_history_record_id() function with the script - returns null, while the downloadId is in the queue, even with or without eventType=1 being included in the curl. I used ./ SABnzbd_nzo_j4hgc6ft which returns null.
  9. The logs will show, that the grabbing of historyId has failed with a null (full logs here)
  10. Now run the again with your downloadId, after the script has exited (completed), in my case: ./ SABnzbd_nzo_j4hgc6ft - it will now return your historyId

I have tried the past few days to get this working, to no avail.

Sonarr seems to be creating the historyId only after the Custom Script has exited, which makes this quite difficult to make work.

Radarr seems to work differently in this regard, as the historyId seems to get created earlier, or synchronously with the script running or import process running.

If anyone has any way of making this work, I would appreciate it :slight_smile:

Are these releases being grabbed by Sonarr? Filtering by eventType=1, will return the grab events, which is ultimately what Sonarr uses to blocklist a release and search for another. If Sonarr is not grabbing the release or it knows the grab under a different ID then that won’t work.

The history event for the import is not guaranteed to be stored before the script executes, which should be the same behaviour in Radarr, since the Custom Script execution is synchronous (by design) if it’s not there at the start of execution it won’t be there at the end.