<?php
/**
* Plugin Name: WPSD Ingest
* Description: REST endpoint to receive WPSD data and save as JSON.
* Version: 1.4.4
* Author: ChatGPT
*/
if (!defined('ABSPATH')) exit;
function get_dmr_info_with_cache($callsign) {
$callsign = strtoupper($callsign);
$transient_key = 'dmr_info_' . md5($callsign);
$cached = get_transient($transient_key);
if ($cached !== false) {
return $cached;
}
$api_url = 'https://radioid.net/api/dmr/user/?callsign=' . urlencode($callsign);
$response = wp_remote_get($api_url, array('timeout' => 8));
if (is_wp_error($response)) {
return null;
}
$json = json_decode(wp_remote_retrieve_body($response), true);
if (!isset($json['results']) || count($json['results']) === 0 || !isset($json['results'][0]['id'])) {
return null;
}
$dmr_info = array(
'dmr_id' => $json['results'][0]['id'],
'name' => $json['results'][0]['name']
);
set_transient($transient_key, $dmr_info, 12 * HOUR_IN_SECONDS);
return $dmr_info;
}
add_action('rest_api_init', function () {
register_rest_route('wpsd/v1', '/ingest', array(
'methods' => 'POST',
'callback' => function($request) {
$token = $request->get_header('x-wpsd-token');
$expected = get_option('wpsd_ingest_token');
if (!$token || $token !== $expected) {
return new WP_Error('unauthorized', 'Invalid token', array('status' => 403));
}
$data = $request->get_json_params();
if (!$data || !is_array($data)) {
return new WP_Error('invalid', 'No JSON data', array('status' => 400));
}
if (!isset($data['callsign']) && isset($data['dmr']['callsign'])) {
$data['callsign'] = $data['dmr']['callsign'];
}
if (!isset($data['callsign']) || empty($data['callsign'])) {
return new WP_Error('invalid', 'Missing callsign', array('status' => 400));
}
$dmr_info = get_dmr_info_with_cache($data['callsign']);
if (!$dmr_info || !isset($dmr_info['dmr_id'])) {
return array('ok' => false, 'reason' => 'callsign not found');
}
$data['dmr_id'] = $dmr_info['dmr_id'];
$data['name'] = $dmr_info['name'];
$dt = new DateTime('now', new DateTimeZone('Asia/Tokyo'));
$data['timestamp'] = $dt->format('Y-m-d H:i:s');
$data['timestamp_local'] = $dt->format('Y-m-d\TH:i:s.vP');
$upload_dir = wp_upload_dir();
$dir = trailingslashit($upload_dir['basedir']) . 'wpsd';
if (!file_exists($dir)) {
wp_mkdir_p($dir);
}
foreach (glob($dir . '/inbox-*.json') as $file) {
$existing = json_decode(file_get_contents($file), true);
if (isset($existing['callsign']) && $existing['callsign'] === $data['callsign']) {
if (isset($existing['timestamp']) && $existing['timestamp'] < $data['timestamp']) {
unlink($file);
}
}
}
$filename = sprintf("inbox-%s.json", $dt->format('Y-m-d\TH-i-s'));
file_put_contents($dir . '/' . $filename, wp_json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
return array('ok' => true, 'stored' => $dir . '/' . $filename);
},
'permission_callback' => '__return_true'
));
});
add_action('admin_menu', function () {
add_options_page('WPSD Ingest Settings', 'WPSD Ingest', 'manage_options', 'wpsd-ingest', function () {
echo '<div class="wrap">';
echo '<h1>WPSD Ingest Settings</h1>';
echo '<form method="post" action="options.php">';
settings_fields('wpsd_ingest');
do_settings_sections('wpsd-ingest');
submit_button();
echo '</form>';
echo '</div>';
});
});
add_action('admin_init', function () {
register_setting('wpsd_ingest', 'wpsd_ingest_token');
add_settings_section('wpsd_ingest_main', 'Main Settings', null, 'wpsd-ingest');
add_settings_field('wpsd_ingest_token', 'Token', function () {
$value = esc_attr(get_option('wpsd_ingest_token'));
echo "<input type='text' name='wpsd_ingest_token' value='$value' class='regular-text' />";
}, 'wpsd-ingest', 'wpsd_ingest_main');
});
?>