Skip to main content

benecaster_transcript_url_generated

Action Free

Fires when an episode gains a Podcasting 2.0 transcript by something other than the podcaster typing it — the media picker, or the benecaster_podcast2_transcript_autodetect auto-detection scan.

The negatives are the contract and must be read as such. It does NOT fire on a hand-typed URL, NOR when the written URL equals the stored one, NOR when the field is cleared, NOR when detection finds nothing or finds several files. That is what lets a listener read it as “this episode just acquired a transcript.”

$mime_type is the type as stored, not as requested, so a callback writing it back cannot persist a value the save path rejects.

The source is deliberately NOT a fourth parameter — an add-on’s origin would be a value core has never heard of. Add-ons that write the field fire this hook themselves via \Benecaster\Episode\TranscriptUrlSource::announce().

It fires during the save, before the response is returned — keep the callback cheap and schedule anything slow rather than doing it inline.

React when an episode gains a transcript

Free Intermediate

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"
}
<?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
);

View on GitHub →

Parameters

Name Type Default Description
$episode_id int ID of the episode that gained a transcript.
$url string The transcript URL, as stored.
$mime_type string The transcript's MIME type, as stored (not necessarily as requested).

Examples

React when an episode gains a transcript

add_action(
    'benecaster_transcript_url_generated',
    function ( int $episode_id, string $url, string $mime_type ): void {
        wp_schedule_single_event(
            time() + 30,
            'my_addon_process_transcript',
            [ $episode_id, $url, $mime_type ]
        );
    },
    10,
    3
);

Notes

If your add-on writes the field itself, fire this same hook so every listener has one thing to hook regardless of where the transcript came from:

``php $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 instead, declare the source and core fires the hook for you: PUT /benecaster/v1/episodes/{id} accepts an optional podcast2_transcript_url_source of media_picker or autodetect. Absent, manual, or anything unrecognised means a manual write and fires nothing.

Need this built rather than just documented? See our services →