import relay set to Rabbit

  • /*
     * @title import relay set to Rabbit
     * @description リレーからkind30002イベントを取得してRabbitにリレーセットをインポートする
     * @include https://rabbit.syusui.net/*
     * @license CC0 1.0
     * @require
     */
    
    (async () => {
    	let relayUrl = 'wss://relay-jp.nostr.wirednet.jp';
    
    	const getPubkey = async () => {
    		let pubkey; //Node.jsでデバッグする際はここに初期値を入れてください。無ければ最新の誰かのイベントで代用します。
    		const nostr = globalThis.window?.nostr;
    		if (nostr?.getPublicKey) {
    			try {
    				pubkey = await nostr.getPublicKey();
    			} catch (error) {
    				console.warn(error);
    			}
    		}
    		return pubkey;
    	};
    
    	const getEvent30002 = async (pubkey) => {
    		return new Promise((resolve) => {
    			const ws = new WebSocket(relayUrl);
    			const subscription_id = 'getrelaysetinrabbit';
    			let res = [];
    			ws.onopen = () => {
    				const req = [
    					'REQ',
    					subscription_id,
    					pubkey ? { kinds: [30002], authors: [pubkey] } : { kinds: [30002], limit: 1 }
    				];
    				ws.send(JSON.stringify(req));
    			};
    			ws.onmessage = (e) => {
    				const msg = JSON.parse(e.data);
    				switch (msg[0]) {
    					case 'EVENT':
    						res.push(msg[2]);
    						break;
    					case 'EOSE':
    						ws.send(JSON.stringify(['CLOSE', subscription_id]));
    						ws.close();
    						resolve(res);
    						break;
    					default:
    						console.log(msg);
    						break;
    				}
    			};
    			ws.onerror = () => {
    				console.error('failed to connect');
    			};
    		});
    	};
    
    	const main = async () => {
    		relayUrl = window.prompt('Input relay URL.', relayUrl);
    		if (!URL.canParse(relayUrl)) {
    			console.warn(`Invalid URL: ${relayUrl}`);
    			return;
    		}
    		let pubkey;
    		try {
    			pubkey = await getPubkey();
    		} catch (error) {
    			console.warn(error);
    			return;
    		}
    		if (globalThis.window && !pubkey) {
    			console.warn('pubkey is empty.');
    			return;
    		}
    		let ev30002s;
    		try {
    			ev30002s = await getEvent30002(pubkey);
    		} catch (error) {
    			console.warn(error);
    			return;
    		}
    		let relays;
    		for (const ev of ev30002s) {
    			const d = ev.tags.find((tag) => tag.length >= 2 && tag[0] === 'd')?.at(1) ?? '';
    			const rs = ev.tags
    				.filter((tag) => tag.length >= 2 && tag[0] === 'relay' && URL.canParse(tag[1]))
    				.map((tag) => tag[1]);
    			if (window.confirm(`Do you want to use "${d}" ?\n\n` + rs.join('\n'))) {
    				relays = rs;
    				break;
    			}
    		}
    		if (relays === undefined) {
    			return;
    		}
    		if (globalThis.window) {
    			const config = JSON.parse(localStorage['RabbitConfig']);
    			config.relayUrls = Array.from(new Set([...config.relayUrls, ...relays]));
    			localStorage['RabbitConfig'] = JSON.stringify(config);
    			alert('Complete. Please reload by yourself.');
    		} else {
    			console.log({ relays });
    			console.log('Complete.');
    		}
    	};
    
    	main();
    })();
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2025/02/28 08:50:17 - 02/28