Skip to content

Commit

Permalink
Merge branch 'main' into 2c01e-field-logic-error-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
formsdev committed Aug 30, 2023
2 parents cfd497a + ec26c21 commit 200fdc2
Show file tree
Hide file tree
Showing 15 changed files with 471 additions and 238 deletions.
38 changes: 38 additions & 0 deletions app/Listeners/FailedWebhookListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace App\Listeners;

use App\Notifications\Forms\FailedWebhookNotification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Spatie\WebhookServer\Events\WebhookCallFailedEvent;

class FailedWebhookListener
{
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle(WebhookCallFailedEvent $event)
{
// Notify form owner
if ($event->meta['type'] == 'form_submission') {
$event->meta['form']->creator->notify(new FailedWebhookNotification($event));
\Log::error('Failed form submission webhook', [
'webhook_url' => $event->webhookUrl,
'exception' => $event->errorType,
'message' => $event->errorMessage,
'form_id' => $event->meta['form']->id
]);
return;
}

\Log::error('Failed webhook', [
'webhook_url' => $event->webhookUrl,
'exception' => $event->errorType,
'message' => $event->errorMessage
]);
}
}
185 changes: 33 additions & 152 deletions app/Listeners/Forms/NotifyFormSubmission.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Notification;
use App\Service\Forms\FormSubmissionFormatter;
use App\Service\Forms\Webhooks\WebhookHandlerProvider;
use App\Notifications\Forms\FormSubmissionNotification;
use Vinkla\Hashids\Facades\Hashids;

class NotifyFormSubmission implements ShouldQueue
{
Expand All @@ -25,165 +25,46 @@ class NotifyFormSubmission implements ShouldQueue
*/
public function handle(FormSubmitted $event)
{
if (!$event->form->is_pro) return;
$this->sendEmailNotifications($event);

if ($event->form->notifies) {
// Send Email Notification
$subscribers = collect(preg_split("/\r\n|\n|\r/", $event->form->notification_emails))->filter(function($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
});
\Log::debug('Sending email notification',[
'recipients' => $subscribers->toArray(),
'form_id' => $event->form->id,
'form_slug' => $event->form->slug,
]);
$subscribers->each(function ($subscriber) use ($event) {
Notification::route('mail', $subscriber)->notify(new FormSubmissionNotification($event));
});
}

if ($event->form->notifies_slack) {
// Send Slack Notification
$this->sendSlackNotification($event);
}

if ($event->form->notifies_discord) {
// Send Discord Notification
$this->sendDiscordNotification($event);
$this->sendWebhookNotification($event, WebhookHandlerProvider::SIMPLE_WEBHOOK_PROVIDER);
$this->sendWebhookNotification($event, WebhookHandlerProvider::SLACK_PROVIDER);
$this->sendWebhookNotification($event, WebhookHandlerProvider::DISCORD_PROVIDER);
foreach ($event->form->zappierHooks as $hook) {
$hook->triggerHook($event->data);
}


}


private function sendSlackNotification(FormSubmitted $event)
private function sendWebhookNotification(FormSubmitted $event, string $provider)
{
if($this->validateSlackWebhookUrl($event->form->slack_webhook_url)){
$submissionString = "";
$formatter = (new FormSubmissionFormatter($event->form, $event->data))->outputStringsOnly();
foreach ($formatter->getFieldsWithValue() as $field) {
$tmpVal = is_array($field['value']) ? implode(",", $field['value']) : $field['value'];
$submissionString .= ">*".ucfirst($field['name'])."*: ".$tmpVal." \n";
}

$formURL = url("forms/".$event->form->slug);
$editFormURL = url("forms/".$event->form->slug."/show");
$submissionId = Hashids::encode($event->data['submission_id']);
$externalLinks = [
'*<'.$formURL.'|🔗 Open Form>*',
'*<'.$editFormURL.'|✍️ Edit Form>*'
];
if($event->form->editable_submissions){
$externalLinks[] = '*<'.$event->form->share_url.'?submission_id='.$submissionId.'|✍️ '.$event->form->editable_submissions_button_text.'>*';
}

$finalSlackPostData = [
'blocks' => [
[
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => 'New submission for your form *<'.$formURL.'|'.$event->form->title.':>*',
]
],
[
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => $submissionString
]
],
[
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => implode(' ', $externalLinks),
]
],
]
];

WebhookCall::create()
->url($event->form->slack_webhook_url)
->doNotSign()
->payload($finalSlackPostData)
->dispatch();
}
}

