Skip to content

Commit

Permalink
feat: handle webhook payload as string if it is not a json object (#583)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellite authored Oct 22, 2024
1 parent c949c41 commit ee834d6
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 62 deletions.
162 changes: 107 additions & 55 deletions endpoints/cronjobs/sendnotifications.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@
return $value !== $emailaddress;
});

foreach($list as $value) {
foreach ($list as $value) {
$mail->addCC(trim($value));
}
}
Expand Down Expand Up @@ -536,77 +536,129 @@

// Webhook notifications if enabled
if ($webhookNotificationsEnabled) {

// Get webhook payload and turn it into a json object

$payload = str_replace("{{days_until}}", $days, $webhook['payload']);

$payload_json = json_decode($payload, true);

if ($payload_json === null) {
echo "Error parsing payload JSON<br />";
continue;
}
// If the payload is valid json, iterate the object and replace the placeholders with the subscription data (all subscriptions in one payload)
if ($payload_json !== null) {
$subscription_template = $payload_json[$webhook['iterator']];
$subscriptions = [];

$subscription_template = $payload_json[$webhook['iterator']];
$subscriptions = [];

foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);

if ($user['name']) {
$payer = $user['name'];
}
if ($user['name']) {
$payer = $user['name'];
}

foreach ($perUser as $k => $subscription) {
$temp_subscription = $subscription_template[0];

foreach ($temp_subscription as $key => $value) {
if (is_string($value)) {
$temp_subscription[$key] = str_replace("{{subscription_name}}", $subscription['name'], $value);
$temp_subscription[$key] = str_replace("{{subscription_price}}", $subscription['price'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_currency}}", $subscription['currency'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_category}}", $subscription['category'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_payer}}", $subscription['payer'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_date}}", $subscription['date'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_days_until_payment}}", $subscription['days'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_url}}", $subscription['url'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_notes}}", $subscription['notes'], $temp_subscription[$key]);
foreach ($perUser as $k => $subscription) {
$temp_subscription = $subscription_template[0];

foreach ($temp_subscription as $key => $value) {
if (is_string($value)) {
$temp_subscription[$key] = str_replace("{{subscription_name}}", $subscription['name'], $value);
$temp_subscription[$key] = str_replace("{{subscription_price}}", $subscription['price'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_currency}}", $subscription['currency'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_category}}", $subscription['category'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_payer}}", $subscription['payer'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_date}}", $subscription['date'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_days_until_payment}}", $subscription['days'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_url}}", $subscription['url'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_notes}}", $subscription['notes'], $temp_subscription[$key]);
}
}
$subscriptions[] = $temp_subscription;

}
$subscriptions[] = $temp_subscription;
}

// remove {{ and }} from the iterator
$payload_iterator = str_replace("{{", "", $webhook['iterator']);
$payload_iterator = str_replace("}}", "", $payload_iterator);

$payload_json["{{subscriptions}}"] = $subscriptions;
$payload_json[$payload_iterator] = $subscriptions;
unset($payload_json["{{subscriptions}}"]);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $webhook['url']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $webhook['request_method']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload_json));
if (!empty($webhook['headers'])) {
$customheaders = preg_split("/\r\n|\n|\r/", $webhook['headers']);
curl_setopt($ch, CURLOPT_HTTPHEADER, $customheaders);
}
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// remove {{ and }} from the iterator
$payload_iterator = str_replace("{{", "", $webhook['iterator']);
$payload_iterator = str_replace("}}", "", $payload_iterator);

$payload_json["{{subscriptions}}"] = $subscriptions;
$payload_json[$payload_iterator] = $subscriptions;
unset($payload_json["{{subscriptions}}"]);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $webhook['url']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $webhook['request_method']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload_json));
if (!empty($webhook['headers'])) {
$customheaders = preg_split("/\r\n|\n|\r/", $webhook['headers']);
curl_setopt($ch, CURLOPT_HTTPHEADER, $customheaders);
$response = curl_exec($ch);
curl_close($ch);

if ($response === false) {
echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else {
echo "Webhook Notifications sent<br />";
}
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

if ($response === false) {
echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else {
echo "Webhook Notifications sent<br />";
// If the payload is not valid json, send it directly as a string, replacing the placeholders with the subscription data (one notification per subscription)

if ($payload_json === null) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);

if ($user['name']) {
$payer = $user['name'];
}

foreach ($perUser as $k => $subscription) {
// Ensure the payload is reset for each subscription
$payload = $webhook['payload'];
$payload = str_replace("{{subscription_name}}", $subscription['name'], $payload);
$payload = str_replace("{{subscription_price}}", $subscription['price'], $payload);
$payload = str_replace("{{subscription_currency}}", $subscription['currency'], $payload);
$payload = str_replace("{{subscription_category}}", $subscription['category'], $payload);
$payload = str_replace("{{subscription_payer}}", $payer, $payload); // Use $payer instead of $subscription['payer']
$payload = str_replace("{{subscription_date}}", $subscription['date'], $payload);
$payload = str_replace("{{subscription_days_until_payment}}", $subscription['days'], $payload);
$payload = str_replace("{{subscription_url}}", $subscription['url'], $payload);
$payload = str_replace("{{subscription_notes}}", $subscription['notes'], $payload);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $webhook['url']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $webhook['request_method']);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
if (!empty($webhook['headers'])) {
$customheaders = preg_split("/\r\n|\n|\r/", $webhook['headers']);
curl_setopt($ch, CURLOPT_HTTPHEADER, $customheaders);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

if ($response === false) {
echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else {
echo "Webhook Notification sent <br />";
}

// Delay for 200 milliseconds
usleep(500000);
}
}
}

}
Expand Down
11 changes: 5 additions & 6 deletions endpoints/notifications/testwebhooknotifications.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
];
die(json_encode($response));
} else {
// Set the message parameters
$title = translate('wallos_notification', $i18n);
$message = translate('test_notification', $i18n);

$requestmethod = $data["requestmethod"];
$url = $data["url"];
$payload = $data["payload"];
Expand All @@ -47,19 +43,22 @@
// Execute the request
$response = curl_exec($ch);


// Close the cURL session
curl_close($ch);

// Check if the message was sent successfully
if ($response === false) {
die(json_encode([
"success" => false,
"message" => translate('notification_failed', $i18n)
"message" => translate('notification_failed', $i18n),
"response" => curl_error($ch)
]));
} else {
die(json_encode([
"success" => true,
"message" => translate('notification_sent_successfuly', $i18n)
"message" => translate('notification_sent_successfuly', $i18n),
"response" => $response
]));
}
}
Expand Down
2 changes: 1 addition & 1 deletion includes/version.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<?php
$version = "v2.30.1";
$version = "v2.31.0";
?>

0 comments on commit ee834d6

Please sign in to comment.