diff --git a/app/Http/Requests/UserFormRequest.php b/app/Http/Requests/UserFormRequest.php index f972c57..5ec5a4a 100644 --- a/app/Http/Requests/UserFormRequest.php +++ b/app/Http/Requests/UserFormRequest.php @@ -42,6 +42,7 @@ abstract class UserFormRequest extends \Illuminate\Foundation\Http\FormRequest 'webhook_url' => 'url|nullable', 'use_captcha' => 'boolean', 'slack_webhook_url' => 'url|nullable', + 'discord_webhook_url' => 'url|nullable', // Customization 'theme' => ['required',Rule::in(Form::THEMES)], diff --git a/app/Http/Resources/FormResource.php b/app/Http/Resources/FormResource.php index c359c33..253a992 100644 --- a/app/Http/Resources/FormResource.php +++ b/app/Http/Resources/FormResource.php @@ -30,6 +30,7 @@ class FormResource extends JsonResource 'submissions_count' => $this->when($this->workspaceIsPro(), $this->submissions_count), 'notifies' => $this->notifies, 'notifies_slack' => $this->notifies_slack, + 'notifies_discord' => $this->notifies_discord, 'send_submission_confirmation' => $this->send_submission_confirmation, 'webhook_url' => $this->webhook_url, 'redirect_url' => $this->redirect_url, @@ -45,6 +46,7 @@ class FormResource extends JsonResource 'visibility' => $this->visibility, 'notification_emails' => $this->notification_emails, 'slack_webhook_url' => $this->slack_webhook_url, + 'discord_webhook_url' => $this->discord_webhook_url, 'removed_properties' => $this->removed_properties, 'last_edited_human' => $this->updated_at?->diffForHumans() ] : []; diff --git a/app/Listeners/Forms/NotifyFormSubmission.php b/app/Listeners/Forms/NotifyFormSubmission.php index 186e7cd..865ddcd 100644 --- a/app/Listeners/Forms/NotifyFormSubmission.php +++ b/app/Listeners/Forms/NotifyFormSubmission.php @@ -2,13 +2,15 @@ namespace App\Listeners\Forms; +use App\Models\Forms\Form; use App\Events\Forms\FormSubmitted; -use App\Notifications\Forms\FormSubmissionNotification; -use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Facades\Http; use Spatie\WebhookServer\WebhookCall; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Support\Facades\Notification; use App\Service\Forms\FormSubmissionFormatter; +use App\Notifications\Forms\FormSubmissionNotification; use Vinkla\Hashids\Facades\Hashids; class NotifyFormSubmission implements ShouldQueue @@ -44,8 +46,16 @@ class NotifyFormSubmission implements ShouldQueue // Send Slack Notification $this->sendSlackNotification($event); } + + if ($event->form->notifies_discord) { + // Send Discord Notification + $this->sendDiscordNotification($event); + } + + } + private function sendSlackNotification(FormSubmitted $event) { if($this->validateSlackWebhookUrl($event->form->slack_webhook_url)){ @@ -105,4 +115,75 @@ class NotifyFormSubmission implements ShouldQueue { return ($url) ? str_contains($url, 'https://hooks.slack.com/') : false; } + + private function sendDiscordNotification(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)), + + "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; + } } diff --git a/app/Models/Forms/Form.php b/app/Models/Forms/Form.php index f2f915e..725a2b5 100644 --- a/app/Models/Forms/Form.php +++ b/app/Models/Forms/Form.php @@ -39,6 +39,7 @@ class Form extends Model 'notification_body', 'notifications_include_submission', 'slack_webhook_url', + 'discord_webhook_url', // integrations 'webhook_url', @@ -98,6 +99,7 @@ class Form extends Model 'workspace_id', 'notifies', 'slack_webhook_url', + 'discord_webhook_url', 'webhook_url', 'send_submission_confirmation', 'redirect_url', @@ -250,6 +252,12 @@ class Form extends Model return FormFactory::new(); } + + public function getNotifiesDiscordAttribute() + { + return !empty($this->discord_webhook_url); + } + public function getNotifiesSlackAttribute() { return !empty($this->slack_webhook_url); diff --git a/app/Service/Forms/FormCleaner.php b/app/Service/Forms/FormCleaner.php index f46af77..b93bc60 100644 --- a/app/Service/Forms/FormCleaner.php +++ b/app/Service/Forms/FormCleaner.php @@ -39,6 +39,7 @@ class FormCleaner 'use_captcha' => false, 'password' => null, 'slack_webhook_url' => null, + 'discord_webhook_url' => null, ]; private array $fieldDefaults = [ @@ -70,6 +71,7 @@ class FormCleaner 'database_fields_update' => 'Form submission will only create new records (no updates).', 'theme' => 'Default theme was applied.', 'slack_webhook_url' => "Slack webhook disabled.", + 'discord_webhook_url' => "Discord webhook disabled.", // For fields 'hide_field_name' => 'Hide field name removed.', diff --git a/database/migrations/2023_01_28_142618_add_discord_url.php b/database/migrations/2023_01_28_142618_add_discord_url.php new file mode 100644 index 0000000..dd403f2 --- /dev/null +++ b/database/migrations/2023_01_28_142618_add_discord_url.php @@ -0,0 +1,32 @@ +string('discord_webhook_url')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('forms', function (Blueprint $table) { + $table->dropColumn('discord_webhook_url'); + }); + } +}; diff --git a/resources/js/components/open/forms/components/form-components/FormNotifications.vue b/resources/js/components/open/forms/components/form-components/FormNotifications.vue index 07049b6..b8f620e 100644 --- a/resources/js/components/open/forms/components/form-components/FormNotifications.vue +++ b/resources/js/components/open/forms/components/form-components/FormNotifications.vue @@ -11,11 +11,12 @@ - + + - + @@ -24,10 +25,11 @@ import Collapse from '../../../../common/Collapse.vue' import ProTag from '../../../../common/ProTag.vue' import FormNotificationsOption from './components/FormNotificationsOption.vue' import FormNotificationsSlack from './components/FormNotificationsSlack.vue' +import FormNotificationsDiscord from './components/FormNotificationsDiscord.vue' import FormNotificationsSubmissionConfirmation from './components/FormNotificationsSubmissionConfirmation.vue' export default { - components: { FormNotificationsSubmissionConfirmation, FormNotificationsSlack, FormNotificationsOption, Collapse, ProTag }, + components: { FormNotificationsSubmissionConfirmation, FormNotificationsSlack, FormNotificationsDiscord, FormNotificationsOption, Collapse, ProTag }, props: { }, data () { diff --git a/resources/js/components/open/forms/components/form-components/components/FormNotificationsDiscord.vue b/resources/js/components/open/forms/components/form-components/components/FormNotificationsDiscord.vue new file mode 100644 index 0000000..f8dc0de --- /dev/null +++ b/resources/js/components/open/forms/components/form-components/components/FormNotificationsDiscord.vue @@ -0,0 +1,74 @@ + + +