Selaa lähdekoodia

Share: og image

Frank 8 kuukautta sitten
vanhempi
sitoutus
edd459ec00
2 muutettua tiedostoa jossa 36 lisäystä ja 24 poistoa
  1. 33 4
      packages/function/src/api.ts
  2. 3 20
      packages/web/src/pages/s/index.astro

+ 33 - 4
packages/function/src/api.ts

@@ -1,5 +1,6 @@
 import { DurableObject } from "cloudflare:workers"
 import { randomUUID } from "node:crypto"
+import { Base64 } from "js-base64"
 
 type Env = {
   SYNC_SERVER: DurableObjectNamespace<SyncServer>
@@ -180,8 +181,12 @@ export default {
         return new Response("Error: Share ID is required", { status: 400 })
       const stub = env.SYNC_SERVER.get(env.SYNC_SERVER.idFromName(id))
       const data = await stub.getData()
+
       let info
-      const messages = {}
+      const messages: Record<string, any> = {}
+      let cost = 0
+      const models: Set<string> = new Set()
+      const version = "v0.1.1"
       data.forEach((d) => {
         const [root, type, ...splits] = d.key.split("/")
         if (root !== "session") return
@@ -192,12 +197,36 @@ export default {
         if (type === "message") {
           const [, messageID] = splits
           messages[messageID] = d.content
+
+          const assistant = d.content.metadata?.assistant
+          if (assistant) {
+            cost += assistant.cost
+            models.add(assistant.modelID)
+          }
         }
       })
 
-      return new Response(JSON.stringify({ info, messages }), {
-        headers: { "Content-Type": "application/json" },
-      })
+      const encodedTitle = encodeURIComponent(
+        Base64.encode(
+          // Convert to ASCII
+          encodeURIComponent(
+            // Truncate to fit S3's max key size
+            info.title.substring(0, 700),
+          ),
+        ),
+      )
+      const encodedCost = encodeURIComponent(`$${cost.toFixed(2)}`)
+
+      return new Response(
+        JSON.stringify({
+          info,
+          messages,
+          ogImage: `https://social-cards.sst.dev/opencode-share/${encodedTitle}.png?cost=${encodedCost}&model=${Array.from(models).join(",")}&version=${version}&id=${id}`,
+        }),
+        {
+          headers: { "Content-Type": "application/json" },
+        },
+      )
     }
   },
 }

+ 3 - 20
packages/web/src/pages/s/index.astro

@@ -1,5 +1,4 @@
 ---
-import { Base64 } from "js-base64";
 import config from "virtual:starlight/user-config";
 
 import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
@@ -12,23 +11,7 @@ const res = await fetch(`${apiUrl}/share_data?id=${id}`);
 const data = await res.json();
 
 const title = data.info.title;
-
-const encodedTitle = encodeURIComponent(
-  Base64.encode(
-    // Convert to ASCII
-    encodeURIComponent(
-      // Truncate to fit S3's max key size
-      title.substring(0, 700)
-    )
-  )
-)
-
-const cardService = "https://social-cards.sst.dev";
-const cost = "$0.12";
-const model = "claude-sonnet-4-20250514,claude-opus-4-20250514";
-const version = "v0.1.1";
-// ?cost=$0.12&model=claude-sonnet-4-20250514,claude-opus-4-20250514&version=v0.1.1&id=43120e6b
-const ogImageUrl = `${cardService}/opencode-share/${encodedTitle}.png?cost=${cost}&model=${model}&version=${version}&id=${id}`;
+const ogImage = data.ogImage;
 
 ---
 <StarlightPage
@@ -43,14 +26,14 @@ const ogImageUrl = `${cardService}/opencode-share/${encodedTitle}.png?cost=${cos
         tag: "meta",
         attrs: {
           property: "og:image",
-          content: ogImageUrl,
+          content: ogImage,
         },
       },
       {
         tag: "meta",
         attrs: {
           name: "twitter:image",
-          content: ogImageUrl,
+          content: ogImage,
         },
       },
     ],