url-atproto

This commit is contained in:
Evert Prants 2024-11-23 11:35:50 +02:00
parent 650e8446a0
commit 0b1dbc87ac
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
4 changed files with 197 additions and 0 deletions

View File

@ -25,6 +25,10 @@
"name": "timezone",
"version": "1.1.0"
},
{
"name": "url-atproto",
"version": "1.0.1"
},
{
"name": "url-fediverse",
"version": "1.0.4"

9
url-atproto/plugin.json Normal file
View File

@ -0,0 +1,9 @@
{
"main": "plugin.js",
"name": "url-atproto",
"description": "AT Protocol (Bluesky) URL",
"version": "1.0.1",
"tags": ["urlreply", "at-protocol", "bluesky"],
"dependencies": ["urlreply"],
"npmDependencies": []
}

175
url-atproto/plugin.ts Normal file
View File

@ -0,0 +1,175 @@
import {
Plugin,
Configurable,
EventListener,
DependencyLoad,
} from '@squeebot/core/lib/plugin';
import { IMessage } from '@squeebot/core/lib/types';
import { httpGET, sanitizeEscapedText } from '@squeebot/core/lib/common';
interface ATRecordEmbed {
$type: string;
images: [
{
alt: string;
aspectRatio: {
height: number;
width: number;
};
image: {
$type: string;
ref: {
$link: string;
};
mimeType: string;
size: number;
};
}
];
}
interface ATRecord {
$type: string;
createdAt: string;
langs: string[];
text: string;
embed?: ATRecordEmbed;
facets?: unknown[];
}
interface ATEmbed {
$type: string;
images?: [
{
thumb: string;
fullsize: string;
alt: string;
aspectRatio: {
height: number;
width: number;
};
}
];
record?: ATRecord;
}
interface ATThread {
thread: {
$type: 'app.bsky.feed.defs#threadViewPost';
post: {
uri: string;
cid: string;
author: {
did: string;
handle: string;
displayName: string;
avatar: string;
labels: unknown[];
createdAt: string;
};
record: ATRecord;
embed?: ATEmbed;
replyCount: number;
repostCount: number;
likeCount: number;
quoteCount: number;
indexedAt: string;
labels: unknown[];
};
replies: ATThread['thread'][];
};
}
@Configurable({})
class TwitterURLPlugin extends Plugin {
@EventListener('pluginUnload')
public unloadEventHandler(plugin: string | Plugin): void {
if (plugin === this.name || plugin === this) {
this.emit('pluginUnloaded', this);
}
}
async handlePost(
data: ATThread['thread']['post'],
msg: IMessage
): Promise<boolean> {
const keys = [];
const end = sanitizeEscapedText(data.record.text);
keys.push(['field', 'Bluesky', { color: 'cyan', type: 'title' }]);
keys.push([
'field',
data.likeCount.toString(),
{ color: 'red', label: ['♥', 'Likes'], type: 'metric' },
]);
keys.push([
'field',
data.repostCount.toString(),
{ color: 'green', label: ['↱↲', 'Reposts'], type: 'metric' },
]);
keys.push(['bold', '@' + data.author.handle + ':']);
keys.push(['field', end, { type: 'content' }]);
if (data.embed?.images?.length) {
const amount = data.embed.images.length;
keys.push([
'field',
`[${amount} attachment${amount !== 1 ? 's' : ''}]`,
{ color: 'brown' },
]);
}
if (data.embed?.record) {
keys.push(['field', '[quoted post]', { color: 'brown' }]);
}
msg.resolve(keys);
return true;
}
async atprotoGetThread(url: URL, msg: IMessage): Promise<boolean> {
const urlString = url.toString();
const det = urlString.match(
/^(https?):\/\/((?:[\w\d-]+\.)*[\w\d-]+\.\w{2,16})\/(?:profile\/)?@?([\d\w-_.]+)\/(?:post\/)?([\w\d]+[^&#?\s/])/i
);
if (!det) {
return false;
}
const [_, proto, webviewHost, atHost, postId] = det;
if (proto !== 'https' || webviewHost !== 'bsky.app') {
// no other webviews atm
return false;
}
try {
const postInfo = await httpGET(
`https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?depth=1&parentHeight=1&uri=at://${atHost}/app.bsky.feed.post/${postId}`
);
const data = JSON.parse(postInfo) as ATThread;
if (data?.thread) {
return this.handlePost(data.thread.post, msg);
}
} catch (e) {
msg.resolve('Could not fetch Bluesky post, it may be private.');
}
return false;
}
@DependencyLoad('urlreply')
addURLHandler(urlreply: any): void {
urlreply.registerHandler(
this.name,
'bsky.app/',
(url: URL, msg: IMessage) => {
return this.atprotoGetThread(url, msg);
}
);
}
}
module.exports = TwitterURLPlugin;

9
url-atproto/schema.json Normal file
View File

@ -0,0 +1,9 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://squeebot.lunasqu.ee/pkg/plugins-evert/url-atproto.schema.json",
"title": "url-atproto",
"description": "url-atproto plugin configuration",
"type": "object",
"properties": {},
"required": []
}