A presentation at Laravel Live UK in in London, UK by Lorna Jane Mitchell
Handling Webhooks with Laravel Lorna Mitchell, Nexmo
What is a Webhook? An HTTP POST request. @lornajane
Why Webhooks? Event-driven HTTP = Webhooks @lornajane
Webhooks in the Wild @lornajane
Slack Integrations @lornajane
GitHub Builds @lornajane
Webhook Use Cases • Notify of events • Deliver data when available • Broadcast to multiple receivers as-it-happens @lornajane
How APIs Work @lornajane
How APIs Work @lornajane
How APIs Work @lornajane
How APIs Work @lornajane
How Webhooks Work @lornajane
How Webhooks Work @lornajane
How Webhooks Work @lornajane
What About Time? @lornajane
APIs Over Time @lornajane
Webhooks Over Time @lornajane
Where To Webhook To? @lornajane
Webhooks Need Pre-arrangement With APIs, the client calls the server. With Webhooks, the client has to register with the server, to get data later. … may also agree security (e.g. shared secret) at this stage. @lornajane
Receiving Webhooks Warning: minor tangent ahead @lornajane
Ngrok for Testing Webhooks https://ngrok.com/ - secure tunnel to your dev platform Use this tool to: • webhook into code running locally • inspect the request and response of the webhook • replay requests and see the responses @lornajane
Ngrok for Testing Webhooks Start the tunnel on your laptop: receive a public URL @lornajane
Example: Nexmo SMS When you register a phone number and receive an SMS, your application receives a webhook. @lornajane
I’m running open endpoints on the internet and accepting data, now what? @lornajane
Webhook Security When working with webhooks: • be aware of attack vectors • always use SSL • consider shared secrets and hashing • all good HTTP security practices apply @lornajane
Shared Secrets Share a secret in advance, then transmit all the fields and a signature hash created using the secret. @lornajane
Nexmo SMS Security Nexmo can sign messages using a shared secret. The PHP library https://github.com/nexmo/nexmo-php can do this for you. $signature = new \Nexmo\Client\Signature($_GET, SIGNATURE_SECRET, ‘sha256’); $isValid = $signature->check($_GET[‘sig’]); @lornajane
Receiving Webhooks: Best Practice It’s just an HTTP request! Advice: • DO: accept, store and acknowledge quickly • DON’T: process before acknowledging @lornajane
Using Queues in PHP Applications Queues protect you against bursty traffic. Queues separate work from webservers. • This example uses https://beanstalkd.github.io/ and Laravel • Other good alternatives: Redis or Laravel Horizon, Amazon SQS, RabbitMQ @lornajane
Laravel and Beanstalkd 1 use App\Jobs\InboundSms; 2 Route::get(‘inbound-sms’, function(Request $request) { 3 // get incoming parameters (includes GET and POST) 4 $params = $request->input(); 5 $data = [“event” => “message”, “text” => $params[‘text’], 6 “receivedAt” => date(“U”), “payload” => $params]; 7 error_log(“New message: ” . $params[‘text’]); 8 9 InboundSms::dispatch($data); 10 return “OK”; 11 }); @lornajane
So The Data is In a Queue. Now What? @lornajane
Let’s talk about Workers Workers are long-running scripts that process a series of jobs. Workers need to be independent: • if things go wrong, exit • separate tool to monitor/restart as needed • beware long-running process hazards • everything processed “at least once” (but maybe more than once, and in any order…) @lornajane
Processing SMSes with Laravel 1 public function handle() 2 { 3 $params = $this->data; 4 $signature = new \Nexmo\Client\Signature($params[‘payload’], 5 config(‘nexmo.signature_secret’), ‘sha256’); 6 $isValid = $signature->check($params[‘payload’][‘sig’]); 7 8 if($isValid) { 9 error_log(“Message Verified: ” . $params[‘payload’][‘text’]); 10 } else { error_log(“Message Rejected”); } 11 } @lornajane
Webhooks … are awesome :) @lornajane
Webhooks in Your Applications • Use them WHEN you want to notify other systems • Examples of HOW to use webhooks hopefully gave you some ideas • Webhooks are HTTP: we already understand this @lornajane
Thanks! • PHP Web Services from O’Reilly • Nexmo: https://nexmo.com • Me: https://lornajane.net • Ngrok: https://ngrok.com/ • Nexmo for Laravel: https://github.com/Nexmo/nexmo-laravel • Code: https://github.com/lornajane/incoming-sms-laravel-beanstalkd @lornajane