mirror of
https://github.com/snachodog/tok-to-insta-follower-bridge.git
synced 2025-04-23 20:12:22 -06:00
support for self hosted PDS
This commit is contained in:
parent
be2779da79
commit
d6ae71877b
74
README.md
74
README.md
@ -48,3 +48,77 @@ https://github.com/kawamataryo/sky-follower-bridge/assets/11070996/67bdd228-dc67
|
|||||||
## 🚨 Limitations
|
## 🚨 Limitations
|
||||||
|
|
||||||
- User search may fail due to late limit in Bluesky's API. In this case, please wait for 2 to 3 minutes and execute the search again.
|
- User search may fail due to late limit in Bluesky's API. In this case, please wait for 2 to 3 minutes and execute the search again.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
- `PLASMO_PUBLIC_BSKY_DOMAIN`: The Bluesky domain to use (default: "bsky.social")
|
||||||
|
|
||||||
|
## Building for Custom PDS Servers
|
||||||
|
|
||||||
|
If you want to use this extension with a custom PDS (Personal Data Server) instead of the default bsky.social, you have two options:
|
||||||
|
|
||||||
|
### Option 1: Using .env file
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/kawamataryo/sky-follower-bridge.git
|
||||||
|
cd sky-follower-bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install dependencies:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Create a `.env` file in the root directory:
|
||||||
|
```bash
|
||||||
|
echo "PLASMO_PUBLIC_BSKY_DOMAIN=bsky.social" > .env
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Build the extension:
|
||||||
|
```bash
|
||||||
|
# For Chrome
|
||||||
|
npm run build
|
||||||
|
npm run package
|
||||||
|
|
||||||
|
# For Firefox
|
||||||
|
npm run build:firefox
|
||||||
|
npm run package:firefox
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Using environment variable directly
|
||||||
|
|
||||||
|
You can also pass the domain directly during build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# For Chrome
|
||||||
|
PLASMO_PUBLIC_BSKY_DOMAIN=your-custom-domain.com npm run build
|
||||||
|
PLASMO_PUBLIC_BSKY_DOMAIN=your-custom-domain.com npm run package
|
||||||
|
|
||||||
|
# For Firefox
|
||||||
|
PLASMO_PUBLIC_BSKY_DOMAIN=your-custom-domain.com npm run build:firefox
|
||||||
|
PLASMO_PUBLIC_BSKY_DOMAIN=your-custom-domain.com npm run package:firefox
|
||||||
|
```
|
||||||
|
|
||||||
|
### Loading the Built Extension
|
||||||
|
|
||||||
|
After building, you can load the extension:
|
||||||
|
|
||||||
|
**For Chrome/Edge:**
|
||||||
|
1. Go to `chrome://extensions/` (or `edge://extensions/`)
|
||||||
|
2. Enable "Developer mode" in the top right
|
||||||
|
3. Click "Load unpacked"
|
||||||
|
4. Select the `build/chrome-mv3-prod` directory
|
||||||
|
|
||||||
|
**For Firefox:**
|
||||||
|
1. Go to `about:debugging#/runtime/this-firefox`
|
||||||
|
2. Click "Load Temporary Add-on"
|
||||||
|
3. Select the zip file from the `dist` directory
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
- The built extension will be in the `build` directory
|
||||||
|
- The packaged extension (.zip) will be in the `dist` directory
|
||||||
|
- When using a custom PDS, users will need to use handles in the format `username.your-custom-domain.com`
|
||||||
|
- Make sure your custom PDS server is compatible with the AT Protocol
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { AtUri, AtpAgent, type AtpSessionData } from "@atproto/api";
|
import { AtUri, AtpAgent, type AtpSessionData } from "@atproto/api";
|
||||||
|
import { BSKY_DOMAIN } from "./constants";
|
||||||
|
|
||||||
// try and cut down the amount of session resumes by caching the clients
|
// try and cut down the amount of session resumes by caching the clients
|
||||||
const clientCache = new Map<string, BskyClient>();
|
const clientCache = new Map<string, BskyClient>();
|
||||||
@ -10,7 +11,7 @@ export type BskyLoginParams = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class BskyClient {
|
export class BskyClient {
|
||||||
private service = "https://bsky.social";
|
private service = `https://${BSKY_DOMAIN}`;
|
||||||
me: {
|
me: {
|
||||||
did: string;
|
did: string;
|
||||||
handle: string;
|
handle: string;
|
||||||
|
@ -99,3 +99,5 @@ export const DOCUMENT_LINK = {
|
|||||||
PAGE_ERROR:
|
PAGE_ERROR:
|
||||||
"https://www.sky-follower-bridge.dev/troubleshooting.html#page-errors",
|
"https://www.sky-follower-bridge.dev/troubleshooting.html#page-errors",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const BSKY_DOMAIN = process.env.PLASMO_PUBLIC_BSKY_DOMAIN || "bsky.social";
|
@ -1,3 +1,5 @@
|
|||||||
|
import { BSKY_DOMAIN } from "./constants";
|
||||||
|
|
||||||
export const getUserCells = ({
|
export const getUserCells = ({
|
||||||
queryParam,
|
queryParam,
|
||||||
filterInsertedElement,
|
filterInsertedElement,
|
||||||
@ -20,13 +22,14 @@ export const getUserCells = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getAccountNameAndDisplayName = (userCell: Element) => {
|
export const getAccountNameAndDisplayName = (userCell: Element) => {
|
||||||
const [avatarEl, displayNameEl] = userCell.querySelectorAll("a");
|
const anchors = Array.from(userCell.querySelectorAll("a"));
|
||||||
|
const [avatarEl, displayNameEl] = anchors;
|
||||||
const twAccountName = avatarEl?.getAttribute("href")?.replace("/", "");
|
const twAccountName = avatarEl?.getAttribute("href")?.replace("/", "");
|
||||||
const twAccountNameRemoveUnderscore = twAccountName.replaceAll("_", ""); // bsky does not allow underscores in handle, so remove them.
|
const twAccountNameRemoveUnderscore = twAccountName.replaceAll("_", ""); // bsky does not allow underscores in handle, so remove them.
|
||||||
const twAccountNameReplaceUnderscore = twAccountName.replaceAll("_", "-");
|
const twAccountNameReplaceUnderscore = twAccountName.replaceAll("_", "-");
|
||||||
const twDisplayName = displayNameEl?.textContent;
|
const twDisplayName = displayNameEl?.textContent;
|
||||||
const bskyHandle =
|
const bskyHandle =
|
||||||
userCell.textContent?.match(/([^/\s]+\.bsky\.social)/)?.[1] ??
|
userCell.textContent?.match(new RegExp(`([^/\\s]+\\.${BSKY_DOMAIN})`))?.[1] ??
|
||||||
userCell.textContent
|
userCell.textContent
|
||||||
?.match(/bsky\.app\/profile\/([^/\s]+)…?/)?.[1]
|
?.match(/bsky\.app\/profile\/([^/\s]+)…?/)?.[1]
|
||||||
?.replace("…", "") ??
|
?.replace("…", "") ??
|
||||||
|
@ -14,6 +14,7 @@ import {
|
|||||||
RATE_LIMIT_ERROR_MESSAGE,
|
RATE_LIMIT_ERROR_MESSAGE,
|
||||||
STORAGE_KEYS,
|
STORAGE_KEYS,
|
||||||
TARGET_URLS_REGEX,
|
TARGET_URLS_REGEX,
|
||||||
|
BSKY_DOMAIN,
|
||||||
} from "~lib/constants";
|
} from "~lib/constants";
|
||||||
|
|
||||||
function IndexPopup() {
|
function IndexPopup() {
|
||||||
@ -135,7 +136,7 @@ function IndexPopup() {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
const formattedIdentifier = (
|
const formattedIdentifier = (
|
||||||
identifier.includes(".") ? identifier : `${identifier}.bsky.social`
|
identifier.includes(".") ? identifier : `${identifier}.${BSKY_DOMAIN}`
|
||||||
).replace(/^@/, "");
|
).replace(/^@/, "");
|
||||||
try {
|
try {
|
||||||
const { session, error } = await sendToBackground({
|
const { session, error } = await sendToBackground({
|
||||||
@ -236,7 +237,7 @@ function IndexPopup() {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="identifier"
|
name="identifier"
|
||||||
placeholder="your-username.bsky.social"
|
placeholder={`your-username.${BSKY_DOMAIN}`}
|
||||||
value={identifier}
|
value={identifier}
|
||||||
onChange={(e) => setIdentifier(e.target.value)}
|
onChange={(e) => setIdentifier(e.target.value)}
|
||||||
className="input input-bordered input-sm w-full max-w-xs join-item focus:outline-none mt-1"
|
className="input input-bordered input-sm w-full max-w-xs join-item focus:outline-none mt-1"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user