Working with Webhooks

A presentation at Sunshine PHP 2019 in February 2019 in Miami, FL, USA by Lorna Jane Mitchell

Slide 1

Slide 1

Working with Webhooks Lorna Mitchell, Nexmo

Slide 2

Slide 2

What is a Webhook? An HTTP POST request. @lornajane

Slide 3

Slide 3

Why Webhooks? Event-driven HTTP = Webhooks @lornajane

Slide 4

Slide 4

Webhooks in the Wild @lornajane

Slide 5

Slide 5

Slack Integrations @lornajane

Slide 6

Slide 6

GitHub Builds @lornajane

Slide 7

Slide 7

Webhook Use Cases • Notify of events • Deliver data when available • Broadcast to multiple receivers as-it-happens @lornajane

Slide 8

Slide 8

How APIs Work @lornajane

Slide 9

Slide 9

How APIs Work @lornajane

Slide 10

Slide 10

How APIs Work @lornajane

Slide 11

Slide 11

How APIs Work @lornajane

Slide 12

Slide 12

How Webhooks Work @lornajane

Slide 13

Slide 13

How Webhooks Work @lornajane

Slide 14

Slide 14

How Webhooks Work @lornajane

Slide 15

Slide 15

What About Time? @lornajane

Slide 16

Slide 16

APIs Over Time @lornajane

Slide 17

Slide 17

Webhooks Over Time @lornajane

Slide 18

Slide 18

Slide 19

Slide 19

Where To Webhook To? @lornajane

Slide 20

Slide 20

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. @lornajane

Slide 21

Slide 21

Receiving Webhooks Warning: minor tangent ahead @lornajane

Slide 22

Slide 22

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

Slide 23

Slide 23

Ngrok for Testing Webhooks Start the tunnel on your laptop: receive a public URL @lornajane

Slide 24

Slide 24

Example: Nexmo SMS When you register a phone number and receive an SMS, your application receives a webhook. @lornajane

Slide 25

Slide 25

I’m running open endpoints on the internet and accepting data, now what? @lornajane

Slide 26

Slide 26

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

Slide 27

Slide 27

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

Slide 28

Slide 28

Slide 29

Slide 29

Receiving Webhooks: Best Practice It’s just an HTTP request! Advice: • DO: accept, store and acknowledge quickly • DON’T: process before acknowledging @lornajane

Slide 30

Slide 30

Using Queues in PHP Applications Queues protect you against bursty traffic. Queues separate work from webservers. • This example uses https://beanstalkd.github.io/ and pheanstalk\pheanstalk from Composer. • Other good alternatives: Laravel Horizon, Amazon SQS, RabbitMQ @lornajane

Slide 31

Slide 31

SlimPHP and Beanstalkd 1 $container = $app->getContainer(); 2 3 $container[‘queue’] = function ($container) { 4 return new \Pheanstalk\Pheanstalk( 5 getenv(‘QUEUE_HOST’), 6 getenv(‘QUEUE_PORT’) 7 ); 8 }; Pro-tip: Try vlucas\phpdotenv for dev platform environment vars. @lornajane

Slide 32

Slide 32

SlimPHP and Beanstalkd 13 $app->get(‘/webhooks/inbound-sms’, function ($request, $response, $arg 14 $params = $request->getQueryParams(); 15 16 $data = [“event” => “message”, 17 “text” => $params[‘text’], 18 “receivedAt” => date(“U”), 19 “payload” => $params]; 20 error_log(“New message: ” . $params[‘text’]); 21 $this->queue->useTube(‘sms’) 22 ->put(json_encode($data)); 23 }); @lornajane

Slide 33

Slide 33

So The Data is In a Queue. Now What? @lornajane

Slide 34

Slide 34

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

Slide 35

Slide 35

Processing SMSes 13 while($job = $queue->reserve()) { 14 $received = json_decode($job->getData(), true); 15 error_log($received[‘text’]); 16 17 // delegate to the class that will do the work 18 $worker->process($received); 19 20 $queue->delete($job); 21 } @lornajane

Slide 36

Slide 36

Processing SMSes 9 class Worker { 10 public function process($data) { 11 $this->write_to_file($this->outfile, $data[‘text’]); 12 } 13 14 protected function write_to_file($filename, $text) { 15 file_put_contents( $filename, 16 $text . “\n”, 17 FILE_APPEND 18 ); 19 } @lornajane

Slide 37

Slide 37

Slide 38

Slide 38

Serverless Webhook Endpoints Serverless technology: • Functions as a Service • Scalable: ideal for bursty workloads • Pay-as-you-go, and with free tiers • PHP supported on some platforms (they all support NodeJS) @lornajane

Slide 39

Slide 39

Serverless PHP SMS Reply Code Example 4 function main(array $params) : array { 5 $cookie = getCookies()[random_int(0, 430)]; 6 parse_str($params[‘__ow_query’], $query); 7 8 $url = “https://rest.nexmo.com/sms/json”; 9 $options = [“http” => [ “method” => “POST”, “content” => json_enco 10 $context = stream_context_create($options); 11 $response = file_get_contents($url, false, $context); 12 return [“body” => $cookie]; 13 } @lornajane

Slide 40

Slide 40

Serverless PHP SMS Reply Deployment Zip the code (and dependencies if needed), then deploy rm -f sms-fortune.zip zip -rq sms-fortune.zip index.php ibmcloud fn action update sms-fortune/incoming-php \ —kind php:7.2 —web raw sms-fortune.zip Link your Nexmo number to the URL of this action, share and enjoy. Here’s one I made earlier: 201-579-9898 @lornajane

Slide 41

Slide 41

Webhooks … are awesome :) @lornajane

Slide 42

Slide 42

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

Slide 43

Slide 43

Thanks! • Feedback please! https://joind.in/ • PHP Web Services from O’Reilly • Nexmo: https://nexmo.com • Me: https://lornajane.net • Ngrok: https://ngrok.com/ • Code: https://github.com/lornajane/fortunes-by-sms • Code: https://github.com/lornajane/incoming-sms-beanstalkd-php @lornajane