React when an episode gains a transcript
Do something once, at the moment an episode acquires a Podcasting 2.0 transcript, whatever produced it. The companion to Supply a transcript URL from your own service: that recipe writes the URL, this one reacts to it. Use it to notify a team, warm a cache, kick off a translation, or add a “transcript available” note to the episode.
Signature: benecaster_transcript_url_generated( int $episode_id, string $url, string $mime_type ). Free, never licence-gated.
It fires only for a non-manual write. Core fires it for a file chosen in the media picker and for a URL auto-detected from the episode’s attached media. ⚠ It does not fire when the podcaster types the URL by hand. That is the whole point: a hook that also fired on typing could not be told apart from “someone saved an episode”.
It also does not fire when the URL written is unchanged from the stored one, nor when the field is cleared. So you can treat it as “this episode just acquired a transcript it did not have” and not guard against repeats on every unrelated save.
$mime_type is the type as stored, not as requested — the save path drops a type outside its five accepted values, so a callback that writes this value back cannot persist something invalid.
⚠ The source is not a parameter, by design. An add-on that writes the field itself fires this same hook, and its origin would be a value core has never heard of; a listener that must branch on origin wants its own hook.
It fires during the save, before the response is returned, so keep the callback cheap — schedule anything slow rather than doing it inline.
If your add-on writes the field itself, fire the same hook so every listener has one thing to hook, regardless of where the transcript came from:
$meta = new \Benecaster\Episode\EpisodeMeta( $episode_id );
$meta->set_podcast2_transcript_url( $url );
$meta->set_podcast2_transcript_type( $mime_type );
\Benecaster\Episode\TranscriptUrlSource::announce( $episode_id, $url, $mime_type );
If you write the field through the REST API, declare the source instead and core fires the hook for you. podcast2_transcript_url_source accepts media_picker or autodetect; absent, manual, or anything unrecognised means a manual write and fires nothing:
PUT /benecaster/v1/episodes/{id}
{
"podcast2_transcript_url": "https://cdn.example.com/ep42.vtt",
"podcast2_transcript_type": "text/vtt",
"podcast2_transcript_url_source": "autodetect"
}
Code
<?php
add_action(
'benecaster_transcript_url_generated',
function ( int $episode_id, string $url, string $mime_type ): void {
// Cheap: hand the slow part to cron rather than holding up the save.
wp_schedule_single_event(
time() + 30,
'my_addon_process_transcript',
[ $episode_id, $url, $mime_type ]
);
},
10,
3
);
Hooks Used
Need this built rather than just documented? See our services →