url-atproto
This commit is contained in:
parent
650e8446a0
commit
0b1dbc87ac
@ -25,6 +25,10 @@
|
|||||||
"name": "timezone",
|
"name": "timezone",
|
||||||
"version": "1.1.0"
|
"version": "1.1.0"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "url-atproto",
|
||||||
|
"version": "1.0.1"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "url-fediverse",
|
"name": "url-fediverse",
|
||||||
"version": "1.0.4"
|
"version": "1.0.4"
|
||||||
|
9
url-atproto/plugin.json
Normal file
9
url-atproto/plugin.json
Normal 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
175
url-atproto/plugin.ts
Normal 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
9
url-atproto/schema.json
Normal 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": []
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user