Purchase access to watch this video.

Unlock course for £159

Already purchased access? Login

Listening for Mux webhooks

  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

Connect GitHub