{"id":8635,"date":"2026-08-24T07:27:04","date_gmt":"2026-08-23T22:27:04","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=8635"},"modified":"2026-08-24T11:37:39","modified_gmt":"2026-08-24T02:37:39","slug":"nextjs-sns-server-11","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/24\/nextjs-sns-server-11\/","title":{"rendered":"[nextjs]SNS Server-11(myapp21)"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb @user1@aloy-horizon.duckdns.org\uc758 follows\uc5d0 \uac19\uc740 \uc0ac\uc6a9\uc790\uac00 \ub450\ubc88 \uc785\ub825\ub418\ub294 \ubb38\uc81c\ub97c \uc218\uc815\ud569\ub2c8\ub2e4.<br>Fixes an issue where the same user is entered twice in the &#8216;follows&#8217; list for @user1@aloy-horizon.duckdns.org.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb follow\uc694\uccad\uc2dc following\uacfc followers\ud14c\uc774\ube14\uc5d0 \uae30\uc874 \uc0ac\uc6a9\uc790 \uc788\uc73c\uba74 \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<br>When a follow request is made, the request is not sent if the user already exists in the &#8216;following&#8217; or &#8216;followers&#8217; tables.<\/p>\n\n\n\n<p>\ud83d\udcc1 \uc804\uccb4 \ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \/ Overall Project Structure<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>myapp21\/  \n\u251c\u2500\u2500 app\/  (Next.js App Router)\n\u2502   \u251c\u2500\u2500 .well-known\/webfinger\/route.ts  -&gt; webfinger\n\u2502   \u251c\u2500\u2500 api\/posts\/route.ts     -&gt; Writing API\n\u2502   \u251c\u2500\u2500 api\/follow\/route.ts    -&gt; Follow API(temporary)\n\u2502   \u251c\u2500\u2500 api\/timeline\/route.ts  -&gt; Timeline API\n\u2502   \u251c\u2500\u2500 users\/&#91;username]\/\n\u2502   \u2502   \u251c\u2500\u2500 statuses\/&#91;id]\/route.ts -&gt; Indivisual Post\n\u2502   \u2502   \u251c\u2500\u2500 route.ts               -&gt; Acotr Information\n\u2502   \u2502   \u251c\u2500\u2500 followers\/route.ts     -&gt; Followers List\n\u2502   \u2502   \u251c\u2500\u2500 following\/route.ts     -&gt; Following List\n\u2502   \u2502   \u251c\u2500\u2500 inbox\/route.ts         -&gt; Inbox\n\u2502   \u2502   \u2514\u2500\u2500 outbox\/route.ts        -&gt; outbox\n\u2502   \u251c\u2500\u2500 usersui\/&#91;username]\/page.tsx  -&gt; Timeline UI\n\u2502   \u251c\u2500\u2500 layout.tsx, page.tsx, globals.css\n\u2502   \u2514\u2500\u2500 favicon.ico\n\u251c\u2500\u2500 lib\/\n\u2502   \u251c\u2500\u2500 ap.ts                  -&gt; Follow Accept\n\u2502   \u2514\u2500\u2500 db.ts                  -&gt; DB connection\n\u251c\u2500\u2500 data\/\n\u2502   \u2514\u2500\u2500 keys\/                  -&gt; private.pem, public.pem\n\u251c\u2500\u2500 data.sqlite                -&gt; Database\n\u251c\u2500\u2500 Caddyfile                  -&gt; https \n\u2514\u2500\u2500 package.json<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \ud504\ub85c\uc81d\ud2b8 \uc2dc\uc791(myapp21)<br>Project Start (myapp21)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx create-next-app@latest<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 SQLite\uc124\uce58 \/ Installing SQLite<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/myapp20\nnpm install better-sqlite3\nnpm install -D @types\/better-sqlite3<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 DDNS,https\uc124\uc815 \/ DDNS,https settings<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-freelifemakers-org wp-block-embed-freelifemakers-org\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"kJubVWPPjF\"><a href=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/10\/nextjs-dns-caddy\/\">[nextjs]nextjs+domain(ddns)+https(caddy)<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;[nextjs]nextjs+domain(ddns)+https(caddy)&#8221; &#8212; freelifemakers.org\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/10\/nextjs-dns-caddy\/embed\/#?secret=iFF7dV1HkU#?secret=kJubVWPPjF\" data-secret=\"kJubVWPPjF\" width=\"560\" height=\"315\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\ud83d\udcc1 \ub3c4\uba54\uc778\ud5c8\uc6a9, @userid \uc0ac\uc6a9\ud558\uae30<br>Allowing domains, using @userid<\/p>\n\n\n\n<p>&#8212; next.config.ts<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import type { NextConfig } from \"next\";\n\nconst nextConfig: NextConfig = {\n  \/* allow domain*\/\n  allowedDevOrigins: &#91;'aloy-horizon.duckdns.org', '*.duckdns.org'],\n\n  \/* host.domain.org\/@userid *\/\n<strong>  async rewrites() {\n    return &#91;\n      {\n        source: '\/@:username',\n        destination: '\/usersui\/:username',\n      },\n    ]\n  }<\/strong>\n};\n\n\nexport default nextConfig;\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udcc1 Following \ucc98\ub9ac \ubd80\ubd84 \uc218\uc815 \/ Modification to the &#8216;Following&#8217; processing logic<\/p>\n\n\n\n<p>\u2714\ufe0f @user1@aloy-horizon.duckdns.org \uacc4\uc815\uc5d0\uc11c followers\uac00 \uc911\ubcf5 \uc694\uccad \ud558\uc9c0 \uc54a\ub3c4\ub85d\ud569\ub2c8\ub2e4.<br>Prevent duplicate requests from followers for the @user1@aloy-horizon.duckdns.org account.<\/p>\n\n\n\n<p>&#8212; \uc720\ub2c8\ud06c \uc778\ub371\uc2a4 \ucd94\uac00(sqlite) \/ Add Unique Index (SQLite)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE UNIQUE INDEX IF NOT EXISTS idx_following_actor_username ON following(actor, username);<\/code><\/pre>\n\n\n\n<p>&#8212; myapp21\/app\/api\/follow\/route.ts<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>... ...\n\nexport async function POST(req: Request) {\n\n ... ...\n\n    \/\/ myapp21 \u2705\n    \/\/ \uc774\ubbf8 \ud314\ub85c\uc789 \uc911\uc774\uba74 \ub124\ud2b8\uc6cc\ud06c \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uc74c\n    \/\/ Do not send a network request if already following\n    const already = db.prepare('SELECT id FROM following WHERE actor = ? AND username = ?').get(target, username) as any;\n    if (already) {\n      console.log(`\u2139\ufe0f &#91;${username}] \uc774\ubbf8 \ud314\ub85c\uc789 \uc911 \/ Already following - \uc694\uccad \uc2a4\ud0b5 \/ Skip request: ${target}`);\n      return Response.json({ \n        ok: true, \n        alreadyFollowing: true, \n        target, \n        username,\n        message: '\uc774\ubbf8 \ud314\ub85c\uc789 \uc911 \/ Already following'\n      });\n\n... ...\n\n}  \n  \n... ...\n\n  \/\/ myapp21 \u2705 \n  \/\/ \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc911\ubcf5 \uc785\ub825 \ubc29\uc9c0 \/ Preventing duplicate entries in the database\n    if (result.ok) {\n      try {\n        db.prepare('INSERT INTO following (id, actor, username) VALUES (?, ?, ?)')\n          .run(result.followDoc.id, target, username);\n        console.log(`\u2705 DB \uc800\uc7a5 \/ DB Save: ${username} -&gt; ${target}`);\n      } catch (e: any) {\n        if (e.code === 'SQLITE_CONSTRAINT_UNIQUE') {\n          console.log(`\u2139\ufe0f \uc774\ubbf8 \uc800\uc7a5\ub428  \/ Already saved: ${target}`);\n        } else {\n          console.error('DB \uc800\uc7a5 \uc2e4\ud328 \/ DB save failed:', e);\n        }\n      }\n    }\n\n... ...\n\n}\n\n... ...\n\nexport async function DELETE(req: Request) {\n\n  ... ...\n\n    \/\/ \u2705 myapp21 - \uc5b8\ud314\ub85c\uc6b0 \uc911\ubcf5 \uccb4\ud06c \/ \n    const exists = db.prepare('SELECT id FROM following WHERE actor = ? AND username = ?').get(target, username) as any;\n    if (!exists) {\n      console.log(`\u2139\ufe0f &#91;${username}] \ud314\ub85c\uc789 \uc911 \uc544\ub2d8 \/ Not Following - \uc5b8\ud314 \uc2a4\ud0b5 \/  Skip Unfollowing: ${target}`);\n      return Response.json({ ok: true, alreadyNotFollowing: true, message: '\uc774\ubbf8 \uc5b8\ud314 \uc0c1\ud0dc \/ Already unfollowed.' });\n    }\n\n... ...\n\n}\n<\/code><\/pre>\n\n\n\n<p>&#8212; myapp21\/lib\/db.ts<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.exec(`\n  CREATE INDEX IF NOT EXISTS idx_followers_username ON followers(username);\n  CREATE INDEX IF NOT EXISTS idx_followers_actor ON followers(actor);\n  CREATE INDEX IF NOT EXISTS idx_following_username ON following(username);\n  CREATE INDEX IF NOT EXISTS idx_following_actor ON following(actor);\n  CREATE INDEX IF NOT EXISTS idx_posts_username_created ON posts(username, created_at DESC);\n  CREATE INDEX IF NOT EXISTS idx_inbox_username_created ON inbox_posts(username, created_at DESC);\n  CREATE INDEX IF NOT EXISTS idx_inbox_actor ON inbox_posts(actor);\n  <strong>CREATE UNIQUE INDEX IF NOT EXISTS idx_following_actor_username ON following(actor, username);<\/strong>\n`);<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 Follower \ucc98\ub9ac \ubd80\ubd84 \uc218\uc815 \/ Modified the follower handling logic.<\/p>\n\n\n\n<p>&#8212; \uc720\ub2c8\ud06c \uc778\ub371\uc2a4 \ucd94\uac00 \/ Add unique index (sqlite)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE UNIQUE INDEX idx_followers_actor_username ON followers(actor, username);<\/code><\/pre>\n\n\n\n<p>&#8212; myapp21\/app\/users\/[username]\/inbox\/route.ts<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      \n... ...\n\n\/\/ \u2705 myapp21 \n\/\/ \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc911\ubcf5 \uc785\ub825 \ubc29\uc9c0 \/ Preventing duplicate entries in the database      \n\nconst exists = db.prepare('SELECT 1 FROM followers WHERE actor = ? AND username = ?').get(actorId, username) as any;\n      \n      if (exists) {\n        console.log(`\u2139\ufe0f &#91;${username}] \uc774\ubbf8 \ud314\ub85c\uc6cc \/ Already follower: ${actorId} - \uc911\ubcf5 \ubb34\uc2dc\/Ignore duplicates`);\n      } else {\n        db.prepare('INSERT INTO followers (id, actor, inbox, username) VALUES (?,?,?,?)')\n        .run(body.id, actorId, inboxUrl, username);\n        console.log(`\u2705 &#91;${username}] \ud314\ub85c\uc6b0 \uc800\uc7a5 \/ follow save : ${actorId}`);\n      }<\/code><\/pre>\n\n\n\n<p>&#8212; myapp21\/lib\/db.ts<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE UNIQUE INDEX IF NOT EXISTS idx_following_actor_username ON following(actor, username);\n<strong>CREATE UNIQUE INDEX idx_followers_actor_username ON followers(actor, username);<\/strong><\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 gotosocial DB(docker compose)<\/p>\n\n\n\n<p>\u2714\ufe0f\uc544\ub798\uc758 \uacfc\uc815\uc73c\ub85c  \uae30\uc874 DB\ub97c \ucd08\uae30\ud654 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>You can initialize the existing database by following the steps below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n# DB \ub4e4\uc5b4\uac00\uae30 \/ Accessing the DB\nsqlite3 sqlite.db\n\nSELECT username, domain, followers_count, following_count FROM accounts WHERE domain='aloy-horizon.duckdns.org';\n\n# \uc0ad\uc81c \/ delete\nDELETE FROM accounts WHERE domain='aloy-horizon.duckdns.org' AND username='user1';\n\n.quit\n\n# \uc11c\ubc84 \uc7ac\uc2dc\uc791 \/ Server restart\ndocker compose restart gotosocial\ndocker compose logs -f gotosocial<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f sqlite\uc5d0\uc11c \uc624\ub958\uac00 \uc788\ub294 \ub370\uc774\ud130 \uc0ad\uc81c<\/p>\n\n\n\n<p>&#8212; \uc544\ub798\ucc98\ub7fc followers,following,toots\ub97c \ubaa8\ub450 0\uc73c\ub85c \ucd08\uae30\ud654 \uc2dc\ud0b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nsqlite> <strong>SELECT id, username, domain, uri FROM accounts WHERE domain='aloy-horizon.duckdns.org';<\/strong>\n<strong>01KZWNMF7BFD5N6MAYV3068C81<\/strong>|user1|aloy-horizon.duckdns.org|https:\/\/aloy-horizon.duckdns.org\/users\/user1\n\nsqlite> <strong>SELECT * FROM account_stats WHERE account_id='01KZWNMF7BFD5N6MAYV3068C81';<\/strong>\n<strong>01KZWNMF7BFD5N6MAYV3068C81<\/strong>|2026-06-10 01:20:08.931+00:00|0|1|0|2|0|\n\n-- follows \ud14c\uc774\ube14 \ud655\uc778 \/ Check the 'follows' table.\nsqlite><strong>SELECT * FROM follows WHERE account_id='01KZWNMF7BFD5N6MAYV3068C81' OR target_account_id='01KZWNMF7BFD5N6MAYV3068C81';<\/strong>\n\nsqlite>DELETE FROM account_stats WHERE account_id='01KZWNMF7BFD5N6MAYV3068C81';\nsqlite>DELETE FROM accounts WHERE id='01KZWNMF7BFD5N6MAYV3068C81';\n\n-- follows\ub294 \uc774\ubbf8 \ube44\uc5b4\uc788\uc74c \/ 'follows' is already empty.\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>-- toots \uc624\ub958 \uc788\uc5b4\uc11c \ubaa8\ub450 \uc0ad\uc81c \/ Deleted everything due to errors with Toots.\n\nsqlite> SELECT id FROM accounts WHERE domain='aloy-horizon.duckdns.org';\n01M0RKD5BF8JEGA7HN2A66Z54C\n\nsqlite> SELECT COUNT(*) FROM statuses WHERE account_id='01M0RKD5BF8JEGA7HN2A66Z54C';\n0\n\nsqlite> SELECT COUNT(*) FROM statuses WHERE account_id='01KZWNMF7BFD5N6MAYV3068C81';\n3\n\nsqlite> DELETE FROM statuses WHERE account_id='01KZWNMF7BFD5N6MAYV3068C81';\nsqlite> DELETE FROM account_stats WHERE account_id='01KZWNMF7BFD5N6MAYV3068C81';\nsqlite> DELETE FROM accounts WHERE id='01KZWNMF7BFD5N6MAYV3068C81';\n\nsqlite> SELECT id, username, domain FROM accounts WHERE domain='aloy-horizon.duckdns.org';\n01M0RKD5BF8JEGA7HN2A66Z54C|user1|aloy-horizon.duckdns.org\n\nsqlite> DELETE FROM statuses WHERE account_id='01M0RKD5BF8JEGA7HN2A66Z54C';\nsqlite> DELETE FROM account_stats WHERE account_id='01M0RKD5BF8JEGA7HN2A66Z54C';\nsqlite> DELETE FROM accounts WHERE id='01M0RKD5BF8JEGA7HN2A66Z54C';\nsqlite> DELETE FROM statuses WHERE id IN (SELECT id FROM statuses WHERE account_id NOT IN (SELECT id FROM accounts));\nsqlite> .quit\n\n-- \ub3c4\ucee4 \ucef4\ud3ec\uc988\ub97c \uc7ac\uc2dc\uc791\ud569\ub2c8\ub2e4.\ndocker compose down\ndocker compose up -d<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \ud14c\uc2a4\ud2b8 \/ Test<\/p>\n\n\n\n<p>\u2714\ufe0f \ud130\ubbf8\ub110\uc5d0\uc11c \uc544\ub798\uc758 \ub77c\uc6b0\ud2b8\ub85c \ud14c\uc2a4\ud2b8 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>You can test using the route below in the terminal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \ud314\ub85c\uc6b0 (following 1\ub85c \uc99d\uac00)\n# Follow (following increased to 1)\n\ncurl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/follow \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"username\":\"user1\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\"}'\n\n# \uc5b8\ud314\ub85c\uc6b0 (following 0\uc73c\ub85c \uac10\uc18c)\n# Unfollow (following count reduced to 0)\n\ncurl -X DELETE https:\/\/aloy-horizon.duckdns.org\/api\/follow \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"username\":\"user1\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\"}'\n\n# \uae00 \uc4f0\uae30 (outbox 7\ub85c \uc99d\uac00 + \ud314\ub85c\uc6cc\ub4e4\uc5d0\uac8c \ubc30\ub2ec)\n# Writing a post (added to outbox 7 + delivered to followers)\n\ncurl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/posts \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"username\":\"user1\",\"content\":\"Hello Follow! #test\"}'<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \ud314\ub85c\uc6b0 \ud14c\uc2a4\ud2b8 \/ Follow Test<\/p>\n\n\n\n<p>&#8211;\ud314\ub85c\uc6b0 \uc694\uccad\uc744 \ub450\ubc88\ud558\uba74 \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<br>If you send a follow request twice, the request will not be sent.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> ~ % <strong>curl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/follow \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"username\":\"user1\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\"}'<\/strong>\n{\"ok\":true,\"inbox\":\"https:\/\/freelifemakers.com\/users\/user1\/inbox\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\",\"username\":\"user1\",\"result\":\"{\\\"status\\\":\\\"Accepted\\\"}\",\"follow\":{\"@context\":\"https:\/\/www.w3.org\/ns\/activitystreams\",\"id\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\/follows\/1787534744543\",\"type\":\"Follow\",\"actor\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\",\"object\":\"https:\/\/freelifemakers.com\/users\/user1\"}}%                                                                                                                       ~ % <strong>curl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/follow \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"username\":\"user1\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\"}'<\/strong>\n{\"ok\":true,\"alreadyFollowing\":true,\"target\":\"https:\/\/freelifemakers.com\/users\/user1\",\"username\":\"user1\",\"message\":\"<strong>\uc774\ubbf8 \ud314\ub85c\uc789 \uc911 \/ Already following<\/strong>\"}%                                                                                                                             \n~ % <\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \uae00 \ubc30\ub2ec \ud655\uc778 \/ Confirming post delivery<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;aloy-horizon.duckdns.org\/@user1<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"422\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp21-timeline-jpg.jpg\" alt=\"\" class=\"wp-image-8710\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp21-timeline-jpg.jpg 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp21-timeline-jpg-300x158.jpg 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp21-timeline-jpg-768x405.jpg 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp21-timeline-jpg-400x211.jpg 400w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb @user1@aloy-horizon.duckdns.org\uc758 follows\uc5d0 \uac19\uc740 \uc0ac\uc6a9\uc790\uac00 \ub450\ubc88 \uc785\ub825\ub418\ub294 \ubb38\uc81c\ub97c \uc218\uc815\ud569\ub2c8\ub2e4.Fixes an issue where the same user is entered twice in the &#8216;follows&#8217; list for @user1@aloy-horizon.duckdns.org. \ud83d\udc49\ud83c\udffb follow\uc694\uccad\uc2dc following\uacfc followers\ud14c\uc774\ube14\uc5d0 \uae30\uc874 \uc0ac\uc6a9\uc790 \uc788\uc73c\uba74 \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.When a follow request is made, the request is not sent if the user already exists in the &#8216;following&#8217; or &#8216;followers&#8217; tables. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28,27,1,7],"tags":[],"class_list":["post-8635","post","type-post","status-publish","format-standard","hentry","category-news","category-nextjs","category-uncategorized","category-website","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/8635","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=8635"}],"version-history":[{"count":68,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/8635\/revisions"}],"predecessor-version":[{"id":8711,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/8635\/revisions\/8711"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=8635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=8635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=8635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}