Tautulli β†’ Nextcloud Talk (Webhook Notifications)

:open_mailbox_with_raised_flag: Tautulli β†’ Nextcloud Talk (Webhook Notifications)

This guide explains how to connect Tautulli with Nextcloud Talk so that every time new content is added to Plex, a message is automatically sent to a Talk conversation.


:bullseye: Result

After adding a movie or episode, you will see a message like this in Talk:

πŸ“¬ PLEX NEW CONTENT

🎬 Oppenheimer
πŸ“ movie

🧾 The story of J. Robert Oppenheimer...

⭐ 8.5
πŸ“… 2026-03-22


:brain: How it works

Plex β†’ Tautulli β†’ Webhook β†’ Nextcloud Talk API β†’ Talk conversation

  • Tautulli detects an event (e.g. Recently Added)

  • It sends an HTTP request (Webhook)

  • Nextcloud Talk API receives the message and posts it into the chat

:backhand_index_pointing_right: In simple terms:
Tautulli acts as a bridge between Plex activity and your chat notifications.


:clipboard: Requirements

Before starting, make sure you have:

  • A working Nextcloud instance with Talk app installed

  • Tautulli installed and connected to Plex

  • Access to your Nextcloud account

  • An existing Talk conversation


:one: Create or choose a Talk conversation

  1. Open Nextcloud

  2. Launch the Talk app

You can either:

  • use an existing conversation (recommended if you already have a channel for notifications), or

  • create a new one (e.g. plex-notifications)

:backhand_index_pointing_right: This conversation will act as your notification channel.


:two: Get the Conversation Token

Open the conversation and check the URL:

https://cloud.example.com/call/abcd1234

:backhand_index_pointing_right: The token is:

abcd1234

:backhand_index_pointing_right: This token uniquely identifies the chat room and is required for the API.


:three: Create an App Password in Nextcloud

  1. Go to Settings β†’ Security

  2. Find App passwords

  3. Create a new password (e.g. tautulli-talk)

Save:

  • your username

  • the generated app password

:backhand_index_pointing_right: This is used instead of your real password and is safer for API usage.


:four: Create a Webhook agent in Tautulli

In Tautulli:

Settings β†’ Notification Agents β†’ Add New β†’ Webhook


Basic configuration

Name:

Nextcloud Talk

Trigger:

Recently Added

:backhand_index_pointing_right: This ensures the notification is triggered whenever new content appears in Plex.


:five: Webhook configuration


URL

https://cloud.example.com/ocs/v2.php/apps/spreed/api/v1/chat/abcd1234

:backhand_index_pointing_right: This is the Nextcloud Talk API endpoint for sending messages.


Method

POST

:backhand_index_pointing_right: We are sending data to the server.


:locked_with_key: JSON Headers (authentication explained)

Tautulli needs to send three important things:

  1. Identify the request as a Nextcloud API call

  2. Specify the data format (JSON)

  3. Authenticate (log in) to Nextcloud

All of this is done using JSON Headers.


Required JSON Headers

{
  "OCS-APIRequest": "true",
  "Content-Type": "application/json",
  "Authorization": "Basic BASE64_STRING"
}


:key: Creating the Authorization header

Nextcloud API uses this format:

Authorization: Basic BASE64(username:password)

Since Tautulli does not have fields for username/password, you must encode them manually.


:gear: Step-by-step

Run this command:

echo -n "USERNAME:APP_PASSWORD" | base64


:magnifying_glass_tilted_left: Example

echo -n "vawaver:abcd-1234-xyz" | base64

Output:

dmF3YXZlcjphYmNkLTEyMzQteHl6


:pushpin: Use it in Tautulli

{
  "OCS-APIRequest": "true",
  "Content-Type": "application/json",
  "Authorization": "Basic dmF3YXZlcjphYmNkLTEyMzQteHl6"
}


:warning: Important notes

  • Must be exactly:
    Basic + space + Base64 string

  • Do NOT use raw username:password

  • Base64 is not encryption, just encoding


:six: Body (message template)

Use this stable template:

{
  "message": "πŸ“¬ PLEX NEW CONTENT\n\n🎬 {title}\nπŸ“ {media_type}\n\n🧾 {summary}\n\n⭐ {audience_rating}\nπŸ“… {added_date}"
}


