README and ca
This commit is contained in:
611
README.md
611
README.md
@@ -1,497 +1,242 @@
|
||||
# post2bsky
|
||||
# post2bsky 🦋
|
||||
|
||||
A Python-based automation tool for reposting content to Bluesky from RSS feeds and Twitter accounts. Includes a daemon mode for continuous operation with comprehensive media support, deduplication, and extensive logging.
|
||||
Una col·lecció d'eines Python per mirar contingut automàticament a [Bluesky](https://bsky.app), incloent publicacions de Twitter/X, feeds RSS i vídeos de TikTok. Dissenyat per executar-se com a tasques programades de CI/CD (GitHub Actions o Jenkins).
|
||||
|
||||
**Note**: This tool is designed for content creators and maintainers who need to automatically synchronize feeds/accounts to Bluesky. Ensure you have permission to repost content and comply with all platform terms of service.
|
||||
---
|
||||
|
||||
## ✨ Features
|
||||
## 📦 Scripts Disponibles
|
||||
|
||||
- **RSS → Bluesky**: Parse RSS feeds and automatically post new entries with proper formatting
|
||||
- **Twitter → Bluesky**: Scrape tweets from Twitter accounts and repost to Bluesky (with media)
|
||||
- **Daemon Mode**: Run continuously as a background service for unattended operation
|
||||
- **Media Support**: Handle images, videos, and other media with automatic optimization
|
||||
- **Deduplication**: Track posted content to prevent duplicates across runs
|
||||
- **Configurable Workflows**: YAML-based pipelines for each source with scheduling
|
||||
- **Media Constraints**: Auto-handles Bluesky's limits (300 chars, 4 images, 45MB video, etc.)
|
||||
- **Error Recovery**: Automatic retries with exponential backoff for transient failures
|
||||
- **Comprehensive Logging**: Detailed logs for monitoring and troubleshooting
|
||||
Aquesta taula resumeix les eines principals incloses en el projecte i la seva funció.
|
||||
|
||||
## 📋 Prerequisites
|
||||
| Script | Descripció |
|
||||
|---|---|
|
||||
| `twitter2bsky.py` | Miralla publicacions d'un compte de Twitter/X a Bluesky |
|
||||
| `rss2bsky.py` | Publica elements d'un feed RSS a Bluesky |
|
||||
| `twitter_login.py` | Extreu un token d'autenticació de Twitter mitjançant un navegador headless i desa un fitxer de sessió |
|
||||
| `tiktok2bsky.py` | Scrapes vídeos recents d'un perfil públic de TikTok i els publica a Bluesky |
|
||||
|
||||
- Python 3.9 or higher
|
||||
- macOS, Linux, or Windows with Chromium support (for Twitter scraping)
|
||||
- Bluesky account with credentials
|
||||
- Twitter account (if using Twitter→Bluesky syncing)
|
||||
Aquests scripts formen el nucli de l'automatització del teu contingut cap a Bluesky.
|
||||
|
||||
## 🚀 Quick Start
|
||||
---
|
||||
|
||||
### 1. Clone & Setup Environment
|
||||
## ⚙️ Requisits i Instal·lació
|
||||
|
||||
### Sistema
|
||||
|
||||
- **Python:** 3.10 o superior.
|
||||
- **FFmpeg:** Necessari per a la llibreria `moviepy` (per al processament de vídeo).
|
||||
|
||||
### Dependències Python
|
||||
|
||||
Instal·la tots els paquets necessaris executant el següent comandament:
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd post2bsky
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||
pip install -r requeriments.txt
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 2. Configure Credentials
|
||||
*(Les dependències inclouen: `atproto`, `tweety-ns`, `playwright`, `playwright-stealth`, `httpx`, `arrow`, `python-dotenv`, `moviepy`, `fastfeedparser`, `beautifulsoup4`, `charset-normalizer`, `Pillow` i `grapheme`)*
|
||||
|
||||
Create a `.env` file in the project root:
|
||||
### Navegador Playwright
|
||||
|
||||
```env
|
||||
# Bluesky Authentication
|
||||
BSKY_USERNAME=your_bluesky_handle
|
||||
BSKY_PASSWORD=your_bluesky_password
|
||||
|
||||
# Optional: Custom Bluesky instance (default: https://bsky.social)
|
||||
BSKY_BASE_URL=https://bsky.social
|
||||
|
||||
# Twitter Authentication (if using Twitter syncing)
|
||||
TWITTER_USERNAME=your_twitter_handle
|
||||
TWITTER_PASSWORD=your_twitter_password
|
||||
```
|
||||
|
||||
### 3. Run a Quick Test
|
||||
Després d'instal·lar les dependències, cal instal·lar el binari del navegador Chromium perquè el login headless funcioni:
|
||||
|
||||
```bash
|
||||
# Test RSS feed posting
|
||||
python rss2bsky.py --feed-url https://example.com/rss
|
||||
|
||||
# Test Twitter account scraping
|
||||
python twitter2bsky_daemon.py --test
|
||||
python -m playwright install chromium
|
||||
```
|
||||
|
||||
## Installation
|
||||
---
|
||||
|
||||
### Standard Installation
|
||||
## 🔐 Configuració de Credencials
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone https://github.com/yourusername/post2bsky.git
|
||||
cd post2bsky
|
||||
```
|
||||
Els scripts requereixen les següents credencials, ja sigui com a variables d'entorn, un fitxer `.env` o secrets de CI/CD.
|
||||
|
||||
2. Create and activate virtual environment:
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate # macOS/Linux
|
||||
# or
|
||||
venv\Scripts\activate # Windows
|
||||
```
|
||||
| Variable | Utilitzada per | Descripció |
|
||||
|---|---|---|
|
||||
| `TWITTER_USERNAME` | `twitter2bsky.py`, `twitter_login.py` | Nom d'usuari de Twitter/X |
|
||||
| `TWITTER_PASSWORD` | `twitter2bsky.py`, `twitter_login.py` | Contrasenya de Twitter/X |
|
||||
| `TWITTER_EMAIL` | `twitter2bsky.py` | Correu electrònic del compte de Twitter/X |
|
||||
| `TWITTER_HANDLE` | `twitter2bsky.py` | Handle de Twitter/X a mirallar (p. ex. `elmeuhandle`) |
|
||||
| `BSKY_HANDLE` | `twitter2bsky.py`, `rss2bsky.py`, `tiktok2bsky.py` | Handle de Bluesky (p. ex. `jo.bsky.social`) |
|
||||
| `BSKY_USERNAME` | `rss2bsky.py` | Nom d'usuari de Bluesky |
|
||||
| `BSKY_APP_PASSWORD` | `twitter2bsky.py`, `rss2bsky.py`, `tiktok2bsky.py` | Contrasenya d'aplicació de Bluesky |
|
||||
| `TIKTOK_HANDLE` | `tiktok2bsky.py` | Handle del perfil públic de TikTok a mirallar |
|
||||
|
||||
3. Install dependencies:
|
||||
```bash
|
||||
pip install -r requeriments.txt
|
||||
```
|
||||
**Important:** No facis mai commit de les credencials al repositori. Utilitza un fitxer `.env` localment (ja cobert per `.gitignore`) o secrets de CI/CD en producció.
|
||||
|
||||
4. Set up environment variables:
|
||||
Create a `.env` file in the root directory (see [Credentials](#-credentials) section)
|
||||
---
|
||||
|
||||
## ⚙️ Configuration
|
||||
## 🚀 Guia d'Ús
|
||||
|
||||
### Credentials
|
||||
### 1. Obtenir un token de sessió de Twitter (`twitter_login.py`)
|
||||
|
||||
Your credentials should be stored in `.env` file at the project root. This file should never be committed to version control (already in `.gitignore`):
|
||||
|
||||
```env
|
||||
BSKY_USERNAME=your_bluesky_handle
|
||||
BSKY_PASSWORD=your_bluesky_password
|
||||
|
||||
# For Twitter scraping (email or username, and password)
|
||||
TWITTER_USERNAME=your_twitter_username_or_email
|
||||
TWITTER_PASSWORD=your_twitter_password
|
||||
```
|
||||
|
||||
**Security Note**: Never commit credentials to Git. The `.env` file is automatically ignored.
|
||||
|
||||
### RSS Feed Configuration
|
||||
|
||||
Run `rss2bsky.py` to post from RSS feeds:
|
||||
Executa això una sola vegada per autenticar-te i desar un fitxer de sessió reutilitzable:
|
||||
|
||||
```bash
|
||||
# Basic usage
|
||||
python rss2bsky.py --feed-url https://example.com/rss --bsky-handle your_handle
|
||||
python twitter_login.py 'EL_TEU_USUARI' 'LA_TEVA_CONTRASENYA'
|
||||
```
|
||||
|
||||
# With advanced options
|
||||
⚠️ **Atenció:** Utilitza sempre cometes simples al voltant de la contrasenya per evitar que la shell interpreti caràcters especials com `!`, `$` o les cometes inverses.
|
||||
|
||||
En cas d'èxit, es crea un fitxer `my_account_session` al directori de treball. Els scripts posteriors reutilitzaran aquesta sessió sense necessitat de tornar a iniciar sessió. Si alguna cosa va malament, es desarà un `error_screenshot.png` al directori de treball perquè puguis veure exactament què ha trobat el navegador.
|
||||
|
||||
### 2. Mirallar Twitter a Bluesky (`twitter2bsky.py`)
|
||||
|
||||
Utilitza aquest script per sincronitzar les teves publicacions:
|
||||
|
||||
```bash
|
||||
python twitter2bsky.py \
|
||||
--twitter-username "EL_TEU_USUARI" \
|
||||
--twitter-password "LA_TEVA_CONTRASENYA" \
|
||||
--twitter-email "EL_TEU_CORREU" \
|
||||
--twitter-handle "EL_TEU_HANDLE" \
|
||||
--bsky-handle "EL_TEU_HANDLE.bsky.social" \
|
||||
--bsky-password "LA_TEVA_APP_PASSWORD" \
|
||||
--bsky-base-url "https://bsky.social" \
|
||||
--bsky-langs "ca"
|
||||
```
|
||||
|
||||
### 3. Publicar un feed RSS a Bluesky (`rss2bsky.py`)
|
||||
|
||||
Per enviar contingut des d'un RSS directament al teu perfil de Bluesky:
|
||||
|
||||
```bash
|
||||
python rss2bsky.py \
|
||||
--feed-url https://example.com/rss \
|
||||
--bsky-handle your_handle \
|
||||
--max-posts 5 \
|
||||
--limit-age 3 # Only posts from last 3 days
|
||||
"https://example.com/feed.rss" \
|
||||
"EL_TEU_BSKY_HANDLE" \
|
||||
"EL_TEU_BSKY_USERNAME" \
|
||||
"LA_TEVA_APP_PASSWORD" \
|
||||
--service "https://bsky.social"
|
||||
```
|
||||
|
||||
**State Management**: The tool tracks posted entries in `twitter2bsky_state.json` to prevent duplicates. This file is updated automatically on each run.
|
||||
### 4. Mirallar TikTok a Bluesky (`tiktok2bsky.py`)
|
||||
|
||||
### Twitter Account Configuration
|
||||
#### 🍪 Gestió de les cookies de TikTok
|
||||
|
||||
Configure Twitter accounts in `twitter2bsky_daemon.py`. The script uses Playwright for browser automation to scrape tweets:
|
||||
TikTok requereix cookies vàlides de sessió per poder accedir als perfils sense ser bloquejat. El fitxer `tiktok_cookies.json` conté aquestes cookies i **cal generar-lo manualment** seguint aquests passos:
|
||||
|
||||
1. **Obre el navegador** (Chrome o Firefox) i accedeix a [https://www.tiktok.com](https://www.tiktok.com).
|
||||
2. **Inicia sessió** amb el teu compte de TikTok (o simplement navega fins que TikTok carregui correctament sense modals de cookies).
|
||||
3. **Obre les DevTools** (`F12`) → pestanya **Application** (Chrome) o **Storage** (Firefox).
|
||||
4. A la secció **Cookies → https://www.tiktok.com**, exporta totes les cookies.
|
||||
5. Desa-les en format JSON com a `tiktok_cookies.json` al directori arrel del projecte.
|
||||
|
||||
Pots utilitzar extensions de navegador com [EditThisCookie](https://chrome.google.com/webstore/detail/editthiscookie) o [Cookie-Editor](https://cookie-editor.cgagnier.ca/) per exportar les cookies directament en format JSON compatible.
|
||||
|
||||
El fitxer ha de tenir aquest format:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "sessionid",
|
||||
"value": "el_teu_valor",
|
||||
"domain": ".tiktok.com",
|
||||
"path": "/",
|
||||
"httpOnly": true,
|
||||
"secure": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
> ⚠️ **Les cookies de TikTok caduquen periòdicament.** Si el script deixa de funcionar o no troba vídeos, regenera el fitxer `tiktok_cookies.json` repetint el procés anterior.
|
||||
|
||||
> 🔒 **No facis mai commit del fitxer `tiktok_cookies.json`** al repositori. Ja està cobert pel `.gitignore`. En entorns CI/CD, injecta'l com a secret o artifact protegit.
|
||||
|
||||
#### ▶️ Execució de `tiktok2bsky.py`
|
||||
|
||||
Un cop tens el fitxer de cookies, executa el script així:
|
||||
|
||||
```bash
|
||||
# Run Twitter daemon
|
||||
python twitter2bsky_daemon.py
|
||||
|
||||
# Run with test mode (dry-run, no posting)
|
||||
python twitter2bsky_daemon.py --test
|
||||
|
||||
# Specify custom state file
|
||||
python twitter2bsky_daemon.py --state-file custom_state.json
|
||||
python tiktok2bsky.py \
|
||||
--tiktok-handle "EL_HANDLE_DE_TIKTOK" \
|
||||
--bsky-handle "EL_TEU_HANDLE.bsky.social" \
|
||||
--bsky-app-password "xxxx-xxxx-xxxx-xxxx" \
|
||||
--bsky-base-url "https://bsky.social" \
|
||||
--bsky-langs "ca" \
|
||||
--cookies-path "tiktok_cookies.json"
|
||||
```
|
||||
|
||||
**Twitter Scraping Details**:
|
||||
- Uses Playwright Chromium for headless browser automation
|
||||
- Handles t.co URL redirects and link metadata
|
||||
- Includes screenshot capture for error debugging
|
||||
- Automatic retry with exponential backoff on failures
|
||||
| Paràmetre | Descripció |
|
||||
|---|---|
|
||||
| `--tiktok-handle` | Handle del perfil públic de TikTok (sense `@`) |
|
||||
| `--bsky-handle` | Handle de Bluesky (p. ex. `jo.bsky.social`) |
|
||||
| `--bsky-app-password` | Contrasenya d'aplicació de Bluesky |
|
||||
| `--bsky-base-url` | URL base del PDS (per defecte: `https://bsky.social`) |
|
||||
| `--bsky-langs` | Codi d'idioma de les publicacions (p. ex. `ca`, `es`, `en`) |
|
||||
| `--cookies-path` | Ruta al fitxer JSON de cookies de TikTok (per defecte: `tiktok_cookies.json`) |
|
||||
|
||||
### Workflow Pipelines
|
||||
#### 📋 Comportament del script
|
||||
|
||||
The `workflows/` directory contains YAML pipeline configurations that define:
|
||||
- Data source (RSS feed URL or Twitter handle)
|
||||
- Posting schedule and frequency
|
||||
- Content filtering rules
|
||||
- Target Bluesky account
|
||||
- Scrapes els **darrers 30 vídeos** del perfil públic indicat.
|
||||
- Filtra vídeos de **més de 3 dies d'antiguitat** i de **més de 179 segons** de durada (límit de Bluesky).
|
||||
- Desa l'estat dels vídeos ja publicats a `tiktok2bsky_state.json` per evitar duplicats.
|
||||
- Els logs es guarden a `tiktok2bsky.log`.
|
||||
- Gestiona automàticament els **modals de cookies i banners** de TikTok mitjançant Playwright.
|
||||
- Aplica **stealth mode** (si `playwright-stealth` v1.x és instal·lat) per reduir la detecció de bots.
|
||||
- Límit de mida de vídeo: **20 MB** per a `bsky.social`, **10 MB** per a PDS de tercers.
|
||||
|
||||
Example: `workflows/324.yml` defines the pipeline for the "324" RSS feed.
|
||||
---
|
||||
|
||||
Each workflow typically has a corresponding Jenkins configuration in `jenkins/` for CI/CD integration.
|
||||
## 🤖 Automatització (CI/CD)
|
||||
|
||||
**Running Workflows**:
|
||||
```bash
|
||||
# Manual execution
|
||||
./sync_runner.sh
|
||||
Tots els scripts estan dissenyats per executar-se de forma programada sense intervenció manual.
|
||||
|
||||
# Run specific workflow
|
||||
python rss2bsky.py --feed-url $(grep 'url:' workflows/324.yml | head -1 | cut -d' ' -f2)
|
||||
```
|
||||
### GitHub Actions
|
||||
|
||||
### Media Handling
|
||||
Els fitxers de workflow ja estan inclosos a la carpeta `.github/workflows/`.
|
||||
|
||||
The tool automatically optimizes media for Bluesky's constraints:
|
||||
| Fitxer de workflow | Script | Programació |
|
||||
|---|---|---|
|
||||
| `.github/workflows/twitter2bsky.yml` | `twitter2bsky.py` | Cada 30 minuts |
|
||||
| `.github/workflows/rss2bsky.yml` | `rss2bsky.py` | Cada 30 minuts |
|
||||
| `.github/workflows/tiktok2bsky.yml` | `tiktok2bsky.py` | Cada 30 minuts |
|
||||
|
||||
| Constraint | Value |
|
||||
|-----------|-------|
|
||||
| Image size limit | 950 KB per image |
|
||||
| Image max dimension | 2000px (width or height) |
|
||||
| Max images per post | 4 |
|
||||
| Video size limit | 45 MB |
|
||||
| Video max duration | 3 minutes |
|
||||
| Thumbnail size | 950 KB |
|
||||
| Text length | 300 characters (grapheme clusters) |
|
||||
Recorda afegir els secrets necessaris a **Settings → Secrets and variables → Actions**.
|
||||
|
||||
Images are automatically converted to JPEG with quality optimization (min 40-45 JPEG quality).
|
||||
### Jenkins
|
||||
|
||||
## 💻 Usage
|
||||
També es proporcionen `Jenkinsfiles` per a totes les pipelines. Tots utilitzen:
|
||||
|
||||
### RSS to Bluesky (`rss2bsky.py`)
|
||||
- Trigger cron `H/30 * * * *`
|
||||
- `disableConcurrentBuilds()`
|
||||
- Credencials injectades mitjançant `withCredentials`
|
||||
|
||||
Post entries from RSS feeds to Bluesky:
|
||||
---
|
||||
|
||||
```bash
|
||||
# Simple usage
|
||||
python rss2bsky.py --feed-url https://example.com/feed.xml --bsky-handle @your_handle
|
||||
|
||||
# Limit to recent posts
|
||||
python rss2bsky.py --feed-url https://example.com/feed.xml --limit-age 7
|
||||
|
||||
# Dry run (preview without posting)
|
||||
python rss2bsky.py --feed-url https://example.com/feed.xml --dry-run
|
||||
```
|
||||
|
||||
**Output**: The script logs all actions to `twitter2bsky.log` and maintains state in `twitter2bsky_state.json`.
|
||||
|
||||
### Twitter to Bluesky (`twitter2bsky_daemon.py`)
|
||||
|
||||
Run continuously to sync tweets from specified accounts:
|
||||
|
||||
```bash
|
||||
# Start daemon mode (continuous monitoring)
|
||||
python twitter2bsky_daemon.py
|
||||
|
||||
# Run once and exit
|
||||
python twitter2bsky_daemon.py --once
|
||||
|
||||
# Test mode (no actual posts to Bluesky)
|
||||
python twitter2bsky_daemon.py --test
|
||||
|
||||
# Custom configuration
|
||||
python twitter2bsky_daemon.py --max-retries 5 --timeout 30
|
||||
```
|
||||
|
||||
**Features**:
|
||||
- Automatically fetches new tweets from configured accounts
|
||||
- Handles retweets, quotes, and threaded tweets
|
||||
- Downloads and optimizes media attachments
|
||||
- Resolves shortened t.co links to actual URLs
|
||||
- Prevents duplicate posts with state tracking
|
||||
|
||||
### Running with Sync Runner
|
||||
|
||||
```bash
|
||||
./sync_runner.sh
|
||||
```
|
||||
|
||||
This script can orchestrate multiple sources and is suitable for integration with cron jobs or systemd timers.
|
||||
|
||||
### Daemon Mode Setup (systemd)
|
||||
|
||||
To run `twitter2bsky_daemon.py` continuously as a system service on Linux:
|
||||
|
||||
1. Create service file `/etc/systemd/system/post2bsky.service`:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=post2bsky Twitter to Bluesky Daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=your_user
|
||||
WorkingDirectory=/path/to/post2bsky
|
||||
Environment="PATH=/path/to/post2bsky/venv/bin"
|
||||
ExecStart=/path/to/post2bsky/venv/bin/python twitter2bsky_daemon.py
|
||||
Restart=always
|
||||
RestartSec=60
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
2. Enable and start:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable post2bsky
|
||||
sudo systemctl start post2bsky
|
||||
sudo systemctl status post2bsky
|
||||
```
|
||||
|
||||
3. View logs:
|
||||
```bash
|
||||
tail -f twitter2bsky.log
|
||||
```
|
||||
|
||||
### Cron Job Integration
|
||||
|
||||
Add to crontab with `crontab -e`:
|
||||
|
||||
```bash
|
||||
# Run RSS sync every 30 minutes
|
||||
*/30 * * * * cd /path/to/post2bsky && source venv/bin/activate && python rss2bsky.py --feed-url https://example.com/rss
|
||||
|
||||
# Run all workflows at 9 AM daily
|
||||
0 9 * * * cd /path/to/post2bsky && ./sync_runner.sh
|
||||
```
|
||||
|
||||
## 📦 Dependencies
|
||||
|
||||
All Python dependencies are listed in `requeriments.txt`. Key packages:
|
||||
|
||||
| Package | Purpose |
|
||||
|---------|---------|
|
||||
| `atproto` | Bluesky API client for posting |
|
||||
| `fastfeedparser` | RSS/Atom feed parsing |
|
||||
| `playwright` | Browser automation for Twitter scraping |
|
||||
| `beautifulsoup4` | HTML parsing and content extraction |
|
||||
| `pillow` | Image optimization and processing |
|
||||
| `moviepy` | Video processing and duration detection |
|
||||
| `grapheme` | Unicode grapheme cluster counting for Bluesky's text limits |
|
||||
| `httpx` | HTTP client for URL resolution and media downloads |
|
||||
| `python-dotenv` | Environment variable management |
|
||||
| `arrow` | Date/time handling with timezone support |
|
||||
|
||||
Install all dependencies with:
|
||||
```bash
|
||||
pip install -r requeriments.txt
|
||||
```
|
||||
|
||||
## 📁 Project Structure
|
||||
## 🗂️ Estructura del Projecte
|
||||
|
||||
```
|
||||
post2bsky/
|
||||
├── rss2bsky.py # RSS feed → Bluesky posting script
|
||||
├── twitter2bsky_daemon.py # Twitter → Bluesky daemon (main logic)
|
||||
├── twitter_login.py # Twitter authentication helper
|
||||
├── cookie_login.py # Alternative login method
|
||||
├── sync_runner.sh # Orchestration script for multiple sources
|
||||
├── twitter2bsky_state.json # State file tracking posted content (auto-generated)
|
||||
├── twitter2bsky.log # Application logs (auto-generated)
|
||||
├── requeriments.txt # Python dependencies
|
||||
├── README.md # This file
|
||||
├── LICENSE # GNU GPLv3 license
|
||||
├── jenkins/ # Jenkins CI/CD configurations
|
||||
│ └── [account_name]Tw/ # Config for each account
|
||||
├── workflows/ # YAML pipeline definitions
|
||||
│ ├── 324.yml # Example: RSS feed for "324"
|
||||
│ ├── fcbarcelona.yml # Example: Twitter account for FC Barcelona
|
||||
│ └── ...
|
||||
└── venv/ # Python virtual environment (created during setup)
|
||||
├── twitter2bsky.py # Script de mirroring Twitter → Bluesky
|
||||
├── rss2bsky.py # Script de mirroring RSS → Bluesky
|
||||
├── tiktok2bsky.py # Script de mirroring TikTok → Bluesky
|
||||
├── twitter_login.py # Login headless de Twitter
|
||||
├── tiktok_cookies.json # Cookies de sessió de TikTok (NO fer commit!)
|
||||
├── tiktok2bsky_state.json # Estat dels vídeos publicats (generat automàticament)
|
||||
├── requirements.txt
|
||||
├── .env # Credencials locals (NO fer commit!)
|
||||
├── .gitignore
|
||||
├── .github/
|
||||
│ └── workflows/
|
||||
│ ├── twitter2bsky.yml
|
||||
│ ├── rss2bsky.yml
|
||||
│ └── tiktok2bsky.yml
|
||||
└── Jenkinsfile
|
||||
```
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
---
|
||||
|
||||
### Authentication Issues
|
||||
## 👤 Autor
|
||||
[Guillem Hernández Sola](https://www.linkedin.com/in/guillemhs/)
|
||||
|
||||
**Problem**: `Login failed: Invalid credentials`
|
||||
## 📄 Llicència
|
||||
|
||||
**Solution**:
|
||||
1. Verify credentials in `.env` are correct (no extra spaces)
|
||||
2. Check if Bluesky account requires app password (Settings → App passwords)
|
||||
3. If using 2FA, generate an app-specific password
|
||||
4. For Twitter, ensure account isn't rate-limited or restricted
|
||||
Aquest codi és alliberat al domini públic per [Guillem Hernández Sola](https://www.linkedin.com/in/guillemhs/) sota llicència Creative Commons Reconeixement-NoComercial 4.0 Internacional (CC BY-NC 4.0).
|
||||
|
||||
### Twitter Scraping Issues
|
||||
El README ha estat redactat per a aquest repositori i segueix la mateixa llicència.
|
||||
|
||||
**Problem**: `Playwright browser failed` or screenshot errors
|
||||
Per a més informació o contacte, consulta el perfil de l’autor al repositori.
|
||||
|
||||
**Solution**:
|
||||
1. Ensure Chromium is properly installed: `playwright install chromium`
|
||||
2. Check available disk space (Playwright requires ~500MB)
|
||||
3. Run script with `--debug` flag for detailed output
|
||||
4. Check browser error screenshots in `screenshot_*.png` files
|
||||
|
||||
**Problem**: `No tweets found` or `Tweets already posted`
|
||||
|
||||
**Solution**:
|
||||
1. Verify Twitter account handle is correct in configuration
|
||||
2. Check `twitter2bsky_state.json` for deduplication data
|
||||
3. Delete state file to reset tracking (careful: may cause re-posting)
|
||||
4. Review `twitter2bsky.log` for detailed debugging
|
||||
|
||||
### Media Processing Issues
|
||||
|
||||
**Problem**: `Image upload failed` or `Video too large`
|
||||
|
||||
**Solution**:
|
||||
1. Images are auto-optimized, but source should be <100MB
|
||||
2. Videos must be <45MB and <3 minutes
|
||||
3. Check available disk space for temporary files
|
||||
4. Enable debug logging in the script for detailed info
|
||||
|
||||
### Performance Issues
|
||||
|
||||
**Problem**: Script runs slowly or times out
|
||||
|
||||
**Solution**:
|
||||
1. Check network connectivity
|
||||
2. Reduce `SCRAPE_TWEET_LIMIT` in `twitter2bsky_daemon.py` (default: 30)
|
||||
3. Increase timeout constants if on slow connection
|
||||
4. Run with `--once` instead of daemon mode to diagnose
|
||||
5. Check system resources (CPU, memory, disk I/O)
|
||||
|
||||
### Log Analysis
|
||||
|
||||
Check `twitter2bsky.log` for detailed debugging:
|
||||
|
||||
```bash
|
||||
# View recent errors
|
||||
grep ERROR twitter2bsky.log | tail -20
|
||||
|
||||
# View all warnings
|
||||
grep WARNING twitter2bsky.log | tail -20
|
||||
|
||||
# Watch logs in real-time
|
||||
tail -f twitter2bsky.log
|
||||
|
||||
# Count posts by status
|
||||
grep -c "✅ Posted to Bluesky" twitter2bsky.log
|
||||
```
|
||||
|
||||
## 🐛 Debugging
|
||||
|
||||
Enable debug logging by modifying the logging level in the script:
|
||||
|
||||
```python
|
||||
# In twitter2bsky_daemon.py, change:
|
||||
level=logging.INFO,
|
||||
# To:
|
||||
level=logging.DEBUG,
|
||||
```
|
||||
|
||||
Run with verbose output:
|
||||
```bash
|
||||
python twitter2bsky_daemon.py 2>&1 | tee debug.log
|
||||
```
|
||||
|
||||
Error screenshots are automatically saved as `screenshot_YYYYMMDD_HHMMSS.png` for investigation.
|
||||
|
||||
## 📄 License
|
||||
|
||||
This project is licensed under the GNU General Public License v3.0. See [LICENSE](LICENSE) for details.
|
||||
|
||||
**Summary**: You are free to use, modify, and distribute this software, but any modifications must also be open-source under GPLv3.
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Contributions are welcome! To contribute:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Make your changes with clear commit messages
|
||||
4. Push to your fork (`git push origin feature/amazing-feature`)
|
||||
5. Open a Pull Request with a description of your changes
|
||||
|
||||
**Before submitting**:
|
||||
- Test your changes thoroughly
|
||||
- Ensure code follows existing style conventions
|
||||
- Add comments for complex logic
|
||||
- Update README if adding new features
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
**Q: Can I use this on Windows?**
|
||||
A: Yes, but ensure you have Python 3.9+ and Chromium/Playwright support. Use `venv\Scripts\activate` instead of `source venv/bin/activate`.
|
||||
|
||||
**Q: How do I avoid posting duplicates?**
|
||||
A: The state file (`twitter2bsky_state.json`) tracks all posted content. It's automatically maintained; just don't delete it between runs.
|
||||
|
||||
**Q: Can I post to multiple Bluesky accounts?**
|
||||
A: Currently, the tool posts to one account per instance. Run multiple instances with different `.env` configurations to handle multiple accounts.
|
||||
|
||||
**Q: What happens if posting fails?**
|
||||
A: The script has automatic retry logic with exponential backoff. Failed posts are logged but the state file is NOT updated, so retries on next run.
|
||||
|
||||
**Q: Is my content optimized for Bluesky?**
|
||||
A: Yes. The tool automatically:
|
||||
- Truncates text to 300 characters (grapheme-aware)
|
||||
- Optimizes images to Bluesky specs
|
||||
- Handles video conversion and compression
|
||||
- Resolves shortened URLs
|
||||
|
||||
**Q: How do I run this on a server?**
|
||||
A: Use the systemd service example in the [Usage](#-usage) section, or set up a cron job.
|
||||
|
||||
**Q: Can I schedule posts?**
|
||||
A: Not directly through this tool. Instead, use cron/scheduler to run the script at desired times.
|
||||
|
||||
## 🎯 Use Cases
|
||||
|
||||
- **Content Creators**: Automatically repost your RSS feeds to Bluesky for wider reach
|
||||
- **News Aggregation**: Create Bluesky bots that share news from multiple RSS sources
|
||||
- **Account Management**: Keep social media accounts synchronized across platforms
|
||||
- **Content Distribution**: Distribute content from Twitter to Bluesky without manual copying
|
||||
|
||||
## 🔐 Security Notes
|
||||
|
||||
- **Never commit `.env`**: Credentials are automatically gitignored
|
||||
- **Secure your state file**: `twitter2bsky_state.json` may contain URLs; protect it like credentials
|
||||
- **Use app passwords**: For Bluesky, use app-specific passwords instead of main account password
|
||||
- **Monitor logs**: Regularly review `twitter2bsky.log` for unauthorized access attempts
|
||||
|
||||
## 📞 Support
|
||||
|
||||
- **Issues**: Open an issue on GitHub with detailed reproduction steps
|
||||
- **Documentation**: Check this README and inline code comments
|
||||
- **Logs**: Attach relevant log excerpts when reporting issues
|
||||
- **Testing**: Test with `--test` flag before running in production
|
||||
|
||||
## 📝 Changelog
|
||||
|
||||
See Git commit history for detailed changes. Notable versions:
|
||||
|
||||
- **v2.0**: Added Twitter scraping with media support, daemon mode
|
||||
- **v1.5**: Improved RSS parsing and media handling
|
||||
- **v1.0**: Initial release with basic RSS→Bluesky posting
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This tool is for personal use and automation. Ensure compliance with the terms of service of Bluesky, Twitter, and any RSS sources you use. Respect rate limits and avoid spamming.
|
||||
Si necessiteu més informació, podeu contactar amb [Guillem Hernández Sola](https://www.linkedin.com/in/guillemhs/).
|
||||
|
||||
## Contacte
|
||||
Per dubtes o col·laboració: obre una issue al repositori o contacta amb en [Guillem Hernández Sola](https://www.linkedin.com/in/guillemhs/)
|
||||
Reference in New Issue
Block a user