Add slack support to Firefly III

This commit is contained in:
James Cole 2022-09-24 12:14:27 +02:00
parent 2945f5fcde
commit 45d7042405
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
10 changed files with 138 additions and 17 deletions

View File

@ -75,8 +75,9 @@ class HomeController extends Controller
foreach (config('firefly.admin_notifications') as $item) {
$notifications[$item] = FireflyConfig::get(sprintf('notification_%s', $item), true)->data;
}
$slackUrl = FireflyConfig::get('slack_webhook_url', '')->data;
return view('admin.index', compact('title', 'mainTitleIcon', 'email', 'notifications'));
return view('admin.index', compact('title', 'mainTitleIcon', 'email', 'notifications', 'slackUrl'));
}
public function notifications(Request $request): RedirectResponse
@ -86,7 +87,14 @@ class HomeController extends Controller
if ($request->has(sprintf('notification_%s', $item))) {
$value = true;
}
FireflyConfig::set(sprintf('notification_%s',$item), $value);
FireflyConfig::set(sprintf('notification_%s', $item), $value);
}
$url = (string) $request->get('slackUrl');
if ('' === $url) {
FireflyConfig::delete('slack_webhook_url');
}
if (str_starts_with($url, 'https://hooks.slack.com/services/')) {
FireflyConfig::set('slack_webhook_url', $url);
}
session()->flash('success', (string) trans('firefly.notification_settings_saved'));

View File

