Skip to content

Commit

Permalink
Add Telegram-Channel Notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Tschucki committed Feb 27, 2024
1 parent 1dbea87 commit 871d566
Show file tree
Hide file tree
Showing 17 changed files with 211 additions and 44 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,6 @@ VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
PR0GRAMM_CLIENT_ID=
PR0GRAMM_CLIENT_SECRET=
PR0GRAMM_REDIRECT_URI=

TELEGRAM_BOT_TOKEN=
TELEGRAM_CHANNEL_CHAT_ID=
3 changes: 1 addition & 2 deletions app/Filament/Actions/PollPreviewAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\HtmlString;
use Str;

class PollPreviewAction
{
Expand All @@ -28,7 +27,7 @@ public static function make($fullPreview = true): Action

if ($fullPreview) {
$preview[] = Placeholder::make('Titel')->content($poll->title);
$preview[] = Placeholder::make('Beschreibung')->content(fn () => new HtmlString('<div class="prose dark:prose-invert">'.Str::markdown($poll->description).'</div>'))->visible(fn () => $poll->description);
$preview[] = Placeholder::make('Beschreibung')->content(fn () => new HtmlString('<div class="prose dark:prose-invert">'.$poll->description.'</div>'))->visible(fn () => (bool) $poll->description);
}

$preview[] = Section::make('Fragen')->schema(function () use ($poll) {
Expand Down
14 changes: 1 addition & 13 deletions app/Filament/Resources/MyPollResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,7 @@ public static function form(Form $form): Form
Components\Toggle::make('not_anonymous')->label('Möchtest du die Umfrage so veröffentlichen, dass dein Name sichtbar ist?')->inline(false)->required()->default(true)->helperText('Es geht nur darum ob dein Name bei der Umfrage angezeigt wird. Das pr0p0ll-Team sieht natürlich, dass du diese Umfrage erstellt hast. Das soll dafür sorgen, dass Teilnehmer nicht beeinflusst werden.'),
TextInput::make('title')->label('Titel')->maxLength(255)->required(),
Select::make('category_id')->label('Kategorie')->options(fn () => Category::where('enabled', true)->pluck('title', 'id'))->nullable()->native(false),
Components\MarkdownEditor::make('description')->toolbarButtons([
'blockquote',
'bold',
'bulletList',
'heading',
'italic',
'link',
'orderedList',
'redo',
'strike',
'table',
'undo',
])->label('Beschreibung')->nullable(),
Textarea::make('description')->label('Beschreibung')->nullable(),
Select::make('closes_after')->label('Ende der Umfrage')->hint('Nachdem die Umfrage genehmigt wurde')->options(ClosesAfter::class)->default('+3 weeks')->required()->helperText('Es wird dir nicht möglich sein, die Umfrage frühzeitig zu beenden.'),
]),
Components\Tabs\Tab::make('Zielgruppe')->schema([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@

class MyPollResults extends Page
{
use InteractsWithRecord;
use InteractsWithForms;
use InteractsWithRecord;

#[Url(as: 'gender')]
public ?string $gender = '';

#[Url(as: 'region')]
public ?array $region = [];

#[Url(as: 'nationality')]
public ?array $nationality = [];

#[Url(as: 'min_age')]
public ?string $min_age = '';

#[Url(as: 'max_age')]
public ?string $max_age = '';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Yepsua\Filament\Forms\Components\Rating;

use function Filament\Support\is_app_url;

/**
Expand All @@ -45,7 +46,7 @@ class PollParticipation extends Page

public function getTitle(): string|\Illuminate\Contracts\Support\Htmlable
{
return 'An ' . '"' . $this->record->title . '"' . ' teilnehmen';
return 'An '.'"'.$this->record->title.'"'.' teilnehmen';
}

public function mount(int|string $record): void
Expand All @@ -69,7 +70,7 @@ public function participate(): void

$anonymousUser = Auth::user()?->createAnonymousUser();

if (!$anonymousUser) {
if (! $anonymousUser) {
Notification::make('error')->danger()->title('Fehler beim Speichern')->body('Es konnte kein anonymer User angelegt werden.')->send();
throw new Halt('Es konnte kein anonymer User angelegt werden.');
}
Expand All @@ -85,15 +86,15 @@ public function participate(): void

$areAllIdsInCurrentPoll = $questionKeys->diff($currentPollQuestions)->isEmpty();

if (!$areAllIdsInCurrentPoll) {
if (! $areAllIdsInCurrentPoll) {
Notification::make('error')->danger()->title('Das ist ja komisch')->body('Du hast mehr beantwortet, als es Fragen gibt...')->send();
throw new Halt('Du hast mehr beantwortet, als es Fragen gibt...');
}

DB::transaction(function () use ($tempData, $anonymousUser) {
collect($tempData)->filter(fn($answer) => $answer !== null)->each(function ($answer, $key) use ($anonymousUser) {
collect($tempData)->filter(fn ($answer) => $answer !== null)->each(function ($answer, $key) use ($anonymousUser) {
$question = Question::find($key);
if (!$question) {
if (! $question) {
Notification::make('error')->danger()->title('Fehler beim Speichern')->body("Die Frage mit der ID {$key} konnte nicht gefunden werden.")->send();
DB::rollBack();
throw new Halt("Die Frage mit der ID {$key} konnte nicht gefunden werden.");
Expand Down
6 changes: 4 additions & 2 deletions app/Models/AnonymousUser.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
Expand All @@ -8,11 +10,11 @@
class AnonymousUser extends Model
{
protected $fillable = [
'demographic_data'
'demographic_data',
];

protected $casts = [
'demographic_data' => 'array'
'demographic_data' => 'array',
];

public function answers(): HasMany
Expand Down
2 changes: 1 addition & 1 deletion app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function canAccessPanel(Panel $panel): bool

public function isAdmin(): bool
{
return (bool)$this->admin;
return (bool) $this->admin;
}

public function scopeAdmin(Builder $query): void
Expand Down
94 changes: 94 additions & 0 deletions app/Notifications/NewPollAvailableNotification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace App\Notifications;

use App\Models\Polls\Poll;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use NotificationChannels\Telegram\TelegramMessage;

class NewPollAvailableNotification extends Notification
{
use Queueable;

/**
* Create a new notification instance.
*/
public function __construct()
{
//
}

/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return [
'telegram',
];
}

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}

public function toTelegram($notifiable): TelegramMessage
{
$poll = Poll::first();
$url = route('filament.pr0p0ll.resources.public-polls.teilnehmen', [
'record' => $poll,
]);

$message = TelegramMessage::create()
->to(config('services.telegram-bot-api.channel'))
->line('*📊 Neue Umfrage verfügbar!*'."\n")
->line("*Titel: {$poll->title}*\n")
->when($poll->description, function (TelegramMessage $message) use ($poll) {
$message->line('*Beschreibung:* '.$poll->description);
})
->when($poll->category, function (TelegramMessage $message) use ($poll) {
$message->line("*\nKategorie:* {$poll->category->title}");
})
->when($poll->not_anonymous, function (TelegramMessage $message) use ($poll) {
$pr0UserName = $poll->user->name;
$pr0grammUserProfileUrl = 'https://pr0gramm.com/'.$pr0UserName;
$message->line("*\nBenutzer:* [$pr0UserName]($pr0grammUserProfileUrl)");
})
->line("*\nEndet in:* ".Carbon::make($poll->closes_after)?->diffForHumans()."\n")
->line("*\nURL:* [$url]($url)")
->button('Jetzt teilnehmen', $url);

return $message;
}

public function toPr0gramm($notifiable): string
{
return 'Hallo, es wurde eine neue Umfrage veröffentlicht. Jetzt teilnehmen.';
}

/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
//
];
}
}
5 changes: 2 additions & 3 deletions app/Providers/Filament/Pr0p0llPanelProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
use App\Filament\Pages\UpdateUserData;
use App\Filament\Widgets\NeedsDataReviewWidget;
use Filament\Enums\ThemeMode;
use Filament\FilamentManager;
use Filament\Facades\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Navigation\MenuItem;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Illuminate\Contracts\View\View;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
Expand All @@ -24,8 +25,6 @@
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Leandrocfe\FilamentApexCharts\FilamentApexChartsPlugin;
use Filament\Facades\Filament;
use Illuminate\Contracts\View\View;

