about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZach Lipton <zach@zachlipton.com>2024-01-23 13:04:22 -0800
committerGitHub <noreply@github.com>2024-01-23 13:04:22 -0800
commitc58e65000d36cec3af46e6c07372260767b23481 (patch)
treefe6ac0a0383b9ec881b3866d060cab8717bd7c77
parentcdbdb37aac3d395dc5ccafb0bc1e901deacc8e0a (diff)
downloadvoidsky-c58e65000d36cec3af46e6c07372260767b23481.tar.zst
Include expanded urls in social cards (#2427)
* include expanded urls in social cards (#2427)

* break expandPostLinks into its own function, add bounds checking
-rw-r--r--bskyweb/cmd/bskyweb/server.go46
-rw-r--r--bskyweb/templates/post.html8
2 files changed, 50 insertions, 4 deletions
diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go
index e391b8b03..7571e536e 100644
--- a/bskyweb/cmd/bskyweb/server.go
+++ b/bskyweb/cmd/bskyweb/server.go
@@ -10,6 +10,7 @@ import (
 	"net/http"
 	"os"
 	"os/signal"
+	"slices"
 	"strings"
 	"syscall"
 	"time"
@@ -351,9 +352,54 @@ func (srv *Server) WebPost(c echo.Context) error {
 			data["imgThumbUrls"] = thumbUrls
 		}
 	}
+
+	data["postText"] = expandPostLinks(postView)
+
 	return c.Render(http.StatusOK, "post.html", data)
 }
 
+// function to expand shortened links in rich text back to full urls, replacing shortened urls in
+// social card meta tags and the noscript output. this essentially reverses the effect
+// of shortenLinks() in src/lib/strings/rich-text-manip.ts
+func expandPostLinks(postView *appbsky.FeedDefs_PostView) string {
+	if postView.Record != nil {
+		rec := postView.Record.Val.(*appbsky.FeedPost)
+		postText := rec.Text
+		var charsAdded int64 = 0
+		// iterate over facets, check if they're link facets, and if found, grab the uri
+		for _, facet := range rec.Facets {
+			linkUri := ""
+			if slices.ContainsFunc(facet.Features, func(feat *appbsky.RichtextFacet_Features_Elem) bool {
+				if feat.RichtextFacet_Link != nil && feat.RichtextFacet_Link.LexiconTypeID == "app.bsky.richtext.facet#link" {
+					linkUri = feat.RichtextFacet_Link.Uri
+					// only expand uris that have been shortened (as opposed to those with non-uri anchor text)
+					if int64(len(postText)) >= facet.Index.ByteEnd+charsAdded &&
+						strings.HasSuffix(postText[facet.Index.ByteStart+charsAdded:facet.Index.ByteEnd+charsAdded], "...") &&
+						strings.Contains(linkUri, postText[facet.Index.ByteStart+charsAdded:(facet.Index.ByteEnd+charsAdded)-3]) {
+						return true
+					}
+				}
+				return false
+			}) {
+				// replace the shortened uri with the full length one from the facet using utf8 byte offsets
+				if int64(len(postText)) >= facet.Index.ByteEnd+charsAdded {
+					postText = postText[0:facet.Index.ByteStart+charsAdded] + linkUri + postText[facet.Index.ByteEnd+charsAdded:]
+					charsAdded += int64(len(linkUri)) - (facet.Index.ByteEnd - facet.Index.ByteStart)
+				}
+			}
+		}
+		// if the post has an embeded link and its url doesn't already appear in postText, append it to
+		// the end to avoid social cards with missing links
+		if postView.Embed != nil &&
+			postView.Embed.EmbedExternal_View != nil &&
+			!strings.Contains(postText, postView.Embed.EmbedExternal_View.External.Uri) {
+			postText = fmt.Sprintf("%s\n%s", postText, postView.Embed.EmbedExternal_View.External.Uri)
+		}
+		return postText
+	}
+	return ""
+}
+
 func (srv *Server) WebProfile(c echo.Context) error {
 	ctx := c.Request().Context()
 	data := pongo2.Context{}
diff --git a/bskyweb/templates/post.html b/bskyweb/templates/post.html
index 307f80bbb..b6688e35b 100644
--- a/bskyweb/templates/post.html
+++ b/bskyweb/templates/post.html
@@ -21,9 +21,9 @@
   {% else %}
   <meta property="og:title" content="@{{ postView.Author.Handle }}">
   {% endif -%}
-  {%- if postView.Record.Val.Text %}
-  <meta name="description" content="{{ postView.Record.Val.Text }}">
-  <meta property="og:description" content="{{ postView.Record.Val.Text }}">
+  {%- if postText %}
+  <meta name="description" content="{{ postText }}">
+  <meta property="og:description" content="{{ postText }}">
   {% endif -%}
   {%- if imgThumbUrls %}
   {% for imgThumbUrl in imgThumbUrls %}
@@ -47,7 +47,7 @@
   <p id="bsky_display_name">{{ postView.Author.DisplayName }}</p>
   <p id="bsky_handle">{{ postView.Author.Handle }}</p>
   <p id="bsky_did">{{ postView.Author.Did }}</p>
-  <p id="bsky_post_text">{{ postView.Record.Val.Text }}</p>
+  <p id="bsky_post_text">{{ postText }}</p>
   <p id="bsky_post_indexedat">{{ postView.IndexedAt }}</p>
 </div>
 {% endif -%}