@ -101,6 +101,7 @@ class PreferencesController extends Controller
$languages = config('firefly.languages');
$locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
$listPageSize = app('preferences')->get('listPageSize', 50)->data;
$slackUrl = app('preferences')->get('slack_webhook_url', '')->data;
$customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
$fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
$fiscalYearStart = date('Y') . '-' . $fiscalYearStartStr;
@ -139,6 +140,7 @@ class PreferencesController extends Controller
'frontPageAccounts',
'languages',
'notifications',
'slackUrl',
'locales',
'locale',
'tjOptionalFields',
@ -173,12 +175,12 @@ class PreferencesController extends Controller
// extract notifications:
$all = $request->all();
foreach(config('firefly.available_notifications') as $option) {
foreach (config('firefly.available_notifications') as $option) {
$key = sprintf('notification_%s', $option);
if(array_key_exists($key, $all)) {
if (array_key_exists($key, $all)) {
app('preferences')->set($key, true);
}
if(!array_key_exists($key, $all)) {
if (!array_key_exists($key, $all)) {
app('preferences')->set($key, false);
}
}
@ -190,6 +192,16 @@ class PreferencesController extends Controller
session()->forget('end');
session()->forget('range');
// slack URL:
$url = (string) $request->get('slackUrl');
if(str_starts_with($url, 'https://hooks.slack.com/services/')){
app('preferences')->set('slack_webhook_url', $url);
}
if('' === $url) {
app('preferences')->delete('slack_webhook_url');
}
// custom fiscal year
$customFiscalYear = 1 === (int) $request->get('customFiscalYear');
$string = strtotime((string) $request->get('fiscalYearStart'));

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Notifications\Admin;
use FireflyIII\Mail\AdminTestMail;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
/**
@ -54,7 +55,7 @@ class TestNotification extends Notification
*/
public function via($notifiable)
{
return ['mail'];
return ['mail', 'slack'];
}
/**
@ -69,6 +70,16 @@ class TestNotification extends Notification
->markdown('emails.admin-test', ['email' => $this->address])
->subject((string) trans('email.admin_test_subject'));
}
/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)->content((string)trans('email.admin_test_subject'));
}
/**
* Get the array representation of the notification.

View File

@ -25,8 +25,12 @@ namespace FireflyIII\Notifications\Admin;
use FireflyIII\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
/**
* Class UserRegistration
*/
class UserRegistration extends Notification
{
use Queueable;
@ -46,18 +50,18 @@ class UserRegistration extends Notification
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
return ['mail', 'slack'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
@ -67,10 +71,21 @@ class UserRegistration extends Notification
->subject((string) trans('email.registered_subject_admin'));
}
/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)->content((string) trans('email.admin_new_user_registered', ['email' => $this->user->email, 'id' => $this->user->id]));
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)

View File

@ -22,9 +22,9 @@ declare(strict_types=1);
namespace FireflyIII\Notifications\Admin;
use FireflyIII\Models\Bill;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
/**
@ -35,7 +35,7 @@ class VersionCheckResult extends Notification
{
use Queueable;
private string $message;
private string $message;
/**
* Create a new notification instance.
@ -55,7 +55,7 @@ class VersionCheckResult extends Notification
*/
public function via($notifiable)
{
return ['mail'];
return ['mail', 'slack'];
}
/**
@ -69,7 +69,21 @@ class VersionCheckResult extends Notification
return (new MailMessage)
->markdown('emails.new-version', ['message' => $this->message])
->subject((string)trans('email.new_version_email_subject'));
->subject((string) trans('email.new_version_email_subject'));
}
/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)->content($this->message)
->attachment(function ($attachment) {
$attachment->title('Firefly III @ GitHub', 'https://github.com/firefly-iii/firefly-iii/releases');
});
}
/**

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Notifications\User;
use FireflyIII\Models\Bill;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
/**
@ -58,7 +59,7 @@ class BillReminder extends Notification
*/
public function via($notifiable)
{
return ['mail'];
return ['mail', 'slack'];
}
/**
@ -79,6 +80,28 @@ class BillReminder extends Notification
->subject($subject);
}
/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
$message = (string) trans(sprintf('email.bill_warning_subject_%s', $this->field), ['diff' => $this->diff, 'name' => $this->bill->name]);
if (0 === $this->diff) {
$message = (string) trans(sprintf('email.bill_warning_subject_now_%s', $this->field), ['diff' => $this->diff, 'name' => $this->bill->name]);
}
$bill = $this->bill;
$url = route('bills.show', [$bill->id]);
return (new SlackMessage)
->warning()
->attachment(function ($attachment) use ($bill, $url) {
$attachment->title((string) trans('firefly.visit_bill', ['name' => $bill->name]), $url);
})
->content($message);
}
/**
* Get the array representation of the notification.
*

View File

@ -48,6 +48,9 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
use FireflyIII\Models\Webhook;
use FireflyIII\Notifications\Admin\TestNotification;
use FireflyIII\Notifications\Admin\UserRegistration;
use FireflyIII\Notifications\Admin\VersionCheckResult;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
@ -578,4 +581,25 @@ class User extends Authenticatable
};
}
/**
* Route notifications for the Slack channel.
*
* @param Notification $notification
* @return string
*/
public function routeNotificationForSlack(Notification $notification): string
{
// this check does not validate if the user is owner, Should be done by notification itself.
if ($notification instanceof TestNotification) {
return app('fireflyconfig')->get('slack_webhook_url', '')->data;
}
if ($notification instanceof UserRegistration) {
return app('fireflyconfig')->get('slack_webhook_url', '')->data;
}
if ($notification instanceof VersionCheckResult) {
return app('fireflyconfig')->get('slack_webhook_url', '')->data;
}
return app('preferences')->getForUser($this, 'slack_webhook_url', '')->data;
}
}

View File

@ -1051,6 +1051,10 @@ return [
'pref_notification_user_login' => 'Alert when you login from a new location',
'pref_notifications' => 'Notifications',
'pref_notifications_help' => 'Indicate if these are notifications you would like to get. Some notifications may contain sensitive financial information.',
'slack_webhook_url' => 'Slack Webhook URL',
'slack_webhook_url_help' => 'If you want Firefly III to notify you using Slack, enter the webhook URL here. Otherwise leave the field blank. If you are an admin, you need to set this URL in the administration as well.',
'slack_url_label' => 'Slack "incoming webhook" URL',
// profile:
'delete_stuff_header' => 'Delete data',
'permanent_delete_stuff' => 'Be careful with these buttons. Deleting stuff is permanent.',
@ -1349,6 +1353,7 @@ return [
// bills:
'not_expected_period' => 'Not expected this period',
'not_or_not_yet' => 'Not (yet)',
'visit_bill' => 'Visit bill ":name" at Firefly III',
'match_between_amounts' => 'Bill matches transactions between :low and :high.',
'running_again_loss' => 'Previously linked transactions to this bill may lose their connection, if they (no longer) match the rule(s).',
'bill_related_rules' => 'Rules related to this bill',
@ -1978,7 +1983,7 @@ return [
'delete_user' => 'Delete user :email',
'user_deleted' => 'The user has been deleted',
'send_test_email' => 'Send test email message',
'send_test_email_text' => 'To see if your installation is capable of sending email, please press this button. You will not see an error here (if any), <strong>the log files will reflect any errors</strong>. You can press this button as many times as you like. There is no spam control. The message will be sent to <code>:email</code> and should arrive shortly.',
'send_test_email_text' => 'To see if your installation is capable of sending email or posting Slack messages, please press this button. You will not see an error here (if any), <strong>the log files will reflect any errors</strong>. You can press this button as many times as you like. There is no spam control. The message will be sent to <code>:email</code> and should arrive shortly.',
'send_message' => 'Send message',
'send_test_triggered' => 'Test was triggered. Check your inbox and the log files.',
'give_admin_careful' => 'Users who are given admin rights can take away yours. Be careful.',
@ -1986,9 +1991,10 @@ return [
'admin_maintanance_expl' => 'Some nifty buttons for Firefly III maintenance',
'admin_maintenance_clear_cache' => 'Clear cache',
'admin_notifications' => 'Admin notifications',
'admin_notifications_expl' => 'The following notifications can be enabled or disabled by the administrator.',
'admin_notifications_expl' => 'The following notifications can be enabled or disabled by the administrator. If you want to get these messages over Slack as well, set the "incoming webhook" URL.',
'admin_notification_check_user_new_reg' => 'User gets post-registration welcome message',
'admin_notification_check_admin_new_reg' => 'Administrator(s) get new user registration notification',
'admin_notification_check_new_version' => 'A new version is available',
'save_notification_settings' => 'Save settings',
'notification_settings_saved' => 'The notification settings have been saved',

View File

@ -47,6 +47,7 @@
</label>
</div>
{% endfor %}
{{ ExpandedForm.text('slackUrl', slackUrl, {'label' : 'slack_url_label'|_}) }}
</div>
<div class="box-footer">
<button type="submit" class="btn btn-success">

View File

@ -260,6 +260,13 @@
{% endfor %}
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="preferences-box">
<h3>{{ 'slack_webhook_url'|_ }}</h3>
<p class="text-info">{{ 'slack_webhook_url_help'|_ }}</p>
{{ ExpandedForm.text('slackUrl',slackUrl,{'label' : 'slack_url_label'|_}) }}
</div>
</div>
</div>
</div>
</div>