class Pr0p0llPanelProvider extends PanelProvider
{
Expand Down
18 changes: 9 additions & 9 deletions app/Services/PollFormService.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,15 @@ private function getComponent(\App\Models\QuestionType $questionType, Question $
$questionKey = $question->getKey();

return match ($component) {
QuestionType::SINGLE->value => Radio::make((string)$questionKey),
QuestionType::MULTIPLE->value => CheckboxList::make((string)$questionKey),
QuestionType::TEXT->value => Textarea::make((string)$questionKey)->hint('Nicht anonym - Max. 255 Zeichen')->maxLength(255),
QuestionType::TOGGLE->value => Toggle::make((string)$questionKey)->default(false)->inline(false),
QuestionType::DATE->value => DatePicker::make((string)$questionKey),
QuestionType::TIME->value => DateTimePicker::make((string)$questionKey)->seconds(false)->date(false)->time()->displayFormat('HH:mm'),
QuestionType::DATETIME->value => DateTimePicker::make((string)$questionKey)->seconds(false)->displayFormat('DD.MM.YYYY HH:mm'),
QuestionType::COLOR->value => ColorPicker::make((string)$questionKey),
QuestionType::NUMBER->value => TextInput::make((string)$questionKey)->numeric(),
QuestionType::SINGLE->value => Radio::make((string) $questionKey),
QuestionType::MULTIPLE->value => CheckboxList::make((string) $questionKey),
QuestionType::TEXT->value => Textarea::make((string) $questionKey)->hint('Nicht anonym - Max. 255 Zeichen')->maxLength(255),
QuestionType::TOGGLE->value => Toggle::make((string) $questionKey)->default(false)->inline(false),
QuestionType::DATE->value => DatePicker::make((string) $questionKey),
QuestionType::TIME->value => DateTimePicker::make((string) $questionKey)->seconds(false)->date(false)->time()->displayFormat('HH:mm'),
QuestionType::DATETIME->value => DateTimePicker::make((string) $questionKey)->seconds(false)->displayFormat('DD.MM.YYYY HH:mm'),
QuestionType::COLOR->value => ColorPicker::make((string) $questionKey),
QuestionType::NUMBER->value => TextInput::make((string) $questionKey)->numeric(),
default => throw new \InvalidArgumentException('Unknown question type'),
};
}
Expand Down
1 change: 0 additions & 1 deletion app/Services/PollResultService.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use App\Models\AnswerTypes\SingleOptionAnswer;
use App\Models\Polls\MyPoll;
use App\Models\Question;
use Filament\Notifications\Notification;
use Filament\Widgets\WidgetConfiguration;
use Illuminate\Support\Collection;

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"filament/filament": "^3.1",
"guzzlehttp/guzzle": "^7.2",
"inertiajs/inertia-laravel": "^0.6.11",
"laravel-notification-channels/telegram": "^4.0",
"laravel/framework": "^10.10",
"laravel/sanctum": "^3.3",
"laravel/tinker": "^2.8",
Expand Down
75 changes: 74 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 871d566

Please sign in to comment.