:brain: Variables used

Variable Description
{title} Title of the movie or episode
{media_type} movie / episode / season
{summary} Description
{audience_rating} Rating (IMDB / TMDB)
{added_date} Date added

:warning: Important notes

JSON Headers

  • Must be valid JSON

  • Not plain text


Authorization

  • Tautulli does not support login fields

  • You must use the Authorization header


Message formatting

  • Nextcloud Talk does NOT support HTML

  • Use:

    • \n for new lines

    • plain text only


Testing

  • The test button may not include real data

  • Best practice:
    β†’ add real content to Plex


:cross_mark: Common issues

Invalid Webhook json header data

β†’ headers are not valid JSON


Message not delivered

β†’ check:

  • Authorization

  • token

  • URL


Date shows as number

β†’ you used {added_at} instead of {added_date}


:1st_place_medal: Final result

  • Automatic Plex notifications

  • Clean output in Nextcloud Talk

  • No additional tools required (no n8n, no scripts)


:rocket: Possible improvements

  • Separate movies and TV shows

  • Add Plex link {plex_url}

  • Add emojis based on content type


Done :+1:

for the reference - more generic discussion about posting messages to Talk using curl and PowerShell

:open_mailbox_with_raised_flag: Follow-up: updated templates for movies, episodes and full seasons

I found one more edge case with the original template.

The previous version worked for:

  • :clapper_board: single movies

  • :television: single episodes

But when I added a complete season at once, Tautulli generated the notification as:

media_type = season

Because my template only had <movie>...</movie> and <episode>...</episode> blocks, the notification did not show the show name or the season number.

The correct approach is to also include a <season>...</season> block.


:left_speech_bubble: Updated Nextcloud Talk webhook template

{
  "message": "πŸ“¬ PLEX - NEW CONTENT\n\n<movie>🎬 {title}</movie><season>πŸ“Ί {show_name} - Season {season_num}</season><episode>πŸ“Ί {show_name} - S{season_num00}E{episode_num00} - {episode_name}</episode><show>πŸ“Ί {show_name}</show>\nπŸ“ {media_type}\n\n🧾 {summary}\n\n⭐ {audience_rating}\nπŸ“… {added_date}"
}


:e_mail: Updated email template

πŸ“¬ <b>PLEX - NEW CONTENT</b><br><br>

<movie>🎬 <b>{title}</b> ({year})</movie><season>πŸ“Ί <b>{show_name}</b> - Season {season_num}</season><episode>πŸ“Ί <b>{show_name}</b> - S{season_num00}E{episode_num00} - {episode_name}</episode><show>πŸ“Ί <b>{show_name}</b></show><br>
πŸ“ {media_type}<br><br>

🧾 <b>Description:</b><br>
{summary}<br><br>

⭐ <b>Rating:</b> {audience_rating}<br>
πŸ“… <b>Added:</b> {added_date}


:gear: Important Tautulli setting

In Tautulli go to:

Settings β†’ Notifications & Newsletters β†’ Recently Added Notifications

Recommended setting:

βœ… Group Notifications by Season or Album: enabled
❌ Group Notifications by TV Show or Artist: disabled


:brain: Why this setting matters

Keeping:

βœ… Group Notifications by Season or Album

enabled allows Tautulli to send one clean season notification when a full season is added.

Disabling:

❌ Group Notifications by TV Show or Artist

avoids grouping multiple seasons into a generic show notification, where detailed season/episode metadata may be unavailable.


:bullseye: Expected behavior

With this setup, Tautulli should use the correct block depending on the content type:

🎬 movie   β†’ <movie> block
πŸ“Ί season  β†’ <season> block
▢️ episode β†’ <episode> block
πŸ“Ί show    β†’ <show> fallback block

Example outputs:

🎬 MarΕ₯an
πŸ“ movie

πŸ“Ί Falling Skies - Season 1
πŸ“ season

πŸ“Ί Falling Skies - S01E03 - Prisoner of War
πŸ“ episode


:warning: Do not use Jinja-style conditions

Do not use syntax like this:

{% if media_type == 'episode' %}

Tautulli does not parse this in these templates and will output it as plain text.