Purchase access to watch this video.

Unlock course for £159

Already purchased access? Login

Listening for Mux webhooks

Connect GitHub

Transcript was automatically generated and may be inaccurate.

  1. –

    We've made our video upload form a little more interactive, but our Video
  2. –

    models won't
  3. –

    be getting updated in the database.
  4. –

    We added two columns to our Video model, "upload_status" and "mux_status".
  5. –

    So we need to update these some how.
  6. –

    To achieve this, we'll use webhooks.
  7. –

    Webhooks is when another service pings your application with some data that the
  8. –

    application
  9. –

    can then respond to.
  10. –

    Mux is no different.
  11. –

    Mux can notify us when an upload has errored or succeeded, and also when a
  12. –

    related asset
  13. –

    is ready or if that too errored.
  14. –

    Webhooks at their simplest, are just POST requests sent from another server to your
  15. –

    application.
  16. –

    So we can create a controller to handle webhooks sent to us from Mux.
  17. –

    Create a MuxWwebhookController.
  18. –

    The controller only has one purpose, so we can make it invokable.
  19. –

    Add the new controller to our routes.
  20. –

    Finally open the class.
  21. –

    When you make a controller invokable, it creates a controller which has this
  22. –

    single "__invoke" method.
  23. –

    Mux will send webhooks as JSON requests, so we can just pass the webhook event
  24. –

    data
  25. –

    by passing the request body.
  26. –

    When we json_decode the data, if we specify "true" as the second argument,
  27. –

    that'll decode
  28. –

    the data as an associative array, no matter if the data is an array or an
  29. –

    object.
  30. –

    This makes working with decoded data from JSON payloads a bit easier.
  31. –

    So now, what events are we receiving and what does the data actually look like?
  32. –

    At this point, Mux can't actually send any data to us, because our Sail
  33. –

    environment
  34. –

    is not accessible on the Internet, so Mux will be able to deliver any events to
  35. –

    our
  36. –

    application.
  37. –

    Luckily, Sail has a handy "share" command that allows us to create a temporary
  38. –

    tunnel and
  39. –

    make our Sale-hosted website accessible on the Internet.
  40. –

    Copy this command.
  41. –

    Run it in the terminal window.
  42. –

    And if we click the public HTTP address, we should see our website in the browser.
  43. –

    This is our Sail-hosted website, but it's now available via a public URL.
  44. –

    We can now add our webhook URL to Mux.
  45. –

    Go to your Mux dashboard.
  46. –

    Go to "Settings".
  47. –

    Go to "Webhooks".
  48. –

    Click the "Create new webhook" button, leave the environment as default.
  49. –

    Paste your "sail share" URL.
  50. –

    And add "/mux/webhook" to the end.
  51. –

    Click the green "Create webhook" button.
  52. –

    Now, any time you createm update, or delete a Mux resource, we should get a
  53. –

    corresponding
  54. –

    webhook sent to us to our application.
  55. –

    We can test this by just logging anything Mux sends to us.
  56. –

    Back in the MuxWebhookController class, simply log the payload.
  57. –

    We'll also need to disable CSRF protection for this route.
  58. –

    Open up your VerifyCsrfToken middleware and add an exception for our Mux
  59. –

    webhook URL.
  60. –

    In a new terminal window, if we tail our Laravel log file, we should see the
  61. –

    contents of any
  62. –

    webhooks event sent to us when we perform an operation, such as uploading a file
  63. –

    .
  64. –

    I've just uploaded a file, so let's see what events we actually received.
  65. –

    The first event we received was video.upload.create.
  66. –

    This is created when we created upload URL.
  67. –

    Next, we received a video.asset.created event.
  68. –

    This is sent when an asset is being created off the back of an upload, so we
  69. –

    can assume
  70. –

    the upload is completed at this point.
  71. –

    Next, we received video.upload.asset_created.
  72. –

    This is dispatched when an asset is created off the back of an upload.
  73. –

    Finally, we received video.asset.ready.
  74. –

    This is sent when Mux has finished processing file and the file is ready for
  75. –

    streaming.
  76. –

    We received this event pretty shortly after uploading, as we only created test
  77. –

    assets
  78. –

    that were limited to 10 seconds in length, so don't require much processing.
  79. –

    This event will arrive much later after uploading upload if you upload and
  80. –

    files that are much
  81. –

    longer in duration.
  82. –

    Using these events, we can update the upload and the Mux status of our videos.
  83. –

    What we'll do is, set the "upload_status" to "complete" when we receive a
  84. –

    video.asset.created
  85. –

    event.
  86. –

    We'll also use the video ID as a "passthrough" parameter to find the
  87. –

    corresponding video,
  88. –

    and also set its "mux_asset_id" and "mux_playback_id" attributes.
  89. –

    We'll then update the "mux_status" to "ready" when we receive the video.asset.ready
  90. –

    event.
  91. –

    Whilst we didn't observe this event coming in, we'll also need to handle video
  92. –

    asset
  93. –

    error events.
  94. –

    These are sent when processing of a video fails, so we'll later update the
  95. –

    video's "mux_status"
  96. –

    accordingly.
  97. –

    If we look at a webhook payload, we can see that the event type is declared
  98. –

    under the
  99. –

    "type" key.
  100. –

    We can use a PHP match statement to handle the different events we want to
  101. –

    handle.
  102. –

    First let's start with the "video.asset.created" event.
  103. –

    We'll create a protected "handleVideoAssetCreated" method.
  104. –

    And call this when the event is received, passing through the payload as a
  105. –

    parameter.
  106. –

    Do the same for "video.asset.ready", and "video.asset.errored".
  107. –

    In our video.asset.created method, we now need to fetch the video by its ID and
  108. –

    update
  109. –

    it.
  110. –

    We have the "passthrough" value and use Laravel "Str::afterLast" helper to get
  111. –

    the ID.
  112. –

    Now let's retrieve the model.
  113. –

    And update its statuses.
  114. –

    Set the "upload_status" to "complete".
  115. –

    The "mux_status" to the status in the payload.
  116. –

    And we can also set the "mux_asset_id" and "mux_playback_id".
  117. –

    Let's also update the "mux_status" appropriately in our video.asset.ready and
  118. –

    video.asset.error
  119. –

    handler methods.
  120. –

    In our ready callback, we can also set the video duration from the duration
  121. –

    value that
  122. –

    comes back in the payload.
  123. –

    Now when we upload files, we should see the statuses of the video being updated
  124. –

    in the
  125. –

    database.
  126. –

    When the video is ready, we should also see the duration being set.

Resources