一键导入
clipboard-sync-cross-device
Sync clipboard content across multiple devices (PC, Android, iOS) via cloud with encryption, history, and push notifications
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Sync clipboard content across multiple devices (PC, Android, iOS) via cloud with encryption, history, and push notifications
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Orchestrate psychology clinic workflows with AI-powered scheduling, WhatsApp automation, AFIP billing, and video consultations for Argentine practitioners
SaaS platform for psychology clinics with intelligent scheduling, WhatsApp automation, AFIP billing, videollamadas, and Claude AI integration
Build and customize the Sesión mental health practice management platform with appointment scheduling, WhatsApp automation, AFIP billing, and Claude AI integration
Orchestrate psychology clinic operations with AI-powered scheduling, WhatsApp automation, AFIP billing, and secure video consultations for Argentine mental health practitioners
Connect AI agents to a running Tabbit browser instance via Chrome DevTools Protocol (CDP) and control it through agent-browser
AI-powered mental health practice management platform for Argentina with WhatsApp automation, AFIP-compliant invoicing, and video consultations
| name | clipboard-sync-cross-device |
| description | Sync clipboard content across multiple devices (PC, Android, iOS) via cloud with encryption, history, and push notifications |
| triggers | ["sync clipboard across devices","set up clipboard sharing between computer and phone","configure cross-device clipboard sync","implement clipboard history with cloud storage","sync text and files via clipboard","enable encrypted clipboard sync","build clipboard synchronization tool","create multi-device clipboard app"] |
Skill by ara.so — Devtools Skills collection.
Clipboard Sync is a Python-based tool for synchronizing clipboard content across multiple devices (Windows, Android, iOS) using cloud storage (Google Drive/Dropbox). It provides end-to-end encryption, clipboard history, push notifications, and selective sync capabilities.
# Clone the repository
git clone https://github.com/mariusboiti/Clipboard_Sync.git
cd Clipboard_Sync
# Install dependencies
pip install -r requirements.txt
# Or install specific dependencies
pip install pyperclip watchdog pycryptodome google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client dropbox pyfcm pillow
import pyperclip
import time
import hashlib
class ClipboardMonitor:
def __init__(self, callback=None):
self.last_content = ""
self.callback = callback
def start_monitoring(self):
"""Monitor clipboard for changes"""
while True:
try:
current_content = pyperclip.paste()
if current_content != self.last_content:
self.last_content = current_content
if self.callback:
self.callback(current_content)
except Exception as e:
print(f"Error monitoring clipboard: {e}")
time.sleep(1)
# Usage
def on_clipboard_change(content):
print(f"Clipboard changed: {content[:50]}...")
monitor = ClipboardMonitor(callback=on_clipboard_change)
monitor.start_monitoring()
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Protocol.KDF import PBKDF2
import base64
import os
class ClipboardEncryption:
def __init__(self, password=None):
self.password = password or os.getenv('CLIPBOARD_SYNC_PASSWORD', 'default_password')
self.salt = get_random_bytes(16)
def _get_key(self, salt):
"""Derive encryption key from password"""
return PBKDF2(self.password, salt, dkLen=32)
def encrypt(self, data):
"""Encrypt clipboard data"""
if isinstance(data, str):
data = data.encode('utf-8')
salt = get_random_bytes(16)
key = self._get_key(salt)
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(data)
# Combine salt, nonce, tag, and ciphertext
encrypted_data = salt + cipher.nonce + tag + ciphertext
return base64.b64encode(encrypted_data).decode('utf-8')
def decrypt(self, encrypted_data):
"""Decrypt clipboard data"""
encrypted_data = base64.b64decode(encrypted_data)
# Extract components
salt = encrypted_data[:16]
nonce = encrypted_data[16:32]
tag = encrypted_data[32:48]
ciphertext = encrypted_data[48:]
key = self._get_key(salt)
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
data = cipher.decrypt_and_verify(ciphertext, tag)
return data.decode('utf-8')
# Usage
encryptor = ClipboardEncryption()
encrypted = encryptor.encrypt("Sensitive clipboard content")
decrypted = encryptor.decrypt(encrypted)
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
import json
import io
import os
class GoogleDriveSync:
SCOPES = ['https://www.googleapis.com/auth/drive.file']
def __init__(self, credentials_path=None):
self.credentials_path = credentials_path or os.getenv('GOOGLE_CREDENTIALS_PATH')
self.service = None
self.authenticate()
def authenticate(self):
"""Authenticate with Google Drive"""
creds = None
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', self.SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
self.credentials_path, self.SCOPES)
creds = flow.run_local_server(port=0)
with open('token.json', 'w') as token:
token.write(creds.to_json())
self.service = build('drive', 'v3', credentials=creds)
def upload_clipboard(self, content, filename='clipboard_data.json'):
"""Upload clipboard content to Drive"""
data = {
'content': content,
'timestamp': time.time()
}
file_metadata = {'name': filename}
media = MediaFileUpload(
io.BytesIO(json.dumps(data).encode()),
mimetype='application/json',
resumable=True
)
# Check if file exists
results = self.service.files().list(
q=f"name='{filename}'",
spaces='drive',
fields='files(id, name)'
).execute()
files = results.get('files', [])
if files:
# Update existing file
file_id = files[0]['id']
self.service.files().update(
fileId=file_id,
media_body=media
).execute()
else:
# Create new file
self.service.files().create(
body=file_metadata,
media_body=media,
fields='id'
).execute()
def download_clipboard(self, filename='clipboard_data.json'):
"""Download clipboard content from Drive"""
results = self.service.files().list(
q=f"name='{filename}'",
spaces='drive',
fields='files(id, name)'
).execute()
files = results.get('files', [])
if not files:
return None
file_id = files[0]['id']
request = self.service.files().get_media(fileId=file_id)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while not done:
status, done = downloader.next_chunk()
fh.seek(0)
data = json.loads(fh.read().decode())
return data['content']
# Usage
sync = GoogleDriveSync()
sync.upload_clipboard("My clipboard content")
content = sync.download_clipboard()
import json
import sqlite3
from datetime import datetime
class ClipboardHistory:
def __init__(self, db_path='clipboard_history.db'):
self.db_path = db_path
self.init_db()
def init_db(self):
"""Initialize database"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS clipboard_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL,
content_type TEXT DEFAULT 'text',
timestamp REAL NOT NULL,
device_id TEXT,
synced INTEGER DEFAULT 0
)
''')
conn.commit()
conn.close()
def add_entry(self, content, content_type='text', device_id=None):
"""Add clipboard entry to history"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
INSERT INTO clipboard_history (content, content_type, timestamp, device_id)
VALUES (?, ?, ?, ?)
''', (content, content_type, datetime.now().timestamp(), device_id))
conn.commit()
entry_id = cursor.lastrowid
conn.close()
return entry_id
def get_history(self, limit=50):
"""Retrieve clipboard history"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
SELECT id, content, content_type, timestamp, device_id, synced
FROM clipboard_history
ORDER BY timestamp DESC
LIMIT ?
''', (limit,))
entries = cursor.fetchall()
conn.close()
return [
{
'id': e[0],
'content': e[1],
'content_type': e[2],
'timestamp': e[3],
'device_id': e[4],
'synced': bool(e[5])
}
for e in entries
]
def mark_synced(self, entry_id):
"""Mark entry as synced"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
UPDATE clipboard_history SET synced = 1 WHERE id = ?
''', (entry_id,))
conn.commit()
conn.close()
# Usage
history = ClipboardHistory()
entry_id = history.add_entry("My clipboard text", device_id="PC-001")
recent = history.get_history(limit=10)
import threading
import time
import pyperclip
class ClipboardSyncApp:
def __init__(self):
self.encryptor = ClipboardEncryption(
password=os.getenv('CLIPBOARD_SYNC_PASSWORD')
)
self.cloud_sync = GoogleDriveSync()
self.history = ClipboardHistory()
self.monitor = ClipboardMonitor(callback=self.on_clipboard_change)
self.running = False
self.device_id = os.getenv('DEVICE_ID', 'default-device')
def on_clipboard_change(self, content):
"""Handle clipboard changes"""
try:
# Add to history
entry_id = self.history.add_entry(content, device_id=self.device_id)
# Encrypt content
encrypted = self.encryptor.encrypt(content)
# Upload to cloud
self.cloud_sync.upload_clipboard(encrypted)
# Mark as synced
self.history.mark_synced(entry_id)
print(f"Synced clipboard content (ID: {entry_id})")
except Exception as e:
print(f"Error syncing clipboard: {e}")
def sync_from_cloud(self):
"""Periodically sync from cloud"""
while self.running:
try:
encrypted_content = self.cloud_sync.download_clipboard()
if encrypted_content:
content = self.encryptor.decrypt(encrypted_content)
current = pyperclip.paste()
if content != current:
pyperclip.copy(content)
print(f"Updated clipboard from cloud")
except Exception as e:
print(f"Error syncing from cloud: {e}")
time.sleep(5) # Check every 5 seconds
def start(self):
"""Start clipboard sync"""
self.running = True
# Start cloud sync thread
sync_thread = threading.Thread(target=self.sync_from_cloud, daemon=True)
sync_thread.start()
# Start monitoring
print("Clipboard Sync started...")
self.monitor.start_monitoring()
def stop(self):
"""Stop clipboard sync"""
self.running = False
# Usage
if __name__ == "__main__":
app = ClipboardSyncApp()
try:
app.start()
except KeyboardInterrupt:
app.stop()
print("\nClipboard Sync stopped")
# Required
export CLIPBOARD_SYNC_PASSWORD="your-encryption-password"
export GOOGLE_CREDENTIALS_PATH="/path/to/credentials.json"
export DEVICE_ID="my-laptop"
# Optional
export SYNC_INTERVAL="5" # seconds
export HISTORY_LIMIT="100"
export DROPBOX_ACCESS_TOKEN="your-token"
{
"sync": {
"provider": "google_drive",
"interval": 5,
"auto_start": true
},
"encryption": {
"enabled": true,
"algorithm": "AES-256-GCM"
},
"history": {
"enabled": true,
"max_entries": 1000,
"db_path": "clipboard_history.db"
},
"selective_sync": {
"enabled": true,
"sync_images": true,
"sync_files": false,
"max_file_size_mb": 10
},
"notifications": {
"enabled": true,
"fcm_server_key": "${FCM_SERVER_KEY}"
}
}
class SelectiveSync:
def __init__(self, config):
self.sync_images = config.get('sync_images', True)
self.sync_files = config.get('sync_files', False)
self.max_file_size = config.get('max_file_size_mb', 10) * 1024 * 1024
def should_sync(self, content, content_type='text'):
"""Determine if content should be synced"""
if content_type == 'text':
return True
elif content_type == 'image':
return self.sync_images
elif content_type == 'file':
return self.sync_files
return False
from pyfcm import FCMNotification
class ClipboardNotifications:
def __init__(self):
self.push_service = FCMNotification(
api_key=os.getenv('FCM_SERVER_KEY')
)
def send_notification(self, device_tokens, content_preview):
"""Send push notification to devices"""
message_title = "Clipboard Updated"
message_body = f"New content: {content_preview[:50]}..."
result = self.push_service.notify_multiple_devices(
registration_ids=device_tokens,
message_title=message_title,
message_body=message_body,
data_message={'action': 'clipboard_sync'}
)
return result
Clipboard not syncing:
High CPU usage:
Authentication errors:
token.json and restartGOOGLE_CREDENTIALS_PATH points to valid credentialsDecryption failures:
CLIPBOARD_SYNC_PASSWORD is identical on all devicesimport logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
app = ClipboardSyncApp()
app.start()
ClipboardMonitor.start_monitoring() - Begin monitoring clipboardClipboardEncryption.encrypt(data) - Encrypt clipboard contentClipboardEncryption.decrypt(data) - Decrypt clipboard contentGoogleDriveSync.upload_clipboard(content) - Upload to Google DriveGoogleDriveSync.download_clipboard() - Download from Google DriveClipboardHistory.add_entry(content) - Add to history databaseClipboardHistory.get_history(limit) - Retrieve history entries