diff --git a/README.md b/README.md index f036007..2ff6e2c 100644 --- a/README.md +++ b/README.md @@ -451,6 +451,22 @@ With the command below you can add a webhook to your Survey: php artisan surveyhero:add-webhooks --eventType=response.completed --url=https://webhook.site/complete-response ``` +### List webhooks + +With the command below you can list all the webhooks of your Survey: + +```shell +php artisan surveyhero:list-webhooks --survey=12345 +``` + +### Delete a webhook + +With the command below you can delete a webhook from your Survey: + +```shell +php artisan surveyhero:delete-webhook --survey=12345 --webhook=2553 +``` + ### Webhook handlers We have also implemented a default controller (`SurveyheroWebhookController.php`) to handle the webhook responses. Currently, it only supports the diff --git a/src/Commands/SurveyheroWebhookCommand.php b/src/Commands/SurveyheroWebhookAddCommand.php similarity index 97% rename from src/Commands/SurveyheroWebhookCommand.php rename to src/Commands/SurveyheroWebhookAddCommand.php index c479eaa..7558ca9 100644 --- a/src/Commands/SurveyheroWebhookCommand.php +++ b/src/Commands/SurveyheroWebhookAddCommand.php @@ -7,7 +7,7 @@ use Statikbe\Surveyhero\Services\SurveyWebhookService; use Statikbe\Surveyhero\SurveyheroRegistrar; -class SurveyheroWebhookCommand extends Command +class SurveyheroWebhookAddCommand extends Command { public $signature = 'surveyhero:add-webhooks {--survey=all : The Surveyhero survey ID} diff --git a/src/Commands/SurveyheroWebhookDeleteCommand.php b/src/Commands/SurveyheroWebhookDeleteCommand.php new file mode 100644 index 0000000..a6cac1a --- /dev/null +++ b/src/Commands/SurveyheroWebhookDeleteCommand.php @@ -0,0 +1,51 @@ +webhookService = $webhookService; + } + + public function handle(): int + { + $surveyId = trim($this->option('survey')); + $webhookId = trim($this->option('webhook')); + + $surveys = app(SurveyheroRegistrar::class)->getSurveyClass()::query()->where('surveyhero_id', $surveyId)->get(); + + foreach ($surveys as $survey) { + /* @var SurveyContract $survey */ + try { + $this->webhookService->deleteWebhook($survey, $webhookId); + $this->comment('Webhook #'.$webhookId.' for survey #'.$surveyId.' deleted'); + } catch (\Exception $e) { + $this->error($e->getMessage()); + + return self::FAILURE; + } + } + + return self::SUCCESS; + } +} diff --git a/src/Commands/SurveyheroWebhookListCommand.php b/src/Commands/SurveyheroWebhookListCommand.php new file mode 100644 index 0000000..093fa9d --- /dev/null +++ b/src/Commands/SurveyheroWebhookListCommand.php @@ -0,0 +1,66 @@ +webhookService = $webhookService; + } + + public function handle(): int + { + $surveyId = trim($this->option('survey')); + + $surveyQuery = app(SurveyheroRegistrar::class)->getSurveyClass()::query(); + if ($surveyId !== 'all') { + $surveyQuery->where('surveyhero_id', $surveyId); + } + $surveys = $surveyQuery->get(); + + foreach ($surveys as $survey) { + /* @var SurveyContract $survey */ + try { + $webhooks = $this->webhookService->listWebhooks($survey); + $webhookData = []; + foreach($webhooks as $webhook) { + $webhookData[] = [ + $webhook->webhook_id, + $webhook->event_type, + $webhook->url, + $webhook->status, + $webhook->created_on, + ]; + } + $this->table( + ['Webhook id','Event type','Url','Status','Created'], + $webhookData + ); + } catch (\Exception $e) { + $this->error($e->getMessage()); + + return self::FAILURE; + } + } + + return self::SUCCESS; + } +} diff --git a/src/Http/SurveyheroClient.php b/src/Http/SurveyheroClient.php index 0e56e2f..25f4510 100644 --- a/src/Http/SurveyheroClient.php +++ b/src/Http/SurveyheroClient.php @@ -4,6 +4,7 @@ use Carbon\Carbon; use Illuminate\Support\Facades\Http; +use stdClass; class SurveyheroClient { @@ -77,6 +78,13 @@ public function getSurveyLanguages(string|int $surveyId): array return $languages ? $languages->languages : []; } + public function listWebhooks(string|int $surveyId): ?array + { + $webhookData = $this->fetchFromSurveyHero(sprintf('surveys/%s/webhooks', $surveyId)); + + return $webhookData->successful() ? json_decode($webhookData->body())->webhooks : null; + } + public function createWebhook(string|int $surveyId, string $eventType, string $url, string $status = 'active') { $body = [ @@ -88,6 +96,13 @@ public function createWebhook(string|int $surveyId, string $eventType, string $u $this->postToSurveyHero(sprintf('surveys/%s/webhooks', $surveyId), $body); } + public function deleteWebhook(string|int $surveyId, string|int $webhookId): ?stdClass + { + $webhookData = $this->deleteFromSurveyHero(sprintf('surveys/%s/webhooks/%s', $surveyId, $webhookId)); + + return $webhookData->successful() ? json_decode($webhookData->body()) : null; + } + public function deleteResponse(string|int $surveyId, string|int $responseId) { $this->deleteFromSurveyHero(sprintf('surveys/%s/responses/%s', $surveyId, $responseId)); @@ -98,6 +113,9 @@ public function transformAPITimestamp(string $surveyheroTimestamp): Carbon return Carbon::createFromFormat('Y-m-d\TH:i:s', substr($surveyheroTimestamp, 0, strpos($surveyheroTimestamp, '+'))); } + /** + * @throws \Exception + */ private function fetchFromSurveyHero(string $urlPath, array $queryStringArgs = []): \Illuminate\Http\Client\Response { $this->preventThrottle(); @@ -115,6 +133,9 @@ private function fetchFromSurveyHero(string $urlPath, array $queryStringArgs = [ throw new \Exception($response->body()); } + /** + * @throws \Exception + */ private function postToSurveyHero(string $urlPath, array $queryStringArgs = []): \Illuminate\Http\Client\Response { $this->preventThrottle(); diff --git a/src/Services/SurveyWebhookService.php b/src/Services/SurveyWebhookService.php index bb360aa..fd8dabf 100644 --- a/src/Services/SurveyWebhookService.php +++ b/src/Services/SurveyWebhookService.php @@ -6,6 +6,17 @@ class SurveyWebhookService extends AbstractSurveyheroAPIService { + /** + * Lists all webhooks for a certain Surveyhero survey + * + * @param SurveyContract $survey + * @return void + */ + public function listWebhooks(SurveyContract $survey): ?array + { + return $this->client->listWebhooks($survey->surveyhero_id); + } + /** * Creates a webhook for Surveyhero to notify on the given event type. * @@ -16,4 +27,16 @@ public function createWebhook(SurveyContract $survey, string $eventType, string { $this->client->createWebhook($survey->surveyhero_id, $eventType, $url, 'active'); } + + /** + * Deletes a webhooks for a certain Surveyhero survey + * + * @param SurveyContract $survey + * @param string|int $webhookId + * @return void + */ + public function deleteWebhook(SurveyContract $survey, string|int $webhookId): void + { + $this->client->deleteWebhook($survey->surveyhero_id, $webhookId); + } } diff --git a/src/SurveyheroServiceProvider.php b/src/SurveyheroServiceProvider.php index be6bbe9..856f98c 100644 --- a/src/SurveyheroServiceProvider.php +++ b/src/SurveyheroServiceProvider.php @@ -8,7 +8,9 @@ use Statikbe\Surveyhero\Commands\SurveyheroQuestionsAndAnswersImportCommand; use Statikbe\Surveyhero\Commands\SurveyheroResponseImportCommand; use Statikbe\Surveyhero\Commands\SurveyheroSurveyImportCommand; -use Statikbe\Surveyhero\Commands\SurveyheroWebhookCommand; +use Statikbe\Surveyhero\Commands\SurveyheroWebhookAddCommand; +use Statikbe\Surveyhero\Commands\SurveyheroWebhookDeleteCommand; +use Statikbe\Surveyhero\Commands\SurveyheroWebhookListCommand; use Statikbe\Surveyhero\Commands\SurveyResponseExportCommand; class SurveyheroServiceProvider extends PackageServiceProvider @@ -30,7 +32,9 @@ public function configurePackage(Package $package): void SurveyheroResponseImportCommand::class, SurveyheroQuestionsAndAnswersImportCommand::class, SurveyheroMapperCommand::class, - SurveyheroWebhookCommand::class, + SurveyheroWebhookAddCommand::class, + SurveyheroWebhookListCommand::class, + SurveyheroWebhookDeleteCommand::class, SurveyResponseExportCommand::class, ]); }