feat: resolve nip5 for OG tags

This commit is contained in:
Kieran 2024-01-10 22:37:33 +00:00
parent fd39290bb5
commit 56570a832d
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941

View File

@ -1,6 +1,7 @@
using AngleSharp;
using AngleSharp.Dom;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Nostr.Client.Identifiers;
using Nostr.Client.Messages;
using Nostr.Client.Utils;
@ -17,11 +18,14 @@ public class OpenGraphController : Controller
{
private readonly ILogger<OpenGraphController> _logger;
private readonly RedisStore _redisStore;
private readonly HttpClient _httpClient;
public OpenGraphController(ILogger<OpenGraphController> logger, RedisStore redisStore)
public OpenGraphController(ILogger<OpenGraphController> logger, RedisStore redisStore, HttpClient httpClient)
{
_logger = logger;
_redisStore = redisStore;
_httpClient = httpClient;
_httpClient.Timeout = TimeSpan.FromSeconds(2);
}
/// <summary>
@ -51,11 +55,13 @@ public class OpenGraphController : Controller
}
}
if (NostrIdentifierParser.TryParse(id, out var nid) || (nid = NostrBareIdentifier.Parse(id)) != default)
if ((NostrIdentifierParser.TryParse(id, out var nid) && nid != default) ||
(nid = NostrBareIdentifier.Parse(id)) != default ||
(nid = await TryParseNip05(id, cts)) != default)
{
try
{
if (nid!.Hrp is "nevent" or "note" or "naddr")
if (nid.Hrp is "nevent" or "note" or "naddr")
{
var ev = await _redisStore.GetEvent(nid);
if (ev != default)
@ -105,7 +111,7 @@ public class OpenGraphController : Controller
{
case (long)NostrKind.LiveEvent:
{
var host = ev.Tags.FirstOrDefault(a => a is {Key: "p", Values: [_, _, "host", ..]})?.Values[1] ?? ev.PubKey.ToHex();
var host = ev.Tags.FirstOrDefault(a => a is {Key: "p", Values: [_, _, "host"]})?.Values[1] ?? ev.PubKey.ToHex();
var hostProfile = await _redisStore.GetProfile(host);
var hostName = hostProfile?.Name ?? profile?.Name ?? "Nostrich";
var stream = ev.GetFirstTagValue("streaming") ?? ev.GetFirstTagValue("recording") ?? "";
@ -164,7 +170,7 @@ public class OpenGraphController : Controller
private async Task<CachedMeta?> GetProfileMeta(CompactProfile? profile)
{
var titleContent = $"Snort - {profile?.Name ?? "Nostrich"}'s Profile";
var titleContent = $"{profile?.Name ?? "Nostrich"}'s Profile";
var aboutContent = profile?.About?.Length > 160 ? profile.About[..160] : profile?.About ?? "";
var imageContent = profile?.Picture ?? "https://snort.social/nostrich_512.png";
return new CachedMeta
@ -211,6 +217,37 @@ public class OpenGraphController : Controller
}
record HeadElement(string Element, List<KeyValuePair<string, string>> Attributes);
private async Task<NostrIdentifier?> TryParseNip05(string id, CancellationToken cts)
{
try
{
if (id.Contains("@"))
{
var idSplit = id.Split("@");
var url = new Uri($"https://{idSplit[1]}/.well-known/nostr.json?name={Uri.EscapeDataString(idSplit[0])}");
var json = await _httpClient.GetStringAsync(url, cts);
var parsed = JsonConvert.DeserializeObject<NostrJson>(json);
var match = parsed?.Names?.FirstOrDefault(a => a.Key.Equals(idSplit[0], StringComparison.CurrentCultureIgnoreCase));
if (match.HasValue && !string.IsNullOrEmpty(match.Value.Value))
{
return new NostrProfileIdentifier(match.Value.Value.ToLower(), null);
}
}
}
catch (Exception ex)
{
_logger.LogWarning("Failed to parse nostr address {id} {msg}", id, ex.Message);
}
return default;
}
class NostrJson
{
[JsonProperty("names")]
public Dictionary<string, string>? Names { get; init; } = new();
}
}
[ProtoContract]