view.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. declare(strict_types=1);
  3. $baseUrl = (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['SCRIPT_NAME']);
  4. $dataPath = __DIR__ . '/data/webhooks.json';
  5. // Validate key parameter
  6. if (!isset($_GET['key']) || empty($_GET['key'])) {
  7. http_response_code(400);
  8. die('<h1>Error: Missing key parameter</h1>');
  9. }
  10. $key = $_GET['key'];
  11. // Load webhooks
  12. $raw = file_get_contents($dataPath);
  13. $data = json_decode($raw, true);
  14. // Find the webhook
  15. $webhook = null;
  16. foreach ($data['webhooks'] as $w) {
  17. if ($w['key'] === $key) {
  18. $webhook = $w;
  19. break;
  20. }
  21. }
  22. if ($webhook === null) {
  23. http_response_code(404);
  24. die('<h1>Error: Webhook not found</h1>');
  25. }
  26. // Reverse requests to show newest first
  27. $requests = array_reverse($webhook['requests']);
  28. // Helper function to format JSON
  29. function formatJson($string) {
  30. $decoded = json_decode($string, true);
  31. if (json_last_error() === JSON_ERROR_NONE) {
  32. return json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  33. }
  34. return $string;
  35. }
  36. // Helper function to format headers
  37. function formatHeaders($headers) {
  38. $output = '';
  39. foreach ($headers as $name => $value) {
  40. $output .= htmlspecialchars($name) . ': ' . htmlspecialchars($value) . "\n";
  41. }
  42. return rtrim($output);
  43. }
  44. ?>
  45. <!DOCTYPE html>
  46. <html lang="en">
  47. <head>
  48. <meta charset="UTF-8">
  49. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  50. <title>Webhook: <?= htmlspecialchars($webhook['key']) ?></title>
  51. <style>
  52. body {
  53. font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  54. max-width: 1400px;
  55. margin: 40px auto;
  56. padding: 0 20px;
  57. background: #f5f5f5;
  58. }
  59. h1 { color: #333; }
  60. .info { background: #e3f2fd; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
  61. .url-box {
  62. background: #fff;
  63. padding: 10px;
  64. border-radius: 3px;
  65. font-family: monospace;
  66. font-size: 13px;
  67. word-break: break-all;
  68. border: 1px solid #ddd;
  69. }
  70. .btn {
  71. display: inline-block;
  72. padding: 8px 16px;
  73. background: #2196F3;
  74. color: white;
  75. text-decoration: none;
  76. border-radius: 5px;
  77. border: none;
  78. cursor: pointer;
  79. font-size: 14px;
  80. }
  81. .btn:hover { background: #1976D2; }
  82. .btn-secondary { background: #757575; }
  83. .btn-secondary:hover { background: #616161; }
  84. .request {
  85. background: white;
  86. border-radius: 5px;
  87. margin-bottom: 20px;
  88. box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  89. overflow: hidden;
  90. }
  91. .request-header {
  92. background: #2196F3;
  93. color: white;
  94. padding: 12px 15px;
  95. font-weight: bold;
  96. display: flex;
  97. justify-content: space-between;
  98. align-items: center;
  99. }
  100. .request-method {
  101. background: rgba(255,255,255,0.2);
  102. padding: 3px 8px;
  103. border-radius: 3px;
  104. font-size: 12px;
  105. margin-right: 10px;
  106. }
  107. .request-body {
  108. padding: 15px;
  109. }
  110. .section {
  111. margin-bottom: 15px;
  112. }
  113. .section-title {
  114. font-weight: bold;
  115. color: #666;
  116. margin-bottom: 5px;
  117. font-size: 13px;
  118. text-transform: uppercase;
  119. }
  120. .code-box {
  121. background: #f5f5f5;
  122. border: 1px solid #ddd;
  123. border-radius: 3px;
  124. padding: 10px;
  125. font-family: 'Courier New', monospace;
  126. font-size: 12px;
  127. white-space: pre-wrap;
  128. word-break: break-all;
  129. max-height: 400px;
  130. overflow-y: auto;
  131. }
  132. .empty { text-align: center; color: #999; padding: 40px; }
  133. .back-link { margin-bottom: 20px; display: inline-block; }
  134. </style>
  135. </head>
  136. <body>
  137. <a href="index.php" class="back-link btn btn-secondary">← Back to Webhooks</a>
  138. <h1>🔗 Webhook Details</h1>
  139. <div class="info">
  140. <div><strong>Key:</strong> <code><?= htmlspecialchars($webhook['key']) ?></code></div>
  141. <div style="margin-top: 10px;"><strong>Created:</strong> <?= htmlspecialchars(date('Y-m-d H:i:s', strtotime($webhook['created']))) ?></div>
  142. <div style="margin-top: 10px;"><strong>Webhook URL:</strong></div>
  143. <div class="url-box" style="margin-top: 5px;">
  144. <?= htmlspecialchars($baseUrl . '/webhook.php?key=' . $webhook['key']) ?>
  145. </div>
  146. <div style="margin-top: 10px;"><strong>Total Requests:</strong> <?= count($webhook['requests']) ?></div>
  147. </div>
  148. <h2>Received Requests</h2>
  149. <?php if (empty($requests)): ?>
  150. <div class="empty">No requests received yet. Send a POST request to the webhook URL above.</div>
  151. <?php else: ?>
  152. <?php foreach ($requests as $index => $request): ?>
  153. <div class="request">
  154. <div class="request-header">
  155. <span>
  156. <span class="request-method"><?= htmlspecialchars($request['method']) ?></span>
  157. Request #<?= count($webhook['requests']) - $index ?>
  158. </span>
  159. <span style="font-size: 12px; font-weight: normal;">
  160. <?= htmlspecialchars(date('Y-m-d H:i:s', strtotime($request['timestamp']))) ?>
  161. </span>
  162. </div>
  163. <div class="request-body">
  164. <div class="section">
  165. <div class="section-title">Headers</div>
  166. <div class="code-box"><?= formatHeaders($request['headers']) ?></div>
  167. </div>
  168. <div class="section">
  169. <div class="section-title">Body</div>
  170. <?php
  171. $isJson = false;
  172. if (isset($request['headers']['Content-Type']) &&
  173. strpos($request['headers']['Content-Type'], 'application/json') !== false) {
  174. $isJson = true;
  175. }
  176. ?>
  177. <div class="code-box"><?= htmlspecialchars($isJson ? formatJson($request['body']) : $request['body']) ?></div>
  178. </div>
  179. </div>
  180. </div>
  181. <?php endforeach; ?>
  182. <?php endif; ?>
  183. </body>
  184. </html>