mirror of https://github.com/pixelfed/pixelfed
Add admin report email notifications
parent
05ee7f2cff
commit
4e1d0ed596
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\ReportPipeline;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Mail\AdminNewAutospam;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class AutospamNotifyAdminViaEmail implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $report;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($report)
|
||||
{
|
||||
$this->report = $report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$addresses = config('instance.reports.email.to');
|
||||
|
||||
if(config('instance.reports.email.enabled') == false || empty($addresses) || !config('instance.reports.email.autospam')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(strpos($addresses, ',')) {
|
||||
$to = explode(',', $addresses);
|
||||
} else {
|
||||
$to = $addresses;
|
||||
}
|
||||
|
||||
Mail::to($to)->send(new AdminNewAutospam($this->report));
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\ReportPipeline;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Mail\AdminNewReport;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ReportNotifyAdminViaEmail implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $report;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($report)
|
||||
{
|
||||
$this->report = $report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$addresses = config('instance.reports.email.to');
|
||||
|
||||
if(config('instance.reports.email.enabled') == false || empty($addresses)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(strpos($addresses, ',')) {
|
||||
$to = explode(',', $addresses);
|
||||
} else {
|
||||
$to = $addresses;
|
||||
}
|
||||
|
||||
Mail::to($to)->send(new AdminNewReport($this->report));
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Services\AccountService;
|
||||
use App\Services\StatusService;
|
||||
|
||||
class AdminNewAutospam extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public $report;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($report)
|
||||
{
|
||||
$this->report = $report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope()
|
||||
{
|
||||
return new Envelope(
|
||||
subject: '[' . config('pixelfed.domain.app') . '] Spam Post Detected',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content()
|
||||
{
|
||||
$data = $this->report->toArray();
|
||||
$reported_status = null;
|
||||
$reported_account = null;
|
||||
$url = url('/i/admin/reports/autospam/' . $this->report->id);
|
||||
|
||||
if($data['item_type'] === 'App\Status') {
|
||||
$reported_status = StatusService::get($this->report->item_id, false);
|
||||
$reported_account = AccountService::get($reported_status['account']['id'], true);
|
||||
}
|
||||
|
||||
return new Content(
|
||||
markdown: 'emails.admin.new_autospam',
|
||||
with: [
|
||||
'report' => $data,
|
||||
'url' => $url,
|
||||
'reported_status' => $reported_status,
|
||||
'reported_account' => $reported_account
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachments for the message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attachments()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Services\AccountService;
|
||||
use App\Services\StatusService;
|
||||
|
||||
class AdminNewReport extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public $report;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($report)
|
||||
{
|
||||
$this->report = $report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope()
|
||||
{
|
||||
$type = $this->report->type;
|
||||
$id = $this->report->id;
|
||||
$object_type = last(explode("\\", $this->report->object_type));
|
||||
return new Envelope(
|
||||
subject: '[' . config('pixelfed.domain.app') . '] ' . $object_type . ' Report (#' . $id . '-' . $type . ')',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content()
|
||||
{
|
||||
$report = $this->report;
|
||||
$object_type = last(explode("\\", $this->report->object_type));
|
||||
$reporter = AccountService::get($report->profile_id, true);
|
||||
$reported = AccountService::get($report->reported_profile_id, true);
|
||||
$title = 'New ' . $object_type . ' Report (#' . $report->id . ')';
|
||||
$reportUrl = url('/i/admin/reports/show/' . $report->id . '?ref=email');
|
||||
$data = [
|
||||
'report' => $report,
|
||||
'object_type' => $object_type,
|
||||
'title' => $title,
|
||||
'reporter' => $reporter,
|
||||
'reported' => $reported,
|
||||
'url' => $reportUrl,
|
||||
'message' => 'You have a new moderation report.'
|
||||
];
|
||||
|
||||
if($object_type === 'Status') {
|
||||
$data['reported_status'] = StatusService::get($report['object_id'], false);
|
||||
if($reporter && $reported) {
|
||||
$data['message'] = '<a href="' . url('/i/web/profile/' . $reporter['id']) . '">@' .
|
||||
$reporter['acct'] . '</a> reported a post by <a href="' . url('/i/web/profile/' . $reported['id']) .
|
||||
'">@' . $reported['acct'] . '</a> as ' . $report->type . '.';
|
||||
}
|
||||
}
|
||||
|
||||
if($object_type === 'Profile') {
|
||||
if($reporter && $reported) {
|
||||
$data['message'] = '<a href="' . url('/i/web/profile/' . $reporter['id']) . '">@' .
|
||||
$reporter['acct'] . '</a> reported <a href="' . url('/i/web/profile/' . $reported['id']) .
|
||||
'">@' . $reported['acct'] . '</a>\'s profile as ' . $report->type . '.';
|
||||
}
|
||||
}
|
||||
|
||||
return new Content(
|
||||
markdown: 'emails.admin.new_report',
|
||||
with: $data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachments for the message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attachments()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
<x-mail::message>
|
||||
# Autospam Detection (#{{ $report['id'] }})
|
||||
|
||||
We have detected a potential spam post. The post has been unlisted from public feeds.
|
||||
**Action is required to restore post visibility**. <br />
|
||||
Please review this report and handle accordingly.
|
||||
|
||||
<x-mail::button :url="$url">
|
||||
Review Autospam Report
|
||||
</x-mail::button>
|
||||
|
||||
@if($reported_status)
|
||||
<x-mail::panel>
|
||||
<p style="font-size: 13px; color: #cccccc; text-align: center; font-weight: bold;margin-bottom: 10px;">Reported Status</p>
|
||||
<div style="display: flex; align-items: center;gap: 10px;">
|
||||
@if(
|
||||
isset($reported_status['media_attachments']) &&
|
||||
isset($reported_status['pf_type']) &&
|
||||
count($reported_status['media_attachments']) &&
|
||||
in_array($reported_status['pf_type'], ['photo', 'photo:album'])
|
||||
)
|
||||
<img
|
||||
src="{{$reported_status['media_attachments'][0]['url']}}"
|
||||
width="100"
|
||||
height="100"
|
||||
alt="Media preview"
|
||||
style="object-fit: cover; border: 1px solid #cccccc; border-radius: 10px; margin-bottom: 10px;"
|
||||
onerror="this.src='{{url('/storage/no-preview.png')}}';this.onerror=null;" />
|
||||
@endif
|
||||
@if(isset($reported_status['content']))
|
||||
<div style="font-size: 12px !important;">{{ strip_tags(str_replace(["\n", "\r", "\r\n"], ' ', $reported_status['content'])) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; justify-content: space-between;margin-top:10px;">
|
||||
<a style="font-size: 11px !important;font-weight: bold;text-decoration: none;" href="{{ url('/i/web/post/' . $reported_status['id'])}}">
|
||||
View status
|
||||
</a>
|
||||
<p style="font-size: 11px !important;font-weight: bold;">
|
||||
Posted {{ now()->parse($reported_status['created_at'])->diffForHumans() }}
|
||||
</p>
|
||||
</div>
|
||||
</x-mail::panel>
|
||||
@endif
|
||||
|
||||
@if($reported_account && isset($reported_account['id']))
|
||||
<x-mail::panel>
|
||||
<p style="font-size: 13px; color: #cccccc; text-align: center; font-weight: bold;margin-bottom: 10px;">Reported Account</p>
|
||||
|
||||
<div style="display: flex; align-items: flex-start;gap: 10px;">
|
||||
|
||||
<img
|
||||
src="{{$reported_account['avatar']}}"
|
||||
width="50"
|
||||
height="50"
|
||||
alt="Avatar"
|
||||
style="border-radius: 10px;min-width: 50px;flex-grow: 1;"
|
||||
onerror="this.src='{{url('/storage/avatars/default.jpg')}}';this.onerror=null;" />
|
||||
<div>
|
||||
|
||||
<p style="margin-bottom: 0;">
|
||||
<a href="{{ url('/i/web/profile/' . $reported_account['id']) }}" style="text-decoration: none;font-weight: bold">{{ $reported_account['username'] }}</a>
|
||||
</p>
|
||||
|
||||
<p style="margin-bottom: 5px;font-size: 10px;opacity: 0.5;">
|
||||
{{ strip_tags(str_replace(["\n", "\r", "\r\n"], ' ', $reported_account['note'])) }}
|
||||
</p>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 5px;">
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reported_account['statuses_count'] }} posts</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reported_account['followers_count'] }} followers</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reported_account['following_count'] }} following</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">Joined {{ now()->parse($reported_account['created_at'])->diffForHumans()}}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-mail::panel>
|
||||
@endif
|
||||
|
||||
<p style="font-size: 12px;color: #cccccc;text-align: center;">
|
||||
This is an automated email that is intended for administrators of {{ config('pixelfed.domain.app')}}.<br />
|
||||
If you received this email by mistake, kindly disregard and delete this email.
|
||||
</p>
|
||||
</x-mail::message>
|
@ -0,0 +1,122 @@
|
||||
<x-mail::message>
|
||||
# {{ $title }}
|
||||
|
||||
## {!! $message !!}
|
||||
|
||||
<x-mail::button :url="$url">
|
||||
View Report
|
||||
</x-mail::button>
|
||||
|
||||
@if($object_type === 'Status' && $reported_status)
|
||||
<x-mail::panel>
|
||||
<p style="font-size: 13px; color: #cccccc; text-align: center; font-weight: bold;margin-bottom: 10px;">Reported Status</p>
|
||||
<div style="display: flex; align-items: center;gap: 10px;">
|
||||
@if(
|
||||
isset($reported_status['media_attachments']) &&
|
||||
isset($reported_status['pf_type']) &&
|
||||
count($reported_status['media_attachments']) &&
|
||||
in_array($reported_status['pf_type'], ['photo', 'photo:album'])
|
||||
)
|
||||
<img
|
||||
src="{{$reported_status['media_attachments'][0]['url']}}"
|
||||
width="100"
|
||||
height="100"
|
||||
alt="Media preview"
|
||||
style="object-fit: cover; border: 1px solid #cccccc; border-radius: 10px; margin-bottom: 10px;"
|
||||
onerror="this.src='{{url('/storage/no-preview.png')}}';this.onerror=null;" />
|
||||
@endif
|
||||
@if(isset($reported_status['content']))
|
||||
<div style="font-size: 12px !important;">{{ strip_tags(str_replace(["\n", "\r", "\r\n"], ' ', $reported_status['content'])) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; justify-content: space-between;margin-top:10px;">
|
||||
<a style="font-size: 11px !important;font-weight: bold;text-decoration: none;" href="{{ url('/i/web/post/' . $reported_status['id'])}}">
|
||||
View status
|
||||
</a>
|
||||
<p style="font-size: 11px !important;font-weight: bold;">
|
||||
Posted {{ now()->parse($reported_status['created_at'])->diffForHumans() }}
|
||||
</p>
|
||||
</div>
|
||||
</x-mail::panel>
|
||||
@endif
|
||||
|
||||
@if($reported && isset($reported['id']))
|
||||
<x-mail::panel>
|
||||
<p style="font-size: 13px; color: #cccccc; text-align: center; font-weight: bold;margin-bottom: 10px;">Reported Account</p>
|
||||
|
||||
<div style="display: flex; align-items: flex-start;gap: 10px;">
|
||||
|
||||
<img
|
||||
src="{{$reported['avatar']}}"
|
||||
width="50"
|
||||
height="50"
|
||||
alt="Avatar"
|
||||
style="border-radius: 10px;min-width: 50px;flex-grow: 1;"
|
||||
onerror="this.src='{{url('/storage/avatars/default.jpg')}}';this.onerror=null;" />
|
||||
<div>
|
||||
|
||||
<p style="margin-bottom: 0;">
|
||||
<a href="{{ url('/i/web/profile/' . $reported['id']) }}" style="text-decoration: none;font-weight: bold">{{ $reported['username'] }}</a>
|
||||
</p>
|
||||
|
||||
<p style="margin-bottom: 5px;font-size: 10px;opacity: 0.5;">
|
||||
{{ strip_tags(str_replace(["\n", "\r", "\r\n"], ' ', $reported['note'])) }}
|
||||
</p>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 5px;">
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reported['statuses_count'] }} posts</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reported['followers_count'] }} followers</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reported['following_count'] }} following</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">Joined {{ now()->parse($reported['created_at'])->diffForHumans()}}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-mail::panel>
|
||||
@endif
|
||||
|
||||
@if($reporter && isset($reporter['id']))
|
||||
<x-mail::panel>
|
||||
<p style="font-size: 13px; color: #cccccc; text-align: center; font-weight: bold;margin-bottom: 10px;">Reported By</p>
|
||||
|
||||
<div style="display: flex; align-items: flex-start;gap: 10px;">
|
||||
|
||||
<img
|
||||
src="{{$reporter['avatar']}}"
|
||||
width="50"
|
||||
height="50"
|
||||
alt="Avatar"
|
||||
style="border-radius: 10px;min-width: 50px;flex-grow: 1;"
|
||||
onerror="this.src='{{url('/storage/avatars/default.jpg')}}';this.onerror=null;" />
|
||||
<div>
|
||||
|
||||
<p style="margin-bottom: 0;"><a href="{{ url('/i/web/profile/' . $reporter['id']) }}" style="text-decoration: none;font-weight: bold">{{ $reporter['username'] }}</a>
|
||||
</p>
|
||||
|
||||
<p style="margin-bottom: 5px;font-size: 10px;opacity: 0.5;">
|
||||
{{ strip_tags(str_replace(["\n", "\r", "\r\n"], ' ', $reporter['note'])) }}
|
||||
</p>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 5px;">
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reporter['statuses_count'] }} posts</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reporter['followers_count'] }} followers</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">{{ $reporter['following_count'] }} following</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">·</p>
|
||||
<p style="font-size: 10px;margin-bottom: 0;">Joined {{ now()->parse($reporter['created_at'])->diffForHumans()}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-mail::panel>
|
||||
@endif
|
||||
|
||||
<p style="font-size: 12px;color: #cccccc;text-align: center;">
|
||||
This is an automated email that is intended for administrators of {{ config('pixelfed.domain.app')}}.<br />
|
||||
If you received this email by mistake, kindly disregard and delete this email.
|
||||
</p>
|
||||
|
||||
</x-mail::message>
|
Loading…
Reference in New Issue