Skip to content

Commit

Permalink
Allow specifying reply to URL for Bluesky posts
Browse files Browse the repository at this point in the history
Analogous to the Mastodon implementation in the previous commit, except
more complicated because Bluesky.
  • Loading branch information
askmeaboutlo0m committed Oct 2, 2023
1 parent 1a1ffc4 commit c588c40
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import { DefaultFileOptions } from '../../submission/default-options.interface';
export interface BlueskyFileOptions extends DefaultFileOptions {
altText?: string;
label_rating: string;
replyToUrl?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import { DefaultOptions } from '../../submission/default-options.interface';

export interface BlueskyNotificationOptions extends DefaultOptions {
label_rating: string;
replyToUrl?: string;
}
5 changes: 5 additions & 0 deletions commons/src/websites/bluesky/bluesky.file.options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export class BlueskyFileOptionsEntity
@DefaultValue('')
label_rating: string = '';

@Expose()
@IsOptional()
@IsString()
replyToUrl?: string;

constructor(entity?: Partial<BlueskyFileOptions>) {
super(entity as DefaultFileOptions);
}
Expand Down
5 changes: 5 additions & 0 deletions commons/src/websites/bluesky/bluesky.notification.options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export class BlueskyNotificationOptionsEntity
@DefaultValue('')
label_rating: string = '';

@Expose()
@IsOptional()
@IsString()
replyToUrl?: string;

constructor(entity?: Partial<BlueskyNotificationOptions>) {
super(entity as DefaultOptions);
}
Expand Down
54 changes: 53 additions & 1 deletion electron-app/src/server/websites/bluesky/bluesky.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { BskyAgent, stringifyLex, jsonToLex, AppBskyEmbedImages, AppBskyRichtex
import { PlaintextParser } from 'src/server/description-parsing/plaintext/plaintext.parser';
import fetch from "node-fetch";
import Graphemer from 'graphemer';
import { ReplyRef } from '@atproto/api/dist/client/types/app/bsky/feed/post';

// Start of Polyfill

Expand Down Expand Up @@ -197,6 +198,8 @@ export class Bluesky extends Website {
password: accountData.password,
});

const reply = await this.getReplyRef(agent, data.options.replyToUrl);

const files = [data.primary, ...data.additional];
let uploadedMedias: AppBskyEmbedImages.Image[] = [];
let fileCount = 0;
Expand Down Expand Up @@ -256,6 +259,7 @@ export class Bluesky extends Website {
facets: rt.facets,
embed: embeds,
labels: labelsRecord,
...(reply ? { reply } : {}),
})
.catch(err => {
return Promise.reject(this.createPostResponse({ message: err }));
Expand Down Expand Up @@ -284,6 +288,7 @@ export class Bluesky extends Website {
password: accountData.password,
});

const reply = await this.getReplyRef(agent, data.options.replyToUrl);
let status = data.description;
let r = new RichText({text: status});

Expand Down Expand Up @@ -322,7 +327,8 @@ export class Bluesky extends Website {
let postResult = await agent.post({
text: rt.text,
facets: rt.facets,
labels: labelsRecord
labels: labelsRecord,
...(reply ? { reply } : {}),
}).catch(err => {
return Promise.reject(
this.createPostResponse({ message: err }),
Expand Down Expand Up @@ -403,6 +409,8 @@ export class Bluesky extends Website {
);
}

this.validateReplyToUrl(problems, submissionPart.data.replyToUrl);

return { problems, warnings };
}

Expand All @@ -424,6 +432,50 @@ export class Bluesky extends Website {
);
}

this.validateReplyToUrl(problems, submissionPart.data.replyToUrl);

return { problems, warnings };
}

private validateReplyToUrl(problems: string[], url?: string): void {
if(url?.trim() && !this.getPostIdFromUrl(url)) {
problems.push("Invalid post URL to reply to.");
}
}

private async getReplyRef(agent: BskyAgent, url?: string): Promise<ReplyRef | null> {
if (!url?.trim()) {
return null;
}

const postId = this.getPostIdFromUrl(url);
if (!postId) {
throw new Error(`Invalid reply to url '${url}'`);
}

// cf. https://atproto.com/blog/create-post#replies
const parent = await agent.getPost(postId);
const reply = parent.value.reply;
const root = reply ? reply.root : parent;
return {
root: { uri: root.uri, cid: root.cid },
parent: { uri: parent.uri, cid: parent.cid },
};
}

private getPostIdFromUrl(url: string): { repo: string; rkey: string } | null {
// A regular web link like https://bsky.app/profile/{repo}/post/{id}
const link = /\/profile\/([^\/]+)\/post\/([a-zA-Z0-9\.\-_~]+)/.exec(url);
if (link) {
return { repo: link[1], rkey: link[2] };
}

// Protocol link like at://did:plc:{repo}/app.bsky.feed.post/{id}
const at = /(did:plc:[a-zA-Z0-9\.\-_~]+)\/.+\.post\/([a-zA-Z0-9\.\-_~]+)/.exec(url);
if (at) {
return { repo: at[1], rkey: at[2] };
}

return null;
}
}
10 changes: 8 additions & 2 deletions ui/src/websites/bluesky/Bluesky.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ BlueskyNotificationOptions
<Select.Option value={'nudity'}>Adult: Nudity</Select.Option>
<Select.Option value={'porn'}>Adult: Porn</Select.Option>
</Select>
</Form.Item>,
</Form.Item>,
<Form.Item label="Reply To Post URL">
<Input value={data.replyToUrl} onChange={this.handleValueChange.bind(this, 'replyToUrl')} />
</Form.Item>,
);
return elements;
}
Expand All @@ -84,13 +87,16 @@ export class BlueskyFileSubmissionForm extends GenericFileSubmissionSection<Blue
<Select.Option value={'nudity'}>Adult: Nudity</Select.Option>
<Select.Option value={'porn'}>Adult: Porn</Select.Option>
</Select>
</Form.Item>,
</Form.Item>,
<Form.Item label="Alt Text">
<Input
value={data.altText}
onChange={this.handleValueChange.bind(this, 'altText')}
/>
</Form.Item>,
<Form.Item label="Reply To Post URL">
<Input value={data.replyToUrl} onChange={this.handleValueChange.bind(this, 'replyToUrl')} />
</Form.Item>,
);
return elements;
}
Expand Down

0 comments on commit c588c40

Please sign in to comment.