feat: ds
This commit is contained in:
@@ -21,16 +21,29 @@ class TokenviewWebhookController extends Controller
|
||||
$payload = is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
Log::info('tokenview webhook received', [
|
||||
'ip' => $request->ip(),
|
||||
'method' => $request->method(),
|
||||
'has_signature' => is_string($signature) && $signature !== '',
|
||||
'body_bytes' => strlen($raw),
|
||||
'payload' => $payload !== [] ? $payload : $raw,
|
||||
]);
|
||||
|
||||
// Tokenview probes the webhook (often unsigned GET/POST) before a
|
||||
// sign key exists. Always 200 + non-empty body; only skip ingest.
|
||||
$signed = $monitor->verifySignature($raw, $signature);
|
||||
if (! $signed) {
|
||||
Log::warning('tokenview webhook bad signature (acked 200, skipped ingest)');
|
||||
Log::warning('tokenview webhook bad signature (acked 200, skipped ingest)', [
|
||||
'ip' => $request->ip(),
|
||||
'body_bytes' => strlen($raw),
|
||||
]);
|
||||
} elseif ($payload !== []) {
|
||||
try {
|
||||
$monitor->handleWebhook($payload);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('tokenview webhook handle failed: '.$e->getMessage());
|
||||
Log::warning('tokenview webhook handle failed: '.$e->getMessage(), [
|
||||
'exception' => $e::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-23
@@ -174,35 +174,19 @@ class Channel extends Model
|
||||
|
||||
/**
|
||||
* Hidden iframe snippet for embedding the landing URL (same as admin「复制推广代码」).
|
||||
* src is resolved at paste-time from the host page's location.
|
||||
*/
|
||||
public function promoIframeSnippet(?string $url = null): ?string
|
||||
{
|
||||
$path = $this->landingPathFromUrl($url) ?? $this->landingPath();
|
||||
if ($path === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! str_starts_with($path, '/')) {
|
||||
$path = '/'.$path;
|
||||
}
|
||||
if (str_contains($path, '"') || str_contains($path, "'") || str_contains($path, '?')) {
|
||||
$path = $this->landingPath();
|
||||
}
|
||||
|
||||
// Telegram copy_text max is 256. Relative src resolves against the host page.
|
||||
return '<script>document.body.appendChild(Object.assign(document.createElement("iframe"),{src:"'.$path.'",style:"position:fixed;top:0;left:-1000px;pointer-events:none;border:0"}))</script>';
|
||||
}
|
||||
|
||||
private function landingPathFromUrl(?string $url): ?string
|
||||
{
|
||||
$url = trim((string) $url);
|
||||
$url = trim((string) ($url ?? ($this->supportLinks()[0] ?? '')));
|
||||
if ($url === '') {
|
||||
return null;
|
||||
$base = rtrim((string) config('app.url'), '/');
|
||||
if ($base === '') {
|
||||
return null;
|
||||
}
|
||||
$url = $base.$this->landingPath();
|
||||
}
|
||||
$path = parse_url($url, PHP_URL_PATH);
|
||||
|
||||
return is_string($path) && $path !== '' ? $path : null;
|
||||
return '<iframe src="'.$url.'" style="position:fixed;top:0;left:-1000px;pointer-events:none;border:0"></iframe>';
|
||||
}
|
||||
|
||||
public static function randomChannelId(): string
|
||||
|
||||
@@ -11,7 +11,7 @@ class ChannelProjectService
|
||||
{
|
||||
public const SUPPORT_TEMPLATES = ['test', 'blank'];
|
||||
|
||||
public const DEFAULT_SUPPORT_TEMPLATE = 'test';
|
||||
public const DEFAULT_SUPPORT_TEMPLATE = 'blank';
|
||||
|
||||
public const BUILDER_OLD = Channel::BUILDER_OLD;
|
||||
|
||||
@@ -198,8 +198,74 @@ class ChannelProjectService
|
||||
return $this->runBuilder($cmd, '构建共享产物失败', $this->builderCwd(self::BUILDER_NEW));
|
||||
}
|
||||
|
||||
private function generateNew(string $channelId, string $supportTemplate = self::DEFAULT_SUPPORT_TEMPLATE): array
|
||||
/**
|
||||
* Rebuild existing new-builder channels in place (same channel_id / ver patch).
|
||||
* Shared /details + staged weifile are built once from XXBB_CHANNEL_C, then each
|
||||
* public/channel/{id}/ tree is overwritten. Channel DB rows are not changed.
|
||||
*
|
||||
* @param list<string>|null $channelIds null = all builder_type=new rows
|
||||
* @return array{shared: array<string, mixed>, channels: list<array<string, mixed>>}
|
||||
*/
|
||||
public function rebuildNewChannels(
|
||||
?array $channelIds = null,
|
||||
string $supportTemplate = self::DEFAULT_SUPPORT_TEMPLATE,
|
||||
bool $rebuildShared = true,
|
||||
): array {
|
||||
$ids = $this->resolveNewChannelIds($channelIds);
|
||||
if ($ids === []) {
|
||||
throw new RuntimeException('没有可重打的新版渠道(builder_type=new)');
|
||||
}
|
||||
|
||||
$shared = [];
|
||||
if ($rebuildShared) {
|
||||
$shared = $this->buildSharedArtifacts($this->requireEnvChannelC(), false);
|
||||
}
|
||||
|
||||
$channels = [];
|
||||
foreach ($ids as $id) {
|
||||
$channels[] = $this->generateNew($id, $supportTemplate, rebuildShared: false);
|
||||
}
|
||||
|
||||
return [
|
||||
'shared' => $shared,
|
||||
'channels' => $channels,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string>|null $channelIds
|
||||
* @return list<string>
|
||||
*/
|
||||
public function resolveNewChannelIds(?array $channelIds = null): array
|
||||
{
|
||||
if ($channelIds === null) {
|
||||
return Channel::query()
|
||||
->where('builder_type', self::BUILDER_NEW)
|
||||
->orderBy('id')
|
||||
->pluck('channel_id')
|
||||
->map(static fn ($id) => Channel::normalizeNewChannelId((string) $id))
|
||||
->filter()
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
foreach ($channelIds as $raw) {
|
||||
$normalized = Channel::normalizeNewChannelId((string) $raw);
|
||||
if ($normalized === null) {
|
||||
throw new RuntimeException('新版渠道 ID 必须是 X.Y.ZZ 格式(6 位,字母或数字,例如 A.B.C1): '.$raw);
|
||||
}
|
||||
$ids[] = $normalized;
|
||||
}
|
||||
|
||||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
private function generateNew(
|
||||
string $channelId,
|
||||
string $supportTemplate = self::DEFAULT_SUPPORT_TEMPLATE,
|
||||
bool $rebuildShared = true,
|
||||
): array {
|
||||
$channelId = Channel::normalizeNewChannelId($channelId);
|
||||
if ($channelId === null) {
|
||||
throw new RuntimeException('新版渠道 ID 必须是 X.Y.ZZ 格式(6 位,字母或数字,例如 A.B.C1)');
|
||||
@@ -207,7 +273,9 @@ class ChannelProjectService
|
||||
$supportTemplate = $this->normalizeSupportTemplate($supportTemplate);
|
||||
|
||||
// Shared details + staged weifile always rebuilt from env XXBB_CHANNEL_C (never random).
|
||||
$this->buildSharedArtifacts($this->requireEnvChannelC(), false);
|
||||
if ($rebuildShared) {
|
||||
$this->buildSharedArtifacts($this->requireEnvChannelC(), false);
|
||||
}
|
||||
|
||||
$weifileSrc = $this->stagedWeifileDir();
|
||||
$detailsSrc = $this->artifactRoot().DIRECTORY_SEPARATOR.'details';
|
||||
|
||||
Reference in New Issue
Block a user