@rmdes/indiekit-endpoint-conversations 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -163,57 +163,109 @@ async function apiMentions(request, response) {
163
163
  items = await getConversationItems(application, null, queryOptions);
164
164
  }
165
165
 
166
+ // Filter out self-interactions from own Bluesky account
167
+ const selfBskyHandle = (process.env.BLUESKY_IDENTIFIER || process.env.BLUESKY_HANDLE || "").replace(/^@+/, "").toLowerCase();
168
+ if (selfBskyHandle) {
169
+ const selfBskyUrl = "https://bsky.app/profile/" + selfBskyHandle;
170
+ items = items.filter(item => (item.author?.url || "").toLowerCase() !== selfBskyUrl);
171
+ }
172
+
166
173
  const children = items.map(conversationItemToJf2);
167
174
 
168
175
  // Enrich with owner replies from the posts collection
169
- // Owner replies are Micropub posts with in-reply-to matching an interaction URL
176
+ // Owner replies are Micropub posts with in-reply-to matching an interaction URL.
177
+ // We collect reply URLs from conversations DB items, but also need to find
178
+ // owner replies to interactions that only exist in webmention.io (e.g., Bluesky
179
+ // replies via Bridgy). Strategy: query for reply URLs from conversations items,
180
+ // plus find owner posts replying to any URL that the frontend might display
181
+ // by checking the canonical post's syndication targets.
170
182
  const replyUrls = children
171
183
  .filter((c) => c["wm-property"] === "in-reply-to")
172
184
  .map((c) => c.url)
173
185
  .filter(Boolean);
174
186
 
175
- if (replyUrls.length > 0) {
176
- const postsCollection = application.collections?.get("posts");
177
- if (postsCollection) {
178
- const siteUrl = application.publication?.me || application.url || "";
179
- const ownerName =
180
- process.env.AUTHOR_NAME ||
181
- (siteUrl ? new URL(siteUrl).hostname : "Owner");
182
-
183
- const ownerPosts = await postsCollection
184
- .find({
185
- "properties.in-reply-to": { $in: replyUrls },
186
- })
187
+ const postsCollection = application.collections?.get("posts");
188
+ if (postsCollection) {
189
+ const siteUrl = application.publication?.me || application.url || "";
190
+ const ownerName =
191
+ process.env.AUTHOR_NAME ||
192
+ (siteUrl ? new URL(siteUrl).hostname : "Owner");
193
+
194
+ // Find the canonical post to get its syndication URLs
195
+ // Interactions on syndicated copies (e.g., Bluesky replies to the bsky.app
196
+ // syndicated post) arrive via webmention.io but not conversations DB.
197
+ // Owner replies to those interactions have in-reply-to pointing to external
198
+ // URLs (bsky.app, mastodon, etc.) — we need to find them too.
199
+ let syndicationDomains = [];
200
+ if (target) {
201
+ const targetWithout = target.endsWith("/") ? target.slice(0, -1) : target;
202
+ const canonicalPost = await postsCollection.findOne({
203
+ $or: [
204
+ { "properties.url": target },
205
+ { "properties.url": targetWithout },
206
+ ],
207
+ });
208
+ if (canonicalPost?.properties?.syndication) {
209
+ const syns = Array.isArray(canonicalPost.properties.syndication)
210
+ ? canonicalPost.properties.syndication
211
+ : [canonicalPost.properties.syndication];
212
+ for (const syn of syns) {
213
+ try {
214
+ const domain = new URL(syn).hostname;
215
+ if (domain && !domain.includes(new URL(siteUrl).hostname)) {
216
+ syndicationDomains.push(domain);
217
+ }
218
+ } catch { /* skip invalid URLs */ }
219
+ }
220
+ }
221
+ }
222
+
223
+ // Build query: replies to known conversation URLs OR replies to URLs
224
+ // on syndication domains (for webmention.io items not in our DB)
225
+ const orClauses = [];
226
+ if (replyUrls.length > 0) {
227
+ orClauses.push({ "properties.in-reply-to": { $in: replyUrls } });
228
+ }
229
+ for (const domain of syndicationDomains) {
230
+ orClauses.push({
231
+ "properties.in-reply-to": { $regex: domain.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") },
232
+ });
233
+ }
234
+
235
+ let ownerPosts = [];
236
+ if (orClauses.length > 0) {
237
+ ownerPosts = await postsCollection
238
+ .find({ $or: orClauses })
187
239
  .sort({ "properties.published": -1 })
188
240
  .limit(50)
189
241
  .toArray();
242
+ }
190
243
 
191
- for (const post of ownerPosts) {
192
- const inReplyTo = post.properties?.["in-reply-to"];
193
- if (!inReplyTo || typeof inReplyTo !== "string") continue;
194
-
195
- children.push({
196
- type: "entry",
197
- "wm-id": `owner-reply-${post._id}`,
198
- "wm-property": "in-reply-to",
199
- "wm-target": target || "",
200
- "wm-received": post.properties?.published || "",
201
- author: {
202
- type: "card",
203
- name: ownerName,
204
- url: siteUrl,
205
- photo: process.env.AUTHOR_AVATAR || "",
206
- },
207
- url: post.properties?.url || "",
208
- published: post.properties?.published || "",
209
- content: {
210
- text: post.properties?.content?.text || "",
211
- html: post.properties?.content?.html || "",
212
- },
213
- is_owner: true,
214
- parent_url: inReplyTo,
215
- });
216
- }
244
+ for (const post of ownerPosts) {
245
+ const inReplyTo = post.properties?.["in-reply-to"];
246
+ if (!inReplyTo || typeof inReplyTo !== "string") continue;
247
+
248
+ children.push({
249
+ type: "entry",
250
+ "wm-id": `owner-reply-${post._id}`,
251
+ "wm-property": "in-reply-to",
252
+ "wm-target": target || "",
253
+ "wm-received": post.properties?.published || "",
254
+ author: {
255
+ type: "card",
256
+ name: ownerName,
257
+ url: siteUrl,
258
+ photo: process.env.AUTHOR_AVATAR || "",
259
+ },
260
+ url: post.properties?.url || "",
261
+ published: post.properties?.published || "",
262
+ content: {
263
+ text: post.properties?.content?.text || "",
264
+ html: post.properties?.content?.html || "",
265
+ },
266
+ is_owner: true,
267
+ parent_url: inReplyTo,
268
+ });
217
269
  }
218
270
  }
219
271
 
@@ -27,9 +27,11 @@ export async function fetchBlueskyNotifications(options) {
27
27
  // Get or refresh session
28
28
  const session = await getSession(serviceUrl, identifier, password);
29
29
 
30
- // Fetch notifications
30
+ // Fetch the most recent notifications (no cursor)
31
+ // Bluesky's listNotifications returns newest first; the cursor pages backward
32
+ // into history. For polling, we always want the latest batch and rely on
33
+ // upsert deduplication (platform_id) to skip already-stored items.
31
34
  const params = new URLSearchParams({ limit: "50" });
32
- if (options.cursor) params.set("cursor", options.cursor);
33
35
 
34
36
  let notifResponse = await fetch(
35
37
  `${serviceUrl}/xrpc/app.bsky.notification.listNotifications?${params.toString()}`,
@@ -425,12 +425,19 @@ async function pollBluesky(indiekit, stateCollection, state, credentials) {
425
425
  const result = await fetchBlueskyNotifications({
426
426
  identifier: credentials.identifier,
427
427
  password: credentials.password,
428
- cursor: state.bluesky_cursor,
429
428
  });
430
429
 
431
430
  let stored = 0;
432
431
 
432
+ // Derive own handle to skip self-interactions
433
+ const ownBskyHandle = (credentials.identifier || "").replace(/^@+/, "").toLowerCase();
434
+
433
435
  for (const notification of result.items) {
436
+ // Skip self-interactions (own account liking/reposting a syndicated post)
437
+ if (ownBskyHandle && (notification.author?.handle || "").toLowerCase() === ownBskyHandle) {
438
+ continue;
439
+ }
440
+
434
441
  let canonicalUrl = null;
435
442
 
436
443
  if (notification.lookup_url) {
@@ -457,22 +464,19 @@ async function pollBluesky(indiekit, stateCollection, state, credentials) {
457
464
  }
458
465
  }
459
466
 
460
- // Update cursor and status
461
- const updateFields = {
462
- bluesky_last_poll: new Date().toISOString(),
463
- bluesky_last_error: null,
464
- };
465
- if (result.cursor) {
466
- updateFields.bluesky_cursor = result.cursor;
467
- }
468
-
467
+ // Update poll timestamp
469
468
  await stateCollection.findOneAndUpdate(
470
469
  { _id: "poll_cursors" },
471
- { $set: updateFields },
470
+ {
471
+ $set: {
472
+ bluesky_last_poll: new Date().toISOString(),
473
+ bluesky_last_error: null,
474
+ },
475
+ },
472
476
  { upsert: true },
473
477
  );
474
478
 
475
- if (stored > 0) {
479
+ if (stored > 0 || result.items.length > 0) {
476
480
  console.info(
477
481
  `[Conversations] Bluesky: stored ${stored}/${result.items.length} interactions`,
478
482
  );
package/locales/de.json CHANGED
@@ -12,6 +12,8 @@
12
12
  "itemsReceived": "Elemente empfangen",
13
13
  "mastodonHint": "MASTODON_ACCESS_TOKEN und MASTODON_URL setzen zum Aktivieren",
14
14
  "blueskyHint": "BLUESKY_IDENTIFIER und BLUESKY_PASSWORD setzen zum Aktivieren",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Automatisch aktiviert, wenn der ActivityPub-Endpunkt Interaktionen empfängt",
15
17
  "webhookTitle": "Webhook / Eingang",
16
18
  "webhookHint": "Externe Dienste k\u00f6nnen Webmentions an den Eingangsendpunkt senden",
17
19
  "stats": "Statistiken",
@@ -26,7 +28,8 @@
26
28
  "source": {
27
29
  "webmention": "Webmention",
28
30
  "mastodon": "Mastodon",
29
- "bluesky": "Bluesky"
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
30
33
  }
31
34
  }
32
35
  }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "Conversaciones",
4
+ "dashboard": {
5
+ "connections": "Conexiones",
6
+ "connected": "Conectado",
7
+ "disconnected": "No configurado",
8
+ "ready": "Listo",
9
+ "lastPoll": "Última consulta",
10
+ "lastError": "Error",
11
+ "itemsCollected": "elementos recopilados",
12
+ "itemsReceived": "elementos recibidos",
13
+ "mastodonHint": "Configurar MASTODON_ACCESS_TOKEN y MASTODON_URL para habilitar",
14
+ "blueskyHint": "Configurar BLUESKY_IDENTIFIER y BLUESKY_PASSWORD para habilitar",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Se habilita automáticamente cuando el endpoint de ActivityPub recibe interacciones",
17
+ "webhookTitle": "Webhook / Ingesta",
18
+ "webhookHint": "Los servicios externos pueden enviar webmentions al endpoint de ingesta",
19
+ "stats": "Estadísticas",
20
+ "totalItems": "Total de elementos",
21
+ "replies": "Respuestas",
22
+ "likes": "Me gusta",
23
+ "reposts": "Republicaciones",
24
+ "pollNow": "Consultar ahora",
25
+ "recentActivity": "Actividad reciente",
26
+ "empty": "Aún no hay interacciones. Configura las credenciales de la plataforma o envía webmentions al endpoint de ingesta."
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
package/locales/es.json CHANGED
@@ -12,6 +12,8 @@
12
12
  "itemsReceived": "elementos recibidos",
13
13
  "mastodonHint": "Configurar MASTODON_ACCESS_TOKEN y MASTODON_URL para activar",
14
14
  "blueskyHint": "Configurar BLUESKY_IDENTIFIER y BLUESKY_PASSWORD para activar",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Se activa automáticamente cuando el endpoint de ActivityPub recibe interacciones",
15
17
  "webhookTitle": "Webhook / Ingesta",
16
18
  "webhookHint": "Los servicios externos pueden enviar webmentions al punto de ingesta",
17
19
  "stats": "Estad\u00edsticas",
@@ -26,7 +28,8 @@
26
28
  "source": {
27
29
  "webmention": "Webmention",
28
30
  "mastodon": "Mastodon",
29
- "bluesky": "Bluesky"
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
30
33
  }
31
34
  }
32
35
  }
package/locales/fr.json CHANGED
@@ -3,30 +3,33 @@
3
3
  "title": "Conversations",
4
4
  "dashboard": {
5
5
  "connections": "Connexions",
6
- "connected": "Connect\u00e9",
7
- "disconnected": "Non configur\u00e9",
8
- "ready": "Pr\u00eat",
6
+ "connected": "Connecté",
7
+ "disconnected": "Non configuré",
8
+ "ready": "Prêt",
9
9
  "lastPoll": "Dernier sondage",
10
10
  "lastError": "Erreur",
11
- "itemsCollected": "\u00e9l\u00e9ments collect\u00e9s",
12
- "itemsReceived": "\u00e9l\u00e9ments re\u00e7us",
13
- "mastodonHint": "D\u00e9finir MASTODON_ACCESS_TOKEN et MASTODON_URL pour activer",
14
- "blueskyHint": "D\u00e9finir BLUESKY_IDENTIFIER et BLUESKY_PASSWORD pour activer",
15
- "webhookTitle": "Webhook / Ing\u00e9rer",
16
- "webhookHint": "Les services externes peuvent envoyer des webmentions au point d'entr\u00e9e",
11
+ "itemsCollected": "éléments collectés",
12
+ "itemsReceived": "éléments reçus",
13
+ "mastodonHint": "Définir MASTODON_ACCESS_TOKEN et MASTODON_URL pour activer",
14
+ "blueskyHint": "Définir BLUESKY_IDENTIFIER et BLUESKY_PASSWORD pour activer",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Activé automatiquement lorsque le point d'entrée ActivityPub reçoit des interactions",
17
+ "webhookTitle": "Webhook / Ingérer",
18
+ "webhookHint": "Les services externes peuvent envoyer des webmentions au point d'entrée",
17
19
  "stats": "Statistiques",
18
- "totalItems": "Total des \u00e9l\u00e9ments",
19
- "replies": "R\u00e9ponses",
20
+ "totalItems": "Total des éléments",
21
+ "replies": "Réponses",
20
22
  "likes": "J'aime",
21
23
  "reposts": "Repartages",
22
24
  "pollNow": "Sonder maintenant",
23
- "recentActivity": "Activit\u00e9 r\u00e9cente",
24
- "empty": "Aucune interaction pour le moment. Configurez les identifiants de plateforme ou envoyez des webmentions au point d'entr\u00e9e."
25
+ "recentActivity": "Activité récente",
26
+ "empty": "Aucune interaction pour le moment. Configurez les identifiants de plateforme ou envoyez des webmentions au point d'entrée."
25
27
  },
26
28
  "source": {
27
29
  "webmention": "Webmention",
28
30
  "mastodon": "Mastodon",
29
- "bluesky": "Bluesky"
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
30
33
  }
31
34
  }
32
35
  }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "वार्तालाप",
4
+ "dashboard": {
5
+ "connections": "कनेक्शन",
6
+ "connected": "कनेक्ट किया गया",
7
+ "disconnected": "कॉन्फ़िगर नहीं किया गया",
8
+ "ready": "तैयार",
9
+ "lastPoll": "अंतिम पोल",
10
+ "lastError": "त्रुटि",
11
+ "itemsCollected": "आइटम एकत्रित",
12
+ "itemsReceived": "आइटम प्राप्त",
13
+ "mastodonHint": "सक्रिय करने के लिए MASTODON_ACCESS_TOKEN और MASTODON_URL सेट करें",
14
+ "blueskyHint": "सक्रिय करने के लिए BLUESKY_IDENTIFIER और BLUESKY_PASSWORD सेट करें",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "ActivityPub एंडपॉइंट पर इंटरैक्शन प्राप्त होने पर स्वचालित रूप से सक्रिय होता है",
17
+ "webhookTitle": "Webhook / इनजेस्ट",
18
+ "webhookHint": "बाहरी सेवाएँ इनजेस्ट एंडपॉइंट पर वेबमेंशन भेज सकती हैं",
19
+ "stats": "आँकड़े",
20
+ "totalItems": "कुल आइटम",
21
+ "replies": "जवाब",
22
+ "likes": "पसंद",
23
+ "reposts": "रीपोस्ट",
24
+ "pollNow": "अभी पोल करें",
25
+ "recentActivity": "हाल की गतिविधि",
26
+ "empty": "अभी तक कोई इंटरैक्शन नहीं। प्लेटफ़ॉर्म क्रेडेंशियल कॉन्फ़िगर करें या इनजेस्ट एंडपॉइंट पर वेबमेंशन भेजें।"
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "Percakapan",
4
+ "dashboard": {
5
+ "connections": "Koneksi",
6
+ "connected": "Terhubung",
7
+ "disconnected": "Belum dikonfigurasi",
8
+ "ready": "Siap",
9
+ "lastPoll": "Polling terakhir",
10
+ "lastError": "Kesalahan",
11
+ "itemsCollected": "item dikumpulkan",
12
+ "itemsReceived": "item diterima",
13
+ "mastodonHint": "Atur MASTODON_ACCESS_TOKEN dan MASTODON_URL untuk mengaktifkan",
14
+ "blueskyHint": "Atur BLUESKY_IDENTIFIER dan BLUESKY_PASSWORD untuk mengaktifkan",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Otomatis aktif saat endpoint ActivityPub menerima interaksi",
17
+ "webhookTitle": "Webhook / Ingest",
18
+ "webhookHint": "Layanan eksternal dapat mengirim webmention ke endpoint ingest",
19
+ "stats": "Statistik",
20
+ "totalItems": "Total item",
21
+ "replies": "Balasan",
22
+ "likes": "Suka",
23
+ "reposts": "Repost",
24
+ "pollNow": "Polling sekarang",
25
+ "recentActivity": "Aktivitas terbaru",
26
+ "empty": "Belum ada interaksi. Konfigurasikan kredensial platform atau kirim webmention ke endpoint ingest."
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "Conversazioni",
4
+ "dashboard": {
5
+ "connections": "Connessioni",
6
+ "connected": "Connesso",
7
+ "disconnected": "Non configurato",
8
+ "ready": "Pronto",
9
+ "lastPoll": "Ultimo sondaggio",
10
+ "lastError": "Errore",
11
+ "itemsCollected": "elementi raccolti",
12
+ "itemsReceived": "elementi ricevuti",
13
+ "mastodonHint": "Impostare MASTODON_ACCESS_TOKEN e MASTODON_URL per attivare",
14
+ "blueskyHint": "Impostare BLUESKY_IDENTIFIER e BLUESKY_PASSWORD per attivare",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Attivato automaticamente quando l'endpoint ActivityPub riceve interazioni",
17
+ "webhookTitle": "Webhook / Ingest",
18
+ "webhookHint": "I servizi esterni possono inviare webmention all'endpoint di ingest",
19
+ "stats": "Statistiche",
20
+ "totalItems": "Totale elementi",
21
+ "replies": "Risposte",
22
+ "likes": "Mi piace",
23
+ "reposts": "Ricondivisioni",
24
+ "pollNow": "Sonda ora",
25
+ "recentActivity": "Attività recente",
26
+ "empty": "Nessuna interazione ancora. Configura le credenziali della piattaforma o invia webmention all'endpoint di ingest."
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
package/locales/nl.json CHANGED
@@ -12,6 +12,8 @@
12
12
  "itemsReceived": "items ontvangen",
13
13
  "mastodonHint": "Stel MASTODON_ACCESS_TOKEN en MASTODON_URL in om te activeren",
14
14
  "blueskyHint": "Stel BLUESKY_IDENTIFIER en BLUESKY_PASSWORD in om te activeren",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Automatisch ingeschakeld wanneer het ActivityPub-eindpunt interacties ontvangt",
15
17
  "webhookTitle": "Webhook / Opname",
16
18
  "webhookHint": "Externe diensten kunnen webmentions naar het opname-eindpunt sturen",
17
19
  "stats": "Statistieken",
@@ -26,7 +28,8 @@
26
28
  "source": {
27
29
  "webmention": "Webmention",
28
30
  "mastodon": "Mastodon",
29
- "bluesky": "Bluesky"
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
30
33
  }
31
34
  }
32
35
  }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "Konwersacje",
4
+ "dashboard": {
5
+ "connections": "Połączenia",
6
+ "connected": "Połączono",
7
+ "disconnected": "Nie skonfigurowano",
8
+ "ready": "Gotowe",
9
+ "lastPoll": "Ostatnie odpytanie",
10
+ "lastError": "Błąd",
11
+ "itemsCollected": "elementów zebranych",
12
+ "itemsReceived": "elementów otrzymanych",
13
+ "mastodonHint": "Ustaw MASTODON_ACCESS_TOKEN i MASTODON_URL, aby włączyć",
14
+ "blueskyHint": "Ustaw BLUESKY_IDENTIFIER i BLUESKY_PASSWORD, aby włączyć",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Włączane automatycznie, gdy endpoint ActivityPub odbiera interakcje",
17
+ "webhookTitle": "Webhook / Ingest",
18
+ "webhookHint": "Zewnętrzne usługi mogą wysyłać webmention do endpointu ingest",
19
+ "stats": "Statystyki",
20
+ "totalItems": "Łączna liczba elementów",
21
+ "replies": "Odpowiedzi",
22
+ "likes": "Polubienia",
23
+ "reposts": "Udostępnienia",
24
+ "pollNow": "Odpytaj teraz",
25
+ "recentActivity": "Ostatnia aktywność",
26
+ "empty": "Brak interakcji. Skonfiguruj dane uwierzytelniające platformy lub wyślij webmention do endpointu ingest."
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "Conversas",
4
+ "dashboard": {
5
+ "connections": "Conexões",
6
+ "connected": "Conectado",
7
+ "disconnected": "Não configurado",
8
+ "ready": "Pronto",
9
+ "lastPoll": "Última consulta",
10
+ "lastError": "Erro",
11
+ "itemsCollected": "itens coletados",
12
+ "itemsReceived": "itens recebidos",
13
+ "mastodonHint": "Defina MASTODON_ACCESS_TOKEN e MASTODON_URL para ativar",
14
+ "blueskyHint": "Defina BLUESKY_IDENTIFIER e BLUESKY_PASSWORD para ativar",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Ativado automaticamente quando o endpoint ActivityPub recebe interações",
17
+ "webhookTitle": "Webhook / Ingestão",
18
+ "webhookHint": "Serviços externos podem enviar webmentions para o endpoint de ingestão",
19
+ "stats": "Estatísticas",
20
+ "totalItems": "Total de itens",
21
+ "replies": "Respostas",
22
+ "likes": "Curtidas",
23
+ "reposts": "Republicações",
24
+ "pollNow": "Consultar agora",
25
+ "recentActivity": "Atividade recente",
26
+ "empty": "Nenhuma interação ainda. Configure as credenciais da plataforma ou envie webmentions para o endpoint de ingestão."
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
package/locales/pt.json CHANGED
@@ -12,6 +12,8 @@
12
12
  "itemsReceived": "itens recebidos",
13
13
  "mastodonHint": "Definir MASTODON_ACCESS_TOKEN e MASTODON_URL para ativar",
14
14
  "blueskyHint": "Definir BLUESKY_IDENTIFIER e BLUESKY_PASSWORD para ativar",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Ativado automaticamente quando o endpoint ActivityPub recebe interações",
15
17
  "webhookTitle": "Webhook / Ingesta",
16
18
  "webhookHint": "Servi\u00e7os externos podem enviar webmentions para o endpoint de ingesta",
17
19
  "stats": "Estat\u00edsticas",
@@ -26,7 +28,8 @@
26
28
  "source": {
27
29
  "webmention": "Webmention",
28
30
  "mastodon": "Mastodon",
29
- "bluesky": "Bluesky"
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
30
33
  }
31
34
  }
32
35
  }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "Разговори",
4
+ "dashboard": {
5
+ "connections": "Везе",
6
+ "connected": "Повезано",
7
+ "disconnected": "Није конфигурисано",
8
+ "ready": "Спремно",
9
+ "lastPoll": "Последње преузимање",
10
+ "lastError": "Грешка",
11
+ "itemsCollected": "ставки прикупљено",
12
+ "itemsReceived": "ставки примљено",
13
+ "mastodonHint": "Подесите MASTODON_ACCESS_TOKEN и MASTODON_URL да бисте омогућили",
14
+ "blueskyHint": "Подесите BLUESKY_IDENTIFIER и BLUESKY_PASSWORD да бисте омогућили",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Аутоматски се омогућава када ActivityPub крајња тачка прими интеракције",
17
+ "webhookTitle": "Webhook / Унос",
18
+ "webhookHint": "Спољне услуге могу слати вебменције на крајњу тачку за унос",
19
+ "stats": "Статистика",
20
+ "totalItems": "Укупно ставки",
21
+ "replies": "Одговори",
22
+ "likes": "Свиђања",
23
+ "reposts": "Дељења",
24
+ "pollNow": "Преузми сада",
25
+ "recentActivity": "Недавна активност",
26
+ "empty": "Још нема интеракција. Конфигуришите акредитиве платформе или пошаљите вебменције на крајњу тачку за унос."
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
package/locales/sv.json CHANGED
@@ -10,10 +10,12 @@
10
10
  "lastError": "Fel",
11
11
  "itemsCollected": "objekt insamlade",
12
12
  "itemsReceived": "objekt mottagna",
13
- "mastodonHint": "Ange MASTODON_ACCESS_TOKEN och MASTODON_URL f\u00f6r att aktivera",
14
- "blueskyHint": "Ange BLUESKY_IDENTIFIER och BLUESKY_PASSWORD f\u00f6r att aktivera",
13
+ "mastodonHint": "Ange MASTODON_ACCESS_TOKEN och MASTODON_URL för att aktivera",
14
+ "blueskyHint": "Ange BLUESKY_IDENTIFIER och BLUESKY_PASSWORD för att aktivera",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "Aktiveras automatiskt när ActivityPub-endpointen tar emot interaktioner",
15
17
  "webhookTitle": "Webhook / Inmatning",
16
- "webhookHint": "Externa tj\u00e4nster kan skicka webmentions till inmatningsendpointen",
18
+ "webhookHint": "Externa tjänster kan skicka webmentions till inmatningsendpointen",
17
19
  "stats": "Statistik",
18
20
  "totalItems": "Totalt antal objekt",
19
21
  "replies": "Svar",
@@ -21,12 +23,13 @@
21
23
  "reposts": "Delningar",
22
24
  "pollNow": "Polla nu",
23
25
  "recentActivity": "Senaste aktivitet",
24
- "empty": "Inga interaktioner \u00e4nnu. Konfigurera plattformsuppgifter eller skicka webmentions till inmatningsendpointen."
26
+ "empty": "Inga interaktioner ännu. Konfigurera plattformsuppgifter eller skicka webmentions till inmatningsendpointen."
25
27
  },
26
28
  "source": {
27
29
  "webmention": "Webmention",
28
30
  "mastodon": "Mastodon",
29
- "bluesky": "Bluesky"
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
30
33
  }
31
34
  }
32
35
  }
@@ -0,0 +1,35 @@
1
+ {
2
+ "conversations": {
3
+ "title": "对话",
4
+ "dashboard": {
5
+ "connections": "连接",
6
+ "connected": "已连接",
7
+ "disconnected": "未配置",
8
+ "ready": "就绪",
9
+ "lastPoll": "上次轮询",
10
+ "lastError": "错误",
11
+ "itemsCollected": "已收集条目",
12
+ "itemsReceived": "已接收条目",
13
+ "mastodonHint": "设置 MASTODON_ACCESS_TOKEN 和 MASTODON_URL 以启用",
14
+ "blueskyHint": "设置 BLUESKY_IDENTIFIER 和 BLUESKY_PASSWORD 以启用",
15
+ "activitypubTitle": "ActivityPub",
16
+ "activitypubHint": "当 ActivityPub 端点收到互动时自动启用",
17
+ "webhookTitle": "Webhook / 接收",
18
+ "webhookHint": "外部服务可以向接收端点发送 Webmention",
19
+ "stats": "统计",
20
+ "totalItems": "总条目数",
21
+ "replies": "回复",
22
+ "likes": "喜欢",
23
+ "reposts": "转发",
24
+ "pollNow": "立即轮询",
25
+ "recentActivity": "最近活动",
26
+ "empty": "暂无互动。请配置平台凭据或向接收端点发送 Webmention。"
27
+ },
28
+ "source": {
29
+ "webmention": "Webmention",
30
+ "mastodon": "Mastodon",
31
+ "bluesky": "Bluesky",
32
+ "activitypub": "ActivityPub"
33
+ }
34
+ }
35
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-conversations",
3
- "version": "2.2.0",
3
+ "version": "2.3.1",
4
4
  "description": "Conversation aggregation endpoint for Indiekit. Backend enrichment service that polls Mastodon/Bluesky notifications and serves JF2-compatible data for the interactions page.",
5
5
  "keywords": [
6
6
  "indiekit",