@page @model Admin.Pages.Channel.YouTubePubSub.IndexModel @{ ViewData["Title"] = "YouTube PubSub 구독"; // 채널별 건강 정보 lookup (YouTubeChannelID → ChannelHealthItem) var healthByChannelId = Model.Health.Channels .GroupBy(h => h.YouTubeChannelID) .ToDictionary(g => g.Key, g => g.First()); string FormatAgo(DateTime? utc) { if (utc is null) return "-"; var diff = DateTime.UtcNow - utc.Value; if (diff < TimeSpan.Zero) return utc.Value.ToString("yyyy-MM-dd HH:mm:ss") + " UTC"; if (diff.TotalMinutes < 1) return $"{(int)diff.TotalSeconds}초 전"; if (diff.TotalHours < 1) return $"{(int)diff.TotalMinutes}분 전"; if (diff.TotalDays < 1) return $"{(int)diff.TotalHours}시간 전"; return $"{(int)diff.TotalDays}일 전"; } string FormatUntil(DateTime? utc) { if (utc is null) return "-"; var diff = utc.Value - DateTime.UtcNow; if (diff < TimeSpan.Zero) return "만료됨"; if (diff.TotalMinutes < 60) return $"{(int)diff.TotalMinutes}분 후"; if (diff.TotalHours < 24) return $"{(int)diff.TotalHours}시간 후"; return $"{(int)diff.TotalDays}일 후"; } }
@Model.Health.ApiKeyMaskedTail@Model.Health.HmacSecretMaskedTail| 채널명 | Video ID | 제목 | 시작 시각(UTC) |
|---|---|---|---|
| @(live.ChannelName ?? "(미확인)") | @live.VideoID |
@live.Title | @(live.ActualStartTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "-") |
PubSubNotify.Command 파이프라인 그대로 실행 →
videos.list 1 unit → actualStartTime 있으면 BroadcastSession 생성 + LiveChat 시작.
@Model.Data.CallbackUrl
appsettings의 YouTube:CallbackUrl로 설정합니다.
| 썸네일 | 채널명 | YouTube Channel ID | 채널 상태 | 구독 | 마지막 폴링 | 구독 만료 | 마지막 비디오 | 작업 |
|---|---|---|---|---|---|---|---|---|
|
@if (!string.IsNullOrEmpty(item.ThumbnailUrl))
{
|
@if (item.HasInternalChannel)
{
@item.ChannelName
@if (!string.IsNullOrEmpty(item.Handle))
{
(@@@item.Handle)
}
}
else
{
(내부 채널 없음 · 고아 구독)
}
|
@item.YouTubeChannelID |
@if (!item.HasInternalChannel) { 고아 } else if (item.IsActive) { 활성 } else { 비활성 } | @if (item.IsSubscribed) { 구독됨 } else { 미구독 } | @{ healthByChannelId.TryGetValue(item.YouTubeChannelID, out var h); }@FormatAgo(h?.LastPolledAtUtc) | @{ var leaseLabel = FormatUntil(h?.LeaseExpiresAtUtc); var leaseClass = h?.LeaseExpiresAtUtc is null ? "text-muted" : (h.LeaseExpiresAtUtc.Value - DateTime.UtcNow).TotalDays < 2 ? "text-danger" : ""; } @leaseLabel |
@if (!string.IsNullOrEmpty(h?.LastProcessedVideoId))
{
@h.LastProcessedVideoId
}
else
{
-
}
|
@if (!item.IsSubscribed)
{
}
else
{
}
|