Skip to content

Commit

Permalink
✨ remove closed reports from backend chat (#2802)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrKrisKrisu authored Jul 31, 2024
1 parent 2b86773 commit 0e00b7d
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 107 deletions.
11 changes: 4 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,14 @@ MIX_LEGAL_ADDRESS2="12345 Musterstadt"
MIX_LEGAL_EMAIL="[email protected]"
MIX_LEGAL_TEL="01234 / 56789"

# Telegram Bot credentials. Currently only used for the admin backend
TELEGRAM_ADMIN_ID=123456789
TELEGRAM_TOKEN=12345678:abcdefghijklmnop

# Should the year in review be visible to the users?
YEAR_IN_REVIEW_BACKEND=false
YEAR_IN_REVIEW_ALERT=false

# Webhook urls which will be called when a new event is suggested
ADMIN_NOTIFICATION_URL=https://api.telegram.org/bot.../sendMessage
ADMIN_NOTIFICATION_CHAT_ID=123456789
# Telegram Bot credentials - used for admin notifications
TELEGRAM_ADMIN_ACTIVE=false # Set to true to enable Telegram notifications
TELEGRAM_ADMIN_TOKEN=0000000000:0000000000000000000000000000
TELEGRAM_ADMIN_CHAT_ID=123456789

# Shall webhooks actually call other servers? Default is off to work privacy-preserving.
WEBHOOKS_ACTIVE=true
Expand Down
32 changes: 15 additions & 17 deletions app/Http/Controllers/Backend/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
use App\Models\EventSuggestion;
use App\Models\Station;
use App\Models\User;
use App\Services\TelegramService;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Http;

abstract class EventController extends Controller
{
Expand Down Expand Up @@ -39,22 +39,20 @@ public static function suggestEvent(
]);

try {
if (config('app.admin.notification.url') !== null) {
Http::post(config('app.admin.notification.url'), [
'chat_id' => config('app.admin.notification.chat_id'),
'text' => strtr("<b>New event suggestion:</b>" . PHP_EOL .
"Title: :name" . PHP_EOL .
"Begin: :begin" . PHP_EOL .
"End: :end" . PHP_EOL .
"Suggested by user: :username", [
':name' => $eventSuggestion->name,
':host' => $eventSuggestion->host,
':begin' => $eventSuggestion->begin->format('d.m.Y'),
':end' => $eventSuggestion->end->format('d.m.Y'),
':username' => $eventSuggestion->user->username,
]),
'parse_mode' => 'HTML',
]);
if (TelegramService::isAdminActive()) {
TelegramService::admin()->sendMessage(
strtr("<b>New event suggestion:</b>" . PHP_EOL .
"Title: :name" . PHP_EOL .
"Begin: :begin" . PHP_EOL .
"End: :end" . PHP_EOL .
"Suggested by user: :username", [
':name' => $eventSuggestion->name,
':host' => $eventSuggestion->host,
':begin' => $eventSuggestion->begin->format('d.m.Y'),
':end' => $eventSuggestion->end->format('d.m.Y'),
':username' => $eventSuggestion->user->username,
])
);
}
} catch (Exception $e) {
report($e);
Expand Down
25 changes: 12 additions & 13 deletions app/Http/Controllers/Frontend/Admin/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Models\Event;
use App\Models\EventSuggestion;
use App\Notifications\EventSuggestionProcessed;
use App\Services\TelegramService;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -107,9 +108,9 @@ public function denySuggestion(Request $request): RedirectResponse {
]);
$eventSuggestion = EventSuggestion::find($validated['id']);
$eventSuggestion->update(['processed' => true]);
if (!App::runningUnitTests() && config('app.admin.notification.url') !== null) {
if (!App::runningUnitTests() && config('services.telegram.admin.active')) {
Http::post(config('app.admin.notification.url'), [
'chat_id' => config('app.admin.notification.chat_id'),
'chat_id' => config('services.telegram.admin.chat_id'),
'text' => strtr("<b>Event suggestion denied</b>" . PHP_EOL .
"Title: :name" . PHP_EOL
. "Denial reason: :reason" . PHP_EOL
Expand Down Expand Up @@ -179,17 +180,15 @@ public function acceptSuggestion(Request $request): RedirectResponse {
]);

$eventSuggestion->update(['processed' => true]);
if (!App::runningUnitTests() && config('app.admin.notification.url') !== null) {
Http::post(config('app.admin.notification.url'), [
'chat_id' => config('app.admin.notification.chat_id'),
'text' => strtr("<b>Event suggestion accepted</b>" . PHP_EOL .
"Title: :name" . PHP_EOL
. "Accepting user: :username" . PHP_EOL, [
':name' => $eventSuggestion->name,
':username' => auth()->user()->username,
]),
'parse_mode' => 'HTML',
]);
if (!App::runningUnitTests() && TelegramService::isAdminActive()) {
TelegramService::admin()->sendMessage(
strtr("<b>Event suggestion accepted</b>" . PHP_EOL .
"Title: :name" . PHP_EOL
. "Accepting user: :username" . PHP_EOL, [
':name' => $eventSuggestion->name,
':username' => auth()->user()->username,
])
);
}

$eventSuggestion->user->notify(new EventSuggestionProcessed($eventSuggestion, $event));
Expand Down
15 changes: 6 additions & 9 deletions app/Http/Controllers/FrontendStatusController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace App\Http\Controllers;

use App\Http\Controllers\Backend\EventController as EventBackend;
use App\Http\Controllers\Backend\Support\LocationController;
use App\Http\Controllers\Backend\Transport\StationController;
use App\Http\Controllers\Backend\User\DashboardController;
use App\Http\Controllers\Backend\User\ProfilePictureController;
Expand All @@ -13,7 +11,6 @@
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\View\View;

/**
Expand All @@ -25,18 +22,18 @@ public function getDashboard(): Renderable|RedirectResponse {
$statuses = DashboardController::getPrivateDashboard(auth()->user());

return view('dashboard', [
'statuses' => $statuses,
'latest' => StationController::getLatestArrivals(auth()->user()),
'future' => StatusBackend::getFutureCheckins(),
'statuses' => $statuses,
'latest' => StationController::getLatestArrivals(auth()->user()),
'future' => StatusBackend::getFutureCheckins(),
'showGlobalButton' => auth()->user()->follows->count() === 0
]);
}

public function getGlobalDashboard(): Renderable {
return view('dashboard', [
'statuses' => DashboardController::getGlobalDashboard(Auth::user()),
'latest' => StationController::getLatestArrivals(Auth::user()),
'future' => StatusBackend::getFutureCheckins(),
'statuses' => DashboardController::getGlobalDashboard(Auth::user()),
'latest' => StationController::getLatestArrivals(Auth::user()),
'future' => StatusBackend::getFutureCheckins(),
'showGlobalButton' => false
]);
}
Expand Down
19 changes: 12 additions & 7 deletions app/Models/Report.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,24 @@
* @property ReportReason $reason
* @property string $description
* @property int $reporter_id
* @property int $admin_notification_id
*/
class Report extends Model
{
use LogsActivity;

protected $fillable = ['status', 'subject_type', 'subject_id', 'reason', 'description', 'reporter_id'];
protected $fillable = [
'status', 'subject_type', 'subject_id', 'reason',
'description', 'reporter_id', 'admin_notification_id'
];
protected $casts = [
'status' => ReportStatus::class,
'subject_type' => 'string',
'subject_id' => 'integer',
'reason' => ReportReason::class,
'description' => 'string',
'reporter_id' => 'integer',
'status' => ReportStatus::class,
'subject_type' => 'string',
'subject_id' => 'integer',
'reason' => ReportReason::class,
'description' => 'string',
'reporter_id' => 'integer',
'admin_notification_id' => 'integer' //telegram message id
];

public function reporter(): BelongsTo {
Expand Down
31 changes: 20 additions & 11 deletions app/Observers/ReportObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,33 @@

namespace App\Observers;

use App\Enum\Report\ReportStatus;
use App\Models\Report;
use App\Services\TelegramService;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Http;

class ReportObserver
{
public function created(Report $report): void {
if (App::runningUnitTests() || config('app.admin.notification.url') === null) {
if (App::runningUnitTests() || !TelegramService::isAdminActive()) {
return;
}
Http::post(config('app.admin.notification.url'), [
'chat_id' => config('app.admin.notification.chat_id'),
'text' => "<b>🚨 New Report for " . $report->subject_type . "</b>" . PHP_EOL
. "Reason: " . $report->reason?->value . PHP_EOL
. "Description: " . ($report->description ?? 'None') . PHP_EOL
. "View Report: " . config('app.url') . "/admin/reports/" . $report->id . PHP_EOL
,
'parse_mode' => 'HTML',
]);
$telegramMessageId = TelegramService::admin()->sendMessage("<b>🚨 New Report for " . $report->subject_type . "</b>" . PHP_EOL
. "Reason: " . $report->reason?->value . PHP_EOL
. "Description: " . ($report->description ?? 'None') . PHP_EOL
. "View Report: " . config('app.url') . "/admin/reports/" . $report->id . PHP_EOL);
$report->update(['admin_notification_id' => $telegramMessageId]);
}

public function updated(Report $report): void {
if (App::runningUnitTests() || !TelegramService::isAdminActive()) {
return;
}
$statusBefore = $report->getOriginal('status');
$statusAfter = $report->status;

if ($statusBefore === ReportStatus::OPEN && $statusAfter === ReportStatus::CLOSED && $report->admin_notification_id) {
TelegramService::admin()->deleteMessage($report->admin_notification_id);
}
}
}
46 changes: 46 additions & 0 deletions app/Services/TelegramService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php declare(strict_types=1);

namespace App\Services;

use Illuminate\Support\Facades\Http;

class TelegramService
{

const TELEGRAM_API_URL = 'https://api.telegram.org/bot';

private string $chatId;
private string $token;

public function __construct(string $chatId, string $token) {
$this->chatId = $chatId;
$this->token = $token;
}

public static function isAdminActive(): bool {
return config('services.telegram.admin.active');
}

public static function admin(): self {
return new self(config('services.telegram.admin.chat_id'), config('services.telegram.admin.token'));
}

/**
* @return int Telegram Message ID
*/
public function sendMessage(string $text, string $parseMode = 'HTML'): int {
$response = Http::post(self::TELEGRAM_API_URL . $this->token . '/sendMessage', [
'chat_id' => $this->chatId,
'text' => $text,
'parse_mode' => $parseMode,
]);
return $response->json('result.message_id');
}

public function deleteMessage(int $messageId): void {
Http::post(self::TELEGRAM_API_URL . $this->token . '/deleteMessage', [
'chat_id' => $this->chatId,
'message_id' => $messageId,
]);
}
}
13 changes: 0 additions & 13 deletions config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,18 +264,6 @@
'email' => env('MIX_LEGAL_EMAIL')
],

'telegram' => [
'admin_id' => env('TELEGRAM_ADMIN_ID'),
'token' => env('TELEGRAM_TOKEN')
],

'admin' => [
'notification' => [
'url' => env('ADMIN_NOTIFICATION_URL'),
'chat_id' => env('ADMIN_NOTIFICATION_CHAT_ID'),
]
],

'privacy' => [
'account-deletion' => [
'send-notification' => (bool) env('PRIVACY_ACCOUNT_DELETION_SEND_NOTIFICATION', false),
Expand All @@ -284,5 +272,4 @@
],

'wikidata_fetcher_enabled' => env('WIKIDATA_FETCHER_ENABLED', false),

];
38 changes: 8 additions & 30 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,18 @@
|
*/

'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],

'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],

'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],

'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],

'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
'webhook' => [
'secret' => env('STRIPE_WEBHOOK_SECRET'),
'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300),
],
],

'mastodon' => [
'domain' => env('MASTODON_DOMAIN'),
'client_id' => env('MASTODON_ID'),
'client_secret' => env('MASTODON_SECRET'),
'redirect' => env('MASTODON_REDIRECT'),
],

'telegram' => [
'admin' => [
'active' => env('TELEGRAM_ADMIN_ACTIVE', false),
'chat_id' => env('TELEGRAM_ADMIN_CHAT_ID'),
'token' => env('TELEGRAM_ADMIN_TOKEN'),
]
]
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void {
Schema::table('reports', static function(Blueprint $table) {
$table->unsignedBigInteger('admin_notification_id')->nullable()->after('reporter_id');
});
}

public function down(): void {
Schema::table('reports', static function(Blueprint $table) {
$table->dropColumn('admin_notification_id');
});
}
};

0 comments on commit 0e00b7d

Please sign in to comment.