125 lines
4.1 KiB
PHP
125 lines
4.1 KiB
PHP
<?php
|
||
/**
|
||
* OG Meta Tag Proxy for Social Media Crawlers
|
||
*
|
||
* Setup: Nginx/Apache rewrite rule on dgray.io:
|
||
* If User-Agent matches crawler → proxy to this script
|
||
* Else → serve static index.html
|
||
*
|
||
* Example Apache config (in VHost):
|
||
* RewriteEngine On
|
||
* RewriteCond %{HTTP_USER_AGENT} Twitterbot|facebookexternalhit|TelegramBot|Discordbot|Slackbot|WhatsApp [NC]
|
||
* RewriteRule ^/listing/(.*)$ https://pow.dgray.io/og-proxy.php?listing=$1 [P,L]
|
||
*
|
||
* Required modules: sudo a2enmod rewrite proxy proxy_http
|
||
*
|
||
* Example Nginx config:
|
||
* location /listing/ {
|
||
* if ($http_user_agent ~* "Twitterbot|facebookexternalhit|TelegramBot|Discordbot|Slackbot|WhatsApp") {
|
||
* rewrite ^/listing/(.*)$ /og-proxy.php?listing=$1 break;
|
||
* proxy_pass https://pow.dgray.io;
|
||
* }
|
||
* }
|
||
*
|
||
* HestiaCP: Place config in /home/<USER>/conf/web/<domain>/apache2.ssl.conf_custom
|
||
*/
|
||
|
||
require __DIR__ . '/config.php';
|
||
|
||
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
|
||
|
||
// Extract listing ID from hash URL or query param
|
||
// Crawlers may receive: /listing/UUID or ?listing=UUID
|
||
$listingId = null;
|
||
|
||
if (preg_match('#/listing/([a-f0-9-]{36})#i', $requestUri, $matches)) {
|
||
$listingId = $matches[1];
|
||
}
|
||
|
||
if (!$listingId && isset($_GET['listing'])) {
|
||
$listingId = $_GET['listing'];
|
||
}
|
||
|
||
$siteUrl = 'https://dgray.io';
|
||
$defaultTitle = 'dgray.io – Anonymous Classifieds with Monero';
|
||
$defaultDesc = 'Buy and sell anonymously with Monero. No KYC, no email, E2E encrypted chat.';
|
||
$defaultImage = $siteUrl . '/assets/press/og-image.png';
|
||
|
||
$title = $defaultTitle;
|
||
$description = $defaultDesc;
|
||
$image = $defaultImage;
|
||
$url = $siteUrl;
|
||
$type = 'website';
|
||
|
||
if ($listingId) {
|
||
$apiUrl = DIRECTUS_URL . '/items/listings/' . urlencode($listingId)
|
||
. '?fields=id,title,description,price,currency,images.directus_files_id.id';
|
||
|
||
$ch = curl_init($apiUrl);
|
||
curl_setopt_array($ch, [
|
||
CURLOPT_HTTPHEADER => [
|
||
'Authorization: Bearer ' . DIRECTUS_TOKEN,
|
||
],
|
||
CURLOPT_RETURNTRANSFER => true,
|
||
CURLOPT_TIMEOUT => 5,
|
||
]);
|
||
$response = curl_exec($ch);
|
||
curl_close($ch);
|
||
|
||
$data = json_decode($response, true);
|
||
$listing = $data['data'] ?? null;
|
||
|
||
if ($listing) {
|
||
$title = htmlspecialchars($listing['title'] ?? '') . ' – dgray.io';
|
||
$description = htmlspecialchars(mb_substr($listing['description'] ?? '', 0, 160));
|
||
$url = $siteUrl . '/#/listing/' . $listing['id'];
|
||
$type = 'product';
|
||
|
||
$imageId = $listing['images'][0]['directus_files_id']['id']
|
||
?? $listing['images'][0]['directus_files_id']
|
||
?? null;
|
||
|
||
if ($imageId) {
|
||
$image = DIRECTUS_URL . '/assets/' . $imageId . '?width=1200&height=630&fit=cover';
|
||
}
|
||
|
||
if (!empty($listing['price']) && !empty($listing['currency'])) {
|
||
$price = number_format((float)$listing['price'], 2);
|
||
$description .= " | {$price} {$listing['currency']}";
|
||
}
|
||
}
|
||
}
|
||
|
||
header('Content-Type: text/html; charset=utf-8');
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title><?= $title ?></title>
|
||
<meta name="description" content="<?= $description ?>">
|
||
|
||
<!-- Open Graph -->
|
||
<meta property="og:type" content="<?= $type ?>">
|
||
<meta property="og:site_name" content="dgray.io">
|
||
<meta property="og:title" content="<?= $title ?>">
|
||
<meta property="og:description" content="<?= $description ?>">
|
||
<meta property="og:url" content="<?= $url ?>">
|
||
<meta property="og:image" content="<?= $image ?>">
|
||
<meta property="og:image:width" content="1200">
|
||
<meta property="og:image:height" content="630">
|
||
|
||
<!-- X (Twitter) Card -->
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<meta name="twitter:title" content="<?= $title ?>">
|
||
<meta name="twitter:description" content="<?= $description ?>">
|
||
<meta name="twitter:image" content="<?= $image ?>">
|
||
|
||
<!-- Redirect real users to the actual page -->
|
||
<meta http-equiv="refresh" content="0;url=<?= $url ?>">
|
||
</head>
|
||
<body>
|
||
<p>Redirecting to <a href="<?= $url ?>"><?= $title ?></a></p>
|
||
</body>
|
||
</html>
|