From b667a875c834ccb2867e22221f3c9d7720ab7997 Mon Sep 17 00:00:00 2001 From: Andrea Vos Date: Wed, 20 Nov 2024 23:03:30 +0100 Subject: [PATCH] (calendar) bsky bot --- server/calendarBot.js | 60 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/server/calendarBot.js b/server/calendarBot.js index cb446db7c..5c9eb92b6 100644 --- a/server/calendarBot.js +++ b/server/calendarBot.js @@ -6,6 +6,7 @@ import * as Sentry from '@sentry/node'; import Mastodon from 'mastodon'; import fetch from 'node-fetch'; import Twitter from 'twitter'; +import {AtpAgent, RichText} from '@atproto/api'; import buildLocaleList from '../src/buildLocaleList.ts'; @@ -14,7 +15,7 @@ const __dirname = new URL('.', import.meta.url).pathname; const locales = buildLocaleList('_'); const publishers = { - async twitter(tweet, _image, previousId, _locale) { + async twitter(tweet, _image, _rootId, previousId, _locale) { const client = new Twitter({ consumer_key: process.env.TWITTER_CALENDAR_CONSUMER_KEY, consumer_secret: process.env.TWITTER_CALENDAR_CONSUMER_SECRET, @@ -34,7 +35,7 @@ const publishers = { Sentry.captureException(error); } }, - async mastodon(tweet, image, previousId, locale) { + async mastodon(tweet, image, _rootId, previousId, locale) { const client = new Mastodon({ access_token: process.env.MASTODON_ACCESS_TOKEN, api_url: `https://${process.env.MASTODON_INSTANCE}/api/v1/`, @@ -68,12 +69,63 @@ const publishers = { Sentry.captureException(error); } }, + async bluesky(tweet, image, rootId, previousId, locale) { + const agent = new AtpAgent({ service: 'https://bsky.social' }); + await agent.login({ + identifier: process.env.BLUESKY_CALENDAR_IDENTIFIER, + password: process.env.BLUESKY_CALENDAR_PASSWORD, + }); + + const media = []; + if (image) { + try { + const uploadResponse = await agent.uploadBlob(image, { encoding: 'image/png' }); + console.log(uploadResponse); + media.push(uploadResponse.data.blob); + } catch (error) { + Sentry.captureException(error); + } + } + + try { + const rt = new RichText({ + text: tweet, + }) + await rt.detectFacets(agent); + + const postResponse = await agent.post({ + $type: 'app.bsky.feed.post', + text: rt.text, + facets: rt.facets, + embed: { + $type: 'app.bsky.embed.images', + images: media.map(blob => ({ image: blob, alt: '' })), + }, + ...previousId ? { + reply: { + root: rootId, + parent: previousId, + } + } : {}, + langs: [locale], + createdAt: new Date().toISOString(), + }); + console.log(postResponse); + return { + uri: postResponse.uri, + cid: postResponse.cid, + } + } catch (error) { + Sentry.captureException(error); + } + }, }; const tmpDir = `${__dirname}/../cache/tmp`; fs.mkdirSync(tmpDir, { recursive: true }); const imageTmpPath = `${tmpDir}/calendar-tmp.png`; +const rootPostId = {}; const lastPostId = {}; (async () => { @@ -106,10 +158,14 @@ const lastPostId = {}; const postId = await publishers[publisher]( message, imageStream, + rootPostId[publisher], lastPostId[publisher], locale, ); console.log(postId); + if (!rootPostId[publisher]) { + rootPostId[publisher] = postId; + } lastPostId[publisher] = postId; } } catch (error) {