Skip to content

Instantly share code, notes, and snippets.

@rikmeijer
Created February 24, 2026 17:11
Show Gist options
  • Select an option

  • Save rikmeijer/ad692f1e4ef02616e6e9e89be860f91d to your computer and use it in GitHub Desktop.

Select an option

Save rikmeijer/ad692f1e4ef02616e6e9e89be860f91d to your computer and use it in GitHub Desktop.
fix originalDatetime based on filename for immich assets (searching for signal- in this example)
<?php
$uri = "https://immich.example.org/api";
$api_key = "<API_KEY_HERE>";
$request = function(string $method, string $endpoint, mixed $body = null, array $headers = []) use ($uri, $api_key) {
$curl = curl_init($uri . $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
switch ($method) {
case 'HEAD':
curl_setopt($curl, CURLOPT_NOBODY, true);
break;
case 'PUT':
case 'POST':
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($body));
$headers[] = 'Content-Type:application/json';
break;
default:
break;
}
$headers[] = 'x-api-key: ' . $api_key;
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$raw_response = curl_exec($curl);
if ($raw_response === false) {
$error = curl_error($curl);
curl_close($curl);
throw new \Exception($error);
}
$info = curl_getinfo($curl);
curl_close($curl);
$response_headers = [];
foreach(array_filter(explode("\r\n", substr($raw_response, 0, $info['header_size']))) as $response_header) {
if (str_starts_with($response_header, 'HTTP/')) {
list($protocol, $status) = explode(' ', $response_header, 2);
$response_headers['protocol'] = [$protocol];
$response_headers['status'] = [trim($status)];
continue;
}
list($header, $value) = explode(':', $response_header, 2);
$response_headers[strtolower($header)] = array_map('trim', explode(';', $value ?? ''));
};
$response_body = substr($raw_response, $info['header_size']);
if (isset($response_headers['status']) === false) {
throw new \Exception(var_export($raw_response, true));
}
return [$response_headers['status'], json_decode($response_body)];
};
$signal_assets = $request('POST', '/search/metadata', ['originalFileName' => "signal-"])[1]->assets;
while ($signal_assets->nextPage !== null) {
foreach ($signal_assets->items as $signal_asset) {
if (property_exists($signal_asset, 'id') === false) {
continue;
}
print $signal_asset->originalFileName . ": " . $signal_asset->fileCreatedAt;
// signal-2023-02-19-15-08-31-693-1.jpg
if (preg_match('/signal-(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d)-(?<hour>\d\d)-?(?<minutes>\d\d)-?(?<seconds>\d\d)/', $signal_asset->originalFileName, $matches) !== 1) {
var_dump($signal_asset->originalFileName);
exit;
}
$datetime = new DateTimeImmutable($matches['year'] . '-' . $matches['month'] . '-' . $matches['day'] . 'T' . $matches['hour'] . ':' . $matches['minutes'] . ':' . $matches['seconds'], new DateTimeZone('europe/amsterdam'));
print ' --> ' . $datetime->format('Y-m-d\\TH:i:s.vp') . PHP_EOL;
print $request('PUT', '/assets/' . $signal_asset->id, ['dateTimeOriginal' => $datetime->format('Y-m-d\\TH:i:s.vp')])[0][0] . PHP_EOL;
}
$signal_assets = $request('POST', '/search/metadata', ['originalFileName' => "signal-", "page" => $signal_assets->nextPage])[1]->assets;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment