per-worker ntfy topics for targeted push notifications

Evelin receives all booking notifications via the shared ntfy topic in config.
Each worker also gets notified on their own personal ntfy topic (set per-worker
in the admin panel) — so workers only see their own booking events.

- _ntfy() now accepts optional $workerTopic and sends to both topics if different
- All three call sites (new/modify/cancel) pass $worker->ntfy_topic
- Admin worker form + worker_process() wired for ntfy_topic field
- DB: ALTER TABLE workers ADD COLUMN ntfy_topic VARCHAR(100) NULL DEFAULT NULL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 15:30:08 +01:00
co-authored by Claude Sonnet 4.6
parent 1b96632f9b
commit 993e0cb8b1
3 changed files with 30 additions and 17 deletions
+2 -1
View File
@@ -650,7 +650,8 @@ class Admin extends CI_Controller {
'is_barber' => $_POST['is_barber'], 'is_barber' => $_POST['is_barber'],
'service_category_id' => $_POST['service_category_id'], 'service_category_id' => $_POST['service_category_id'],
'is_active' => $_POST['is_active'], 'is_active' => $_POST['is_active'],
'google_calendar_id' => isset($_POST['google_calendar_id']) ? $_POST['google_calendar_id'] : '' 'google_calendar_id' => isset($_POST['google_calendar_id']) ? $_POST['google_calendar_id'] : '',
'ntfy_topic' => isset($_POST['ntfy_topic']) ? $_POST['ntfy_topic'] : ''
); );
$this->Service_model->updateWorker($_POST['worker_id'], $workerArray); $this->Service_model->updateWorker($_POST['worker_id'], $workerArray);
$this->Log_model->addLog('workers', $data['currentUser']->username.' módosította a(z) '.$_POST['worker_name'].' nevű dolgozót ('.implode(',',$workerArray).')', $data['currentUser']->username); $this->Log_model->addLog('workers', $data['currentUser']->username.' módosította a(z) '.$_POST['worker_name'].' nevű dolgozót ('.implode(',',$workerArray).')', $data['currentUser']->username);
+14 -6
View File
@@ -466,7 +466,8 @@ class Pages extends CI_Controller {
'New booking: ' . $bookingArray['guest_name'], 'New booking: ' . $bookingArray['guest_name'],
'Worker: ' . $worker->worker_name . "\n" . 'Worker: ' . $worker->worker_name . "\n" .
'Date: ' . $bookingArray['booking_date'] . ' ' . $bookingArray['booking_start_time'] . ' - ' . $bookingArray['booking_finish_time'] . "\n" . 'Date: ' . $bookingArray['booking_date'] . ' ' . $bookingArray['booking_start_time'] . ' - ' . $bookingArray['booking_finish_time'] . "\n" .
'Services: ' . $gcalServiceNamesNtfy 'Services: ' . $gcalServiceNamesNtfy,
isset($worker->ntfy_topic) ? $worker->ntfy_topic : null
); );
$content = ''; $content = '';
@@ -894,7 +895,8 @@ class Pages extends CI_Controller {
'Modified booking: ' . $booking->guest_name, 'Modified booking: ' . $booking->guest_name,
'Worker: ' . $worker->worker_name . "\n" . 'Worker: ' . $worker->worker_name . "\n" .
'Date: ' . $newBookingDate . ' ' . $newStartTime . ' - ' . $finishTime . "\n" . 'Date: ' . $newBookingDate . ' ' . $newStartTime . ' - ' . $finishTime . "\n" .
'Services: ' . $gcalServiceNames 'Services: ' . $gcalServiceNames,
isset($worker->ntfy_topic) ? $worker->ntfy_topic : null
); );
$manageLink = SITEURL.$lang.'/manage-booking/'.$token; $manageLink = SITEURL.$lang.'/manage-booking/'.$token;
@@ -1021,7 +1023,8 @@ class Pages extends CI_Controller {
$this->_ntfy( $this->_ntfy(
'Cancelled booking: ' . $booking->guest_name, 'Cancelled booking: ' . $booking->guest_name,
'Worker: ' . $worker->worker_name . "\n" . 'Worker: ' . $worker->worker_name . "\n" .
'Date: ' . $booking->booking_date . ' ' . $booking->booking_start_time 'Date: ' . $booking->booking_date . ' ' . $booking->booking_start_time,
isset($worker->ntfy_topic) ? $worker->ntfy_topic : null
); );
$this->Service_model->deleteBooking($booking->booking_id); $this->Service_model->deleteBooking($booking->booking_id);
@@ -1033,10 +1036,14 @@ class Pages extends CI_Controller {
$this->load->view('pages/manage-booking-cancelled', $data); $this->load->view('pages/manage-booking-cancelled', $data);
} }
private function _ntfy($title, $message){ private function _ntfy($title, $message, $workerTopic = null){
$this->config->load('google_calendar'); $this->config->load('google_calendar');
$topic = $this->config->item('ntfy_topic'); $evelinTopic = $this->config->item('ntfy_topic');
if(empty($topic)) return; $topics = [];
if(!empty($evelinTopic)) $topics[] = $evelinTopic;
if(!empty($workerTopic) && $workerTopic !== $evelinTopic) $topics[] = $workerTopic;
if(empty($topics)) return;
foreach($topics as $topic){
$ch = curl_init('https://ntfy.sh/' . $topic); $ch = curl_init('https://ntfy.sh/' . $topic);
curl_setopt_array($ch, [ curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_POST => true,
@@ -1048,5 +1055,6 @@ class Pages extends CI_Controller {
curl_exec($ch); curl_exec($ch);
curl_close($ch); curl_close($ch);
} }
}
} }
@@ -56,6 +56,10 @@
<label class="formTitle">Google Calendar ID</label> <label class="formTitle">Google Calendar ID</label>
<input type="text" class="formInputBox" name="google_calendar_id" value="<?php echo isset($selectedItem->google_calendar_id) ? $selectedItem->google_calendar_id : '';?>"> <input type="text" class="formInputBox" name="google_calendar_id" value="<?php echo isset($selectedItem->google_calendar_id) ? $selectedItem->google_calendar_id : '';?>">
</div> </div>
<div class="formRow">
<label class="formTitle">ntfy Topic</label>
<input type="text" class="formInputBox" name="ntfy_topic" value="<?php echo isset($selectedItem->ntfy_topic) ? $selectedItem->ntfy_topic : '';?>">
</div>
<div class="formRow"> <div class="formRow">
<input type="submit" class="submitButton" name="updateWorker" value="Módosítás"> <input type="submit" class="submitButton" name="updateWorker" value="Módosítás">
<a href="<?php echo base_url();?>workers" class="cancelButton">Mégsem</a> <a href="<?php echo base_url();?>workers" class="cancelButton">Mégsem</a>