entity = $entity; $this->db = $db; $this->includes = $includes; $this->subscription_id = $subscription_id; } public function backoff() { return [10, 30, 60, 180, 3600]; } /** * Execute the job. * * @return bool */ public function handle() { MultiDB::setDb($this->db); $subscription = Webhook::with('company')->find($this->subscription_id); if($subscription) nlog("firing event ID {$subscription->event_id}"); if(!$subscription){ $this->fail(); nlog("failed to fire event, could not find webhook ID {$this->subscription_id}"); return; } $this->company = $subscription->company; $this->entity->refresh(); // generate JSON data $manager = new Manager(); $manager->setSerializer(new ArraySerializer()); $manager->parseIncludes($this->includes); $class = sprintf('App\\Transformers\\%sTransformer', class_basename($this->entity)); $transformer = new $class(); $resource = new Item($this->entity, $transformer, $this->entity->getEntityType()); $data = $manager->createData($resource)->toArray(); $this->postData($subscription, $data, []); } private function postData($subscription, $data, $headers = []) { $base_headers = [ 'Content-Length' => strlen(json_encode($data)), 'Accept' => 'application/json', ]; $client = new Client(['headers' => array_merge($base_headers, $headers)]); try { $response = $client->post($subscription->target_url, [ RequestOptions::JSON => $data, // or 'json' => [...] ]); SystemLogger::dispatch( array_merge((array) $response, $data), SystemLog::CATEGORY_WEBHOOK, SystemLog::EVENT_WEBHOOK_SUCCESS, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->resolveClient(), $this->company ); } catch(\GuzzleHttp\Exception\ConnectException $e){ nlog("connection problem"); nlog($e->getCode()); nlog($e->getMessage()); SystemLogger::dispatch( ['message' => "Error connecting to ". $subscription->target_url], SystemLog::CATEGORY_WEBHOOK, SystemLog::EVENT_WEBHOOK_FAILURE, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->resolveClient(), $this->company ); } catch (BadResponseException $e) { if ($e->getResponse()->getStatusCode() >= 400 && $e->getResponse()->getStatusCode() < 500){ $message = "Server encountered a problem when connecting to {$subscription->target_url} => status code ". $e->getResponse()->getStatusCode(). " scheduling retry."; nlog($message); SystemLogger::dispatch( ['message' => $message], SystemLog::CATEGORY_WEBHOOK, SystemLog::EVENT_WEBHOOK_FAILURE, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->resolveClient(), $this->company ); $this->release($this->backoff()[$this->attempts()-1]); } if($e->getResponse()->getStatusCode() >= 500){ nlog("endpoint returned a 500, failing"); $message = "Server encountered a problem when connecting to {$subscription->target_url} => status code ". $e->getResponse()->getStatusCode(). " no retry attempted."; SystemLogger::dispatch( ['message' => $message], SystemLog::CATEGORY_WEBHOOK, SystemLog::EVENT_WEBHOOK_FAILURE, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->resolveClient(), $this->company ); $this->fail(); return; } } catch (ServerException $e) { nlog("Server exception"); $error = json_decode($e->getResponse()->getBody()->getContents()); SystemLogger::dispatch( ['message' => $error], SystemLog::CATEGORY_WEBHOOK, SystemLog::EVENT_WEBHOOK_FAILURE, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->resolveClient(), $this->company ); } catch (ClientException $e) { nlog("Client exception"); $error = json_decode($e->getResponse()->getBody()->getContents()); SystemLogger::dispatch( ['message' => $error], SystemLog::CATEGORY_WEBHOOK, SystemLog::EVENT_WEBHOOK_FAILURE, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->resolveClient(), $this->company ); } catch (\Exception $e) { nlog("Exception handler => " . $e->getMessage()); nlog($e->getCode()); SystemLogger::dispatch( $e->getMessage(), SystemLog::CATEGORY_WEBHOOK, SystemLog::EVENT_WEBHOOK_FAILURE, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->resolveClient(), $this->company, ); $this->release($this->backoff()[$this->attempts()-1]); } } private function resolveClient() { //make sure it isn't an instance of the Client Model if (! $this->entity instanceof ClientModel && ! $this->entity instanceof Product && $this->entity->client()->exists()) { return $this->entity->client; } return null; } public function failed($exception = null) { if($exception){ nlog("failed in webhooksingle"); nlog($exception->getMessage()); } } }