import emoji list to Rabbit
by
Nikola
07/21 [2024/07/21 07:39:06]
リレーからkind10030,kind30030イベントを取得してRabbitにカスタム絵文字リストをインポートする
@@ -6,11 +6,15 @@
* @require
*/
-(() => {
- const relayUrl = 'wss://relay-jp.nostr.wirednet.jp';
+(async () => {
+ if (typeof window === 'undefined') {
+ await import('websocket-polyfill');
+ }
+
+ const relayUrl = 'wss://relay-jp.nostr.wirednet.jp';//リレーは決め打ちです。すみません。
const getPubkey = async () => {
- let pubkey;
+ let pubkey;//Node.jsでデバッグする際はここに初期値を入れてください。無ければ最新の誰かのイベントで代用します。
const nostr = globalThis.window?.nostr;
if (nostr?.getPublicKey) {
try {
@@ -31,7 +35,7 @@
const req = [
'REQ',
subscription_id,
- { 'kinds': [10030], 'authors': [pubkey] }
+ pubkey ? { 'kinds': [10030], 'authors': [pubkey] } : { 'kinds': [10030], 'limit': 1 }
];
ws.send(JSON.stringify(req));
};
@@ -43,6 +47,7 @@
break;
case 'EOSE':
ws.send(JSON.stringify(['CLOSE', subscription_id]));
+ ws.close();
resolve(res);
break;
default:
@@ -93,6 +98,7 @@
break;
case 'EOSE':
ws.send(JSON.stringify(['CLOSE', subscription_id]));
+ ws.close();
resolve();
break;
default:
@@ -115,6 +121,10 @@
console.warn(error);
return;
}
+ if (globalThis.window && !pubkey) {
+ console.warn('pubkey is empty.');
+ return;
+ }
let ev10030;
try {
ev10030 = await getEvent10030(pubkey);
@@ -134,6 +144,10 @@
localStorage['RabbitConfig'] = JSON.stringify(config);
alert('Complete. Please reload by yourself.');
}
+ else {
+ console.log(emojiMap);
+ console.log('Complete.');
+ }
};
main();
/*
* @title import emoji list to Rabbit
* @description リレーからkind10030,kind30030イベントを取得してRabbitにカスタム絵文字リストをインポートする
* @include https://rabbit.syusui.net/*
* @license CC0 1.0
* @require
*/
(async () => {
if (typeof window === 'undefined') {
await import('websocket-polyfill');
}
const 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 getEvent10030 = async (pubkey) => {
return new Promise((resolve) => {
const ws = new WebSocket(relayUrl);
const subscription_id = 'getemojilistinrabbit';
let res;
ws.onopen = () => {
const req = [
'REQ',
subscription_id,
pubkey ? { 'kinds': [10030], 'authors': [pubkey] } : { 'kinds': [10030], 'limit': 1 }
];
ws.send(JSON.stringify(req));
};
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
switch ( msg[0] ) {
case 'EVENT':
res = 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 getEmojiList = async (ev10030) => {
const atags = ev10030.tags.filter(tag => tag.length >= 2 && tag[0] === 'a').map(tag => tag[1]);
if (atags.length === 0) {
return [];
}
const filters = [];
for (const atag of atags) {
const ary = atag.split(':');
filters.push({ kinds: [parseInt(ary[0])], authors: [ary[1]], '#d': [ary[2]] });
}
let emojiMap = new Map();
for (const filter of filters) {
await getEvent30030(filter);
}
return emojiMap;
async function getEvent30030(filter) {
return new Promise((resolve) => {
const ws = new WebSocket(relayUrl);
const subscription_id = 'getemojiinrabbit';
ws.onopen = () => {
const req = [
'REQ',
subscription_id,
filter
];
ws.send(JSON.stringify(req));
};
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
switch ( msg[0] ) {
case 'EVENT':
for (const tag of msg[2].tags.filter(tag => tag.length >= 2 && tag[0] === 'emoji')) {
emojiMap.set(tag[1], tag[2]);
}
break;
case 'EOSE':
ws.send(JSON.stringify(['CLOSE', subscription_id]));
ws.close();
resolve();
break;
default:
console.log(msg);
break;
}
};
ws.onerror = () => {
console.error('failed to connect');
}
});
};
};
const main = async () => {
let pubkey;
try {
pubkey = await getPubkey();
} catch (error) {
console.warn(error);
return;
}
if (globalThis.window && !pubkey) {
console.warn('pubkey is empty.');
return;
}
let ev10030;
try {
ev10030 = await getEvent10030(pubkey);
} catch (error) {
console.warn(error);
return;
}
if (!ev10030) {
return;
}
const emojiMap = await getEmojiList(ev10030);
if (globalThis.window) {
const config = JSON.parse(localStorage['RabbitConfig']);
for (const [key, value] of emojiMap) {
config.customEmojis[key] = { shortcode: key, url: value };
}
localStorage['RabbitConfig'] = JSON.stringify(config);
alert('Complete. Please reload by yourself.');
}
else {
console.log(emojiMap);
console.log('Complete.');
}
};
main();
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。