private function validateSlackWebhookUrl($url)
{
return ($url) ? str_contains($url, 'https://hooks.slack.com/') : false;
WebhookHandlerProvider::getProvider(
$event->form,
$event->data,
$provider
)->handle();
}

private function sendDiscordNotification(FormSubmitted $event)
/**
* Sends an email to each email address in the form's notification_emails field
* @param FormSubmitted $event
* @return void
*/
private function sendEmailNotifications(FormSubmitted $event)
{
if($this->validateDiscordWebhookUrl($event->form->discord_webhook_url)){
$submissionString = "";
$formatter = (new FormSubmissionFormatter($event->form, $event->data))->outputStringsOnly();

foreach ($formatter->getFieldsWithValue() as $field) {
$tmpVal = is_array($field['value']) ? implode(",", $field['value']) : $field['value'];
$submissionString .= "**".ucfirst($field['name'])."**: `".$tmpVal."`\n";
}

$form_name = $event->form->title;
$form = Form::find($event->form->id);
$formURL = url("forms/".$event->form->slug."/show/submissions");

$finalDiscordPostData = [
"content" => "@here We have received a new submission for **$form_name**",
"username" => config('app.name'),
"avatar_url" => asset('img/logo.png'),
"tts" => false,
"embeds" => [
[
"title" => "🔗 Go to $form_name",

"type" => "rich",

"description" => $submissionString,

"url" => $formURL,

"color" => hexdec(str_replace('#', '', $event->form->color)),
if (!$event->form->is_pro || !$event->form->notifies) return;

"footer" => [
"text" => config('app.name'),
"icon_url" => asset('img/logo.png'),
],

"author" => [
"name" => config('app.name'),
"url" => config('app.url'),
],

"fields" => [
[
"name" => "Views 👀",
"value" => "$form->views_count",
"inline" => true
],
[
"name" => "Submissions 🖊️",
"value" => "$form->submissions_count",
"inline" => true
]
]
]
]
];

WebhookCall::create()
->url($event->form->discord_webhook_url)
->doNotSign()
->payload($finalDiscordPostData)
->dispatch();
}
}

private function validateDiscordWebhookUrl($url)
{
return ($url) ? str_contains($url, 'https://discord.com/api/webhooks') : false;
$subscribers = collect(preg_split("/\r\n|\n|\r/", $event->form->notification_emails))->filter(function (
$email
) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
});
\Log::debug('Sending email notification', [
'recipients' => $subscribers->toArray(),
'form_id' => $event->form->id,
'form_slug' => $event->form->slug,
]);
$subscribers->each(function ($subscriber) use ($event) {
Notification::route('mail', $subscriber)->notify(new FormSubmissionNotification($event));
});
}
}
77 changes: 0 additions & 77 deletions app/Listeners/Forms/PostFormDataToWebhook.php

This file was deleted.

5 changes: 5 additions & 0 deletions app/Models/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ public function getShareUrlAttribute()
return url('/forms/'.$this->slug);
}

public function getEditUrlAttribute()
{
return url('/forms/'.$this->slug.'/show');
}

public function getSubmissionsCountAttribute()
{
return $this->submissions()->count();
Expand Down
15 changes: 9 additions & 6 deletions app/Models/Integration/FormZapierWebhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Models\Integration;

use App\Models\Forms\Form;
use App\Service\Forms\Webhooks\WebhookHandlerProvider;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
Expand All @@ -27,11 +28,13 @@ public function form()
return $this->belongsTo(Form::class);
}

public function triggerHook(array $data) {
WebhookCall::create()
->url($this->hook_url)
->doNotSign()
->payload($data)
->dispatch();
public function triggerHook(array $data)
{
WebhookHandlerProvider::getProvider(
$this->form,
$data,
WebhookHandlerProvider::ZAPIER_PROVIDER,
$this->hook_url
)->handle();
}
}
Loading

0 comments on commit 200fdc2

Please sign in to comment.