Process npubs one by one

This commit is contained in:
minimo-io 2024-04-27 15:33:29 -03:00
parent a613e622d8
commit da657383aa
7 changed files with 124 additions and 147 deletions

View File

@ -5,8 +5,7 @@ Let promote some reciprocity here! 😹
## ToDo
- Actually load builds at minimo.io/app/ or something alike.
- Ask community for help about the bug (see below) so I can keep understanding the protocol and the library.
- Create groups to checks to fire simultaneously instad of one by one (to remember: fireing all the `fetchProfile` at once for a given npub resulted in a permanent halt of the process -mainly for big users). Maybe using https://lodash.com/docs `_.chunk(array, [size=1])`
- Polish the proof-of-concept code, making it TS code and remove `// @ts-nocheck`!
- Create interfaces or new types instead of loose variables
- Save followbackers and not followbackers in lists to see details.
@ -15,10 +14,6 @@ Let promote some reciprocity here! 😹
- Show the relay list to be used
- Upload a localStorage list of relays
- ~~Actually load builds at minimo.io/app/ or something alike.~~
- ~~Configure Vite for the miniapp to be loaded in the article's url as base.~~
- ~~Remove SvelteKit (just Vite + Svelte).~~
## BUG
- **When user follows lots of people, progress freezes:**<br>
[NDK](https://github.com/nostr-dev-kit/ndk) keeps trying to re-connect to relays, and progress slows down or halts completly. Maybe slow requests down? Are they blocking the requests because they are too many too fast?

View File

@ -1,7 +1,7 @@
{
"name": "nostr-followback",
"private": true,
"version": "0.0.0",
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite",

View File

@ -1,23 +1,23 @@
<script lang="ts">
// @ts-nocheck
// Import the package
import NDK from "@nostr-dev-kit/ndk";
import { fetchUserProfile } from "./lib/fetchs";
import NDK, { type NDKUserProfile } from "@nostr-dev-kit/ndk";
import type { userFollowData } from "./lib/types";
import { relays } from "./lib/data/relays";
// let npubToQuery = "npub1wujhdsytm3w6g0mpsqh8v7ezx83jcm64dlkwuqgm5v8lv0pds55ssudkw0";
let npubToQuery = "";
let querying = false;
let userName = "";
let userThumb = "";
let followsCount = 0;
let npubToQuery = "npub1wujhdsytm3w6g0mpsqh8v7ezx83jcm64dlkwuqgm5v8lv0pds55ssudkw0";
let querying: "completed" | "processing" | "uninitiated" = "uninitiated";
let userProfile: NDKUserProfile | null;
let followsCount = 0;
let followBackCount = 0;
let notFollowBackCount = 0;
let unknownFollowBack = 0;
let totalCountOfContactsChecked = 0;
$: progress = ((totalCountOfContactsChecked / followsCount) * 100).toFixed() | 0;
$: notFollowBackPercentage = ((notFollowersBack.length / originalFollow.length) * 100) | 0;
let originalFollow = [];
let notFollowersBack = [];
@ -27,26 +27,28 @@
const ndk = new NDK({
explicitRelayUrls: relays,
});
await ndk.connect();
await ndk.connect(6000);
querying = "processing";
const user = await fetchUserProfile(npubToQuery, ndk);
// create user instance
const user = ndk.getUser({ npub: npubToQuery });
// query for user profile
userProfile = await user.fetchProfile();
userName = user.profile.name;
userThumb = user.profile.image;
if (userName) {
if (userProfile) {
// console.log(user.profile);
const follows = await user.follows();
const follows = await user.follows({ groupable: false }, false);
// query for a set of user followers
followsCount = follows.size;
let lastFollowerBack;
let i = 0;
follows.forEach(async (follower) => {
//for (const follower of follows) {
// await new Promise((resolve) => setTimeout(resolve, 0));
for await (const follower of follows) {
const followerFollowList = await follower.follows();
try {
originalFollow.push({ npub: follower.npub, followsBack: "-" }); // add to follower list
originalFollow = originalFollow;
@ -81,28 +83,36 @@
totalCountOfContactsChecked++;
}
i++;
});
// follows.forEach(async (follower) => {
// });
}
} catch (error) {
console.error("Error fetching data:", error);
console.log(follower);
console.error(`Error fetching npub:`, error);
}
}
//checkFollowBacks();
}
querying = "completed";
} catch (error) {
console.error(`Error fetching data (${npubToQuery}):`, error);
}
}
function ItemCount(i: number): string {
let ret = i.toString();
if (i < 10) ret = `0${i}`;
return ret;
}
</script>
<form class="npub-form">
<input disabled={querying && progress < 100} type="text" placeholder="An npub to check" bind:value={npubToQuery} />
<input
disabled={querying == "processing" && progress < 100}
type="text"
placeholder="npub to check"
bind:value={npubToQuery}
/>
<input
type="button"
on:click={async () => {
querying = true;
userName = "";
userThumb = "";
userProfile = null;
originalFollow = [];
notFollowersBack = [];
followBackCount = 0;
@ -116,43 +126,35 @@
/>
</form>
<!-- {#if !querying}
{npubToQuery}
{/if} -->
{#if userThumb}
{#if userProfile}
<div class="user-box">
<img src={userThumb} width="50" style="border-radius:100%;" alt="user-thumb" />
<img src={userProfile.image} width="50" style="border-radius:100%;" alt="user-thumb" />
User:
<a href="https://primal.net/p/{npubToQuery}">{userName}</a>
<a href="https://primal.net/p/{npubToQuery}">{userProfile.displayName}</a>
|  Follows: {followsCount}
<br />
Unknown: {unknownFollowBack} | Follow_Back: {followBackCount} |
Unknown: {unknownFollowBack} - Follow_Back: {followBackCount} -
<strong>👉 Not_Follow_Back</strong>
:
<!-- <span title="Actually Counted">{notFollowBackCount}</span>
/ -->
<span title="Actualy counted">{notFollowersBack.length}</span>
<br />
{#if progress < 100}
<p>
Progress =
<strong>{progress}%</strong>
Progress = <strong>{progress}%</strong>
- {totalCountOfContactsChecked} of {followsCount}
<!-- - {totalCountOfContactsChecked} of {followBackCount +
notFollowBackCount +
unknownFollowBack} -->
</p>
{:else}
<p><strong>Completed!</strong></p>
<p><strong>✅ Completed!</strong></p>
{/if}
<hr />
<br />
Results ({originalFollow.length})
<strong>Not followers</strong>
: {notFollowersBack.length} of
{originalFollow.length} ({notFollowBackPercentage}%)
<ul>
{#each originalFollow as item, i}
<li>
#{i + 1} - {@html item.followBack == "0" ? "<span>🔴</span>" : "<span>🟢</span>"}
#{ItemCount(i + 1)} - {@html item.followBack == "0" ? "<span>🔴</span>" : "<span>🟢</span>"}
<a target="_blank noreferrer noopener" href="https://primal.net/p/{item.npub}">
{item.npub}
</a>
@ -160,22 +162,8 @@
</li>
{/each}
</ul>
<!-- <br />
<strong>They don't follow you ({notFollowersBack.length}):</strong>
<br />
<ul>
{#each notFollowersBack as item, i (item)}
<li>
#{i + 1} - <a href="https://nostr.band/{item}" target="_blank noreferrer noopener">Nostr.Band</a>
/ <a href="https://primal.net/p/{item}" target="_blank noreferrer noopener">Primal</a>
:
{item}
</li>
{/each}
</ul> -->
</div>
{:else if !querying}
{:else if querying == "uninitiated"}
<!-- <p>Let's find out who does not follow you back in Nostr!</p> -->
{:else}
<div class="loader">Loading data...</div>

View File

@ -9,11 +9,11 @@ export const relays = [
"wss://nostr.mom",
"wss://nostrelay.yeghro.site",
"wss://relay.damus.io",
"wss://relay.nostr.bg",
// "wss://relay.nostr.bg",
"wss://relay.snort.social",
"wss://relay.primal.net",
"wss://nostr.bitcoiner.social",
"wss://nostr.mutinywallet.com",
"wss://relay.current.fyi",
"wss://brb.io",
// "wss://brb.io",
];

View File

@ -1,9 +0,0 @@
export async function fetchUserProfile(npub, ndk) {
const user = ndk.getUser({ npub });
await user.fetchProfile();
return user;
}
export async function fetchNotes(hexkey, ndk) {
const kind1filter = { kinds: [3], authors: [hexkey] };
return ndk.fetchEvent(kind1filter);
}

View File

@ -0,0 +1,3 @@
export type userFollowData = {
followsCount: number;
};