Jellyfin Webhook v2

hope you like this one, a bit more extensive version of the previous release. I have released this as v2 due to the extra effort and work gone in to it.

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

github link < Need for webhook_template.handlebars

Handling Notification Types:

  • Authentication Failure
  • Authentication Success
  • Item Added
  • Item Deleted
  • Playback Progress
  • Playback Start
  • Playback Stop
  • User Created
  • User Deleted
  • User Locked Out
  • User Password Changed
  • User Updated

1 toggle helper is needed to be setup (preferably per each automation deployment from the blueprint, this is to handle the pause/resume function)

1 Like

Just add the webhook like this
http://{ha_ip}:{ha_port}/api/webhook/{your_webhook_id}
and check it in the other automation, and trigger work fine.
Then add same webhook to the Blueprint Jellyfin Webhook v2, and i don’t get trigger event, traceroute is empty

alias: Jellyfin Webhook Handler
description: ""
use_blueprint:
  path: thenextbutton/jellyfin_webhook_release_v2.yaml
  input:
    webhook_id: >-
      http://ip:port/api/webhook/jellyfin-blueprint
    movie_play_actions:
      - alias: Noti
        data:
          title: <b>{{trigger.data.Name }}</b> - {{ trigger.data.Year }} ️▶️
          data:
            image: "{{ trigger.data.Thumbnail }}"
            tag: jellyfin-notification
            channel: Jellyfin
            notification_icon: mdi:television-play
            color: green
        enabled: true
        action: notify.mobile_app
    movie_stop_actions:
      - alias: Noti
        data:
          title: <b>{{trigger.data.Name }}</b> - {{ trigger.data.Year }} ️⏹
          data:
            image: "{{ trigger.data.Thumbnail }}"
            tag: jellyfin-notification
            channel: Jellyfin
            notification_icon: mdi:television-stop
            color: red
        enabled: true
        action: notify.mobile_app
    automation_mode: restart
    jellyfin_ispaused_helper: input_boolean.jellyfin_pause_helper
    webhook_local_only: true
    jellyfin_client_id: Synology
    jellyfin_client: Synology
    jellyfin_client_retrieve: true

1 Like

Does the last triggered on the automation update its time when Jellyfin plays any media?

What happens if you check the option within the Jellyfin Webhook plugin:

Then try and play some media.

Have released an update.

which brings with it Added/Deleted Alerts for:
Music Albums
Season
Series

The webhook_template.handlebars has also been updated to process this:
webhook_template

If i check this option nothing happens
Another automation (setting up by this )with the same webhook works fine, but when i use the blueprint It doesn’t work

And last triggered on the automation update say - “Never” :roll_eyes:

I tried to create a new automation without action, only a webhook, as well as nonsense

I found out what was the problem
I’ve insert full address of the webhook, but when I indicated only part after
http://ip:port/api/webhook/
only generated random string, everything worked!

But for now the action won’t work…

alias: Jellyfin Webhook Handler
description: ""
use_blueprint:
  path: thenextbutton/jellyfin_webhook_release_v2.yaml
  input:
    webhook_id: 302b4ea2-16c2-40c8-8473-3972ca080836
    movie_play_actions: []
    movie_stop_actions:
      - action: notify.mobile_app_reno_7
        metadata: {}
        data:
          message: Test
    automation_mode: restart
    jellyfin_ispaused_helper: input_boolean.jellyfin_pause_helper
    webhook_local_only: true
    jellyfin_client_retrieve: false

that is good that you got it to trigger, did you fill in the Jellyfin Client ID or Name? You just need the one, ID is preferable.

If you need to retrieve it then enable:

When you save the automation after enabling it the client id/name will appear within the notifications:

UPDATE Release:

Added the ability to add Playback Progress actions, within these actions variables are available:
media_playback_time : 00:00:32 (format hh:mm:ss)
media_remaining_time : 00:05:31 (format hh:mm:ss)
media_total_time : 00:06:03 (format hh:mm:ss)
media_played_percentange : 008.8% (format 000.0%)
media_left_precentage : 091.2% (format 000.0%)

When creating a new automation from the template, I have included an example of how they can be used within the playback progress actions

1 Like

After uncheck
Send all properies
I get the ClientID

But if i want run automation for all Clients?
I need to make another automation?

Yes, it is supposed to be one automation per jellyfin client / room.

I can, if needed, alter it (as I have done with the plex blueprint) to accept multiple client IDs. However the idea is you are targeting one room with the blueprint, so create one automation per room.

I have only done multiple for the Plex blueprint as I used the Plex and Plexamp player in the same room on the same device but they both give different IDs. However as you can see here:

It can be possible for me to change the jellyfin blueprint to this as well.

It will be nice. Cause I have 2 devices in one room with different ClientID, and two mobile devices in other room.

that is now done, just re-import the blueprint:

Have altered it so you can use multiple client ids or names (although ids are always preferred as you can have multiple clients with the same name).

With any automatons you have deployed from the blueprint please remove any existing client id’s and re-add them again. The jellyfin_client_id/name is moving from a single entry line to a multi line option, so it will not trigger any actions until this is done (hope that makes sense).

Thank you so much!

1 Like

I have one more question?
Can please add this variables?

"ItemUrl": "http://ip:port/web/index.html#!/details?id={{ItemId}}&serverId={{ServerId}}",
    "Provider_tmdb": "{{Provider_tmdb}}",
    "Provider_kinopoiskru": "{{Provider_kinopoiskru}}",
    "Provider_tvdb": "{{Provider_tvdb}}",
    "Provider_imdb": "{{Provider_imdb}}"

That is not a problem. I will get that added and let you know.

I left that out thinking nobody would use that information :joy:

Nice!
Thanks again :smiley:

I will use it :upside_down_face:

Before I update github would you please try the following:

{
    "notification_type": "{{NotificationType}}"
    ,"user_name": "{{NotificationUsername}}"
    ,"device_name": "{{DeviceName}}"
    ,"device_id": "{{DeviceId}}"
    ,"client_name": "{{ClientName}}"
    ,"server_name": "{{ServerName}}"
    ,"server_id": "{{ServerId}}"
    ,"server_version": "{{ServerVersion}}"
    {{#if_equals ItemType "Movie"}}
        ,"item_id": "{{ItemId}}"
        ,"item_type": "{{ItemType}}"
        ,"item_name": "{{Name}}"
        ,"thumbnail_url": "{{ServerUrl}}/Items/{{ItemId}}/Images/Primary"
        ,"year": "{{Year}}"
        ,"overview": "{{Overview}}"
        ,"genres": "{{Genres}}"
    {{/if_equals}}
    {{#if_equals ItemType "Audio"}}
        ,"item_id": "{{ItemId}}"
        ,"item_type": "{{ItemType}}"
        ,"item_name": "{{Name}}"
        ,"thumbnail_url": "{{ServerUrl}}/Items/{{ItemId}}/Images/Primary"
        ,"album": "{{Album}}"
        ,"artist": "{{Artist}}"
        ,"genres": "{{Genres}}"
        ,"year": "{{Year}}"
    {{/if_equals}}
    {{#if_equals ItemType "MusicAlbum"}}
        ,"item_id": "{{ItemId}}"
        ,"item_type": "{{ItemType}}"
        ,"item_name": "{{Name}}"
        ,"thumbnail_url": "{{ServerUrl}}/Items/{{ItemId}}/Images/Primary"
        ,"album": "{{Album}}"
        ,"artist": "{{Artist}}"
        ,"genres": "{{Genres}}"
        ,"year": "{{Year}}"
        ,"runtime_ticks": "{{RunTimeTicks}}"
        ,"runtime": "{{RunTime}}"
    {{/if_equals}}
    {{#if_equals ItemType "Episode"}}
        ,"item_id": "{{ItemId}}"
        ,"item_type": "{{ItemType}}"
        ,"item_name": "{{Name}}"
        ,"thumbnail_url": "{{ServerUrl}}/Items/{{ItemId}}/Images/Primary"
        ,"series_name": "{{SeriesName}}"
        ,"season_number": "{{SeasonNumber}}"
        ,"season_number_00": "{{SeasonNumber00}}"
        ,"episode_number": "{{EpisodeNumber}}"
        ,"episode_number_00": "{{EpisodeNumber00}}"
        ,"episode_year": "{{Year}}"
        ,"overview": "{{Overview}}"
        ,"genres": "{{Genres}}"
        ,"series_id": "{{SeriesId}}"
        ,"series_url": "{{ServerUrl}}/web/index.html#!/details?id={{SeriesId}}&serverId={{ServerId}}"
    {{/if_equals}}
    {{#if_equals ItemType "Season"}}
        ,"item_id": "{{ItemId}}"
        ,"item_type": "{{ItemType}}"
        ,"item_name": "{{Name}}"
        ,"thumbnail_url": "{{ServerUrl}}/Items/{{ItemId}}/Images/Primary"
        ,"series_name": "{{SeriesName}}"
        ,"series_id": "{{SeriesId}}"
        ,"series_url": "{{ServerUrl}}/web/index.html#!/details?id={{SeriesId}}&serverId={{ServerId}}"
        ,"season_number": "{{SeasonNumber}}"
        ,"season_number_00": "{{SeasonNumber00}}"
        ,"overview": "{{Overview}}"
        ,"year": "{{Year}}"
    {{/if_equals}}
    {{#if_equals ItemType "Series"}}
        ,"item_id": "{{ItemId}}"
        ,"item_type": "{{ItemType}}"
        ,"item_name": "{{Name}}"
        ,"thumbnail_url": "{{ServerUrl}}/Items/{{ItemId}}/Images/Primary"
        ,"overview": "{{Overview}}"
        ,"year": "{{Year}}"
    {{/if_equals}}
    {{#if_equals NotificationType "ItemAdded"}}
        ,"item_url": "{{ServerUrl}}/web/index.html#!/details?id={{ItemId}}&serverId={{ServerId}}"
    {{/if_equals}}
    {{~#if_exist Provider_imdb~}}
        ,"imdb_id": "{{Provider_imdb}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_tmdb~}}
        ,"tmdb_id": "{{Provider_tmdb}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_tvdb~}}
        ,"tvdb_id": "{{Provider_tvdb}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_wikidata~}}
        ,"wikidata_id": "{{Provider_wikidata}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_musicbrainzartist~}}
        ,"musicbrainz_artist": "{{Provider_musicbrainzartist}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_musicbrainzalbumartist~}}
        ,"musicbrainz_albumartist": "{{Provider_musicbrainzalbumartist}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_musicbrainztrack~}}
        ,"musicbrainz_track": "{{Provider_musicbrainztrack}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_musicbrainzalbum~}}
        ,"musicbrainz_album": "{{Provider_musicbrainzalbum}}"
    {{~/if_exist~}}
    {{~#if_exist Provider_kinopoiskru~}}
        ,"kinopoiskru_id": "{{Provider_kinopoiskru}}"
    {{~/if_exist~}}
    {{#if_equals NotificationType "PlaybackStart"}}
        ,"item_url": "{{ServerUrl}}/web/index.html#!/details?id={{ItemId}}&serverId={{ServerId}}"
        ,"event_type": "playback_start"
        ,"runtime_ticks": "{{RunTimeTicks}}"
        ,"play_method": "{{PlayMethod}}"
    {{/if_equals}}
    {{#if_equals NotificationType "PlaybackProgress"}}
        ,"item_url": "{{ServerUrl}}/web/index.html#!/details?id={{ItemId}}&serverId={{ServerId}}"
        ,"event_type": "playback_progress"
        ,"playback_position_ticks": "{{PlaybackPositionTicks}}"
        ,"runtime_ticks": "{{RunTimeTicks}}"
        ,"is_paused": "{{IsPaused}}"
        ,"play_method": "{{PlayMethod}}"
    {{/if_equals}}
    {{#if_equals NotificationType "PlaybackStop"}}
        ,"item_url": "{{ServerUrl}}/web/index.html#!/details?id={{ItemId}}&serverId={{ServerId}}"
        ,"event_type": "playback_stop"
        ,"played_to_completion": "{{PlayedToCompletion}}"
        ,"playback_position_ticks": "{{PlaybackPositionTicks}}"
        ,"runtime_ticks": "{{RunTimeTicks}}"
        ,"play_method": "{{PlayMethod}}"
    {{/if_equals}}
    {{#if_equals NotificationType "UserCreated"}}
        ,"event_type": "user_created"
        ,"user_id": "{{UserId}}"
        ,"is_admin": "{{IsAdmin}}"
    {{/if_equals}}
    {{#if_equals NotificationType "UserDeleted"}}
        ,"event_type": "user_deleted"
        ,"user_id": "{{UserId}}"
    {{/if_equals}}
    {{#if_equals NotificationType "UserLockedOut"}}
        ,"event_type": "user_locked_out"
        ,"user_id": "{{UserId}}"
        ,"is_locked_out": "{{IsLockedOut}}"
    {{/if_equals}}
    {{#if_equals NotificationType "UserPasswordChanged"}}
        ,"event_type": "user_password_changed"
        ,"user_id": "{{UserId}}"
    {{/if_equals}}
    {{#if_equals NotificationType "UserUpdated"}}
        ,"event_type": "user_updated"
        ,"user_id": "{{UserId}}"
        ,"is_admin": "{{IsAdmin}}"
        ,"is_locked_out": "{{IsLockedOut}}"
    {{/if_equals}}
    {{#if_equals NotificationType "AuthenticationSuccess"}}
        ,"event_type": "authentication_success"
        ,"user_id": "{{UserId}}"
        ,"last_login_date": "{{LastLoginDate}}"
        ,"last_activity_date": "{{LastActivityDate}}"
        ,"client": "{{Client}}"
        ,"remote_end_point": "{{RemoteEndPoint}}"
    {{/if_equals}}
    {{#if_equals NotificationType "AuthenticationFailure"}}
        ,"event_type": "authentication_failure"
        ,"username": "{{Username}}"
        ,"user_id": "{{UserId}}"
        ,"app": "{{App}}"
        ,"app_version": "{{AppVersion}}"
        ,"remote_end_point": "{{RemoteEndPoint}}"
    {{/if_equals}}
}

you should see (if they are available):
payload.item_url
payload.imdb_id
payload.tmdb_id
payload.tvdb_id
payload.kinopoiskru_id

I have also added, just incase:
payload.series_url
payload.wikidata_id
payload.musicbrainz_artist
payload.musicbrainz_albumartist
payload.musicbrainz_track
payload.musicbrainz_album

please let me know how you get on, from my very quick testing they look to be ok but I do not use kinopoiskru (so hopefully the formatting is ok)

Seems everything looking good!

    imdb_id: tt12412888
    tmdb_id: '675353'
    tvdb_id: '135895'
    kinopoiskru_id: '1387469'
    item_url: >-
      http://192.168.1.7:8096//web/index.html#!/details?id=a38b6a95-1c9b-2865-4b0b-a15ddd21935c&serverId=3f6529b442ea42509fb5c14c2e371a5a