{"id":8901,"date":"2026-08-28T08:33:56","date_gmt":"2026-08-27T23:33:56","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=8901"},"modified":"2026-08-28T10:37:39","modified_gmt":"2026-08-28T01:37:39","slug":"nextjs-sns-server-15","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/28\/nextjs-sns-server-15\/","title":{"rendered":"[nextjs]SNS Server-15(myapp25)"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb myapp25\uc5d0\uc11c\ub294 \ubd80\uc2a4\ud2b8\ud558\ub294 \uacbd\uc6b0 \ub0b4 \ud314\ub85c\uc6cc\uc5d0\uac8c \uae00\uc744 \uc804\ub2ec\ud558\ub294 \uae30\ub2a5\uc744 \uad6c\ud604\ud569\ub2c8\ub2e4.<br>In myapp25, we are implementing a feature that delivers posts to your followers when you &#8220;boost&#8221; them.<\/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>myapp24\/  \n\u251c\u2500\u2500 app\/  (Next.js App Router)\n\u2502   \u251c\u2500\u2500 .well-known\/webfinger\/route.ts  -> webfinger\n\u2502   \u251c\u2500\u2500 api\/follow\/route.ts    -> Follow API(temporary)\n\u2502   \u251c\u2500\u2500 api\/announce\/route.ts  -> Boost(Announcement)\n\u2502   \u251c\u2500\u2500 api\/like\/route.ts.     -> Like API\n\u2502   \u251c\u2500\u2500 api\/posts\/route.ts     -> Writing API\n\u2502   \u251c\u2500\u2500 api\/timeline\/route.ts  -> Timeline API\n\u2502   \u251c\u2500\u2500 users\/&#91;username]\/\n\u2502   \u2502   \u251c\u2500\u2500 statuses\/&#91;id]\/route.ts -> Indivisual Post\n\u2502   \u2502   \u251c\u2500\u2500 route.ts               -> Acotr Information\n\u2502   \u2502   \u251c\u2500\u2500 followers\/route.ts     -> Followers List\n\u2502   \u2502   \u251c\u2500\u2500 following\/route.ts     -> Following List\n\u2502   \u2502   \u251c\u2500\u2500 inbox\/route.ts         -> Inbox\n\u2502   \u2502   \u2514\u2500\u2500 outbox\/route.ts        -> outbox\n\u2502   \u251c\u2500\u2500 usersui\/&#91;username]\/page.tsx  -> 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                  -> Follow Accept\n\u2502   \u2514\u2500\u2500 db.ts                  -> DB connection\n\u251c\u2500\u2500 data\/\n\u2502   \u2514\u2500\u2500 keys\/                  -> private.pem, public.pem\n\u251c\u2500\u2500 data.sqlite                -> Database\n\u251c\u2500\u2500 Caddyfile                  -> https \n\u2514\u2500\u2500 package.json<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \ud504\ub85c\uc81d\ud2b8 \uc2dc\uc791(myapp25)<br>Project Start (myapp25)<\/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 ~\/myapp25\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=\"CvEOhSSfNN\"><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=2PmOV3nrtC#?secret=CvEOhSSfNN\" data-secret=\"CvEOhSSfNN\" 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 \ubd80\uc2a4\ud2b8 \ubcf4\ub0bc \ub54c \/ When sending a boost<\/p>\n\n\n\n<p>\u2714\ufe0f myapp25\/app\/api\/announce\/route.ts<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    if (result.ok) {\n      db.prepare('INSERT INTO announces (id, username, object) VALUES (?, ?, ?)').run(result.announceDoc.id, username, apObjectId);\n    \n      \/\/ \u2705 myapp25 - \ud314\ub85c\uc6cc\uc5d0\uac8c \ubd80\uc2a4\ud2b8 \ubc30\ub2ec \/ Deliver Boosts to followers\n      const followers = db.prepare('SELECT inbox, actor FROM followers WHERE username = ?').all(username) as any&#91;];\n      console.log(`\ud83d\udce2 \ubd80\uc2a4\ud2b8 \ubc30\ub2ec \uc2dc\uc791: ${followers.length}\uba85\uc5d0\uac8c`);\n\n      for (const f of followers) {\n        try {\n          \/\/ \ud314\ub85c\uc6cc inbox\uc5d0 Announce \uadf8\ub300\ub85c \uc804\ub2ec\n          \/\/ ap.ts\uc5d0 sendAnnounce \uc7ac\uc0ac\uc6a9\n          await sendAnnounce(f.inbox, apObjectId, username);\n        } catch (e) {\n          console.error(`\ubc30\ub2ec \uc2e4\ud328 -> ${f.actor}`, e);\n        }\n      }\n      \n    }<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \ubd80\uc2a4\ud2b8 \ubc1b\uc744 \ub54c \/ When receiving a boost<\/p>\n\n\n\n<p>\u2714\ufe0f myapp25\/app\/users\/[username]\/inbox\/route.ts<\/p>\n\n\n\n<p>&#8212; \ubd80\uc2a4\ud2b8 \ubc1b\uae30 \/ Receive boost<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> \/\/ \u2705 myapp25 - \ubd80\uc2a4\ud2b8 \ubc1b\uae30 \/ Receive Boost !\n    if (body.type === 'Announce') {\n      try {\n        const announceId = body.id;\n        const objectId = typeof body.object === 'string' ? body.object : body.object?.id;\n        console.log(`\ud83d\udd01 &#91;${username}] Announce \ub3c4\ucc29: ${actorId} -> ${objectId}`);\n\n        \/\/ 1. announces \ud14c\uc774\ube14\uc5d0 \uae30\ub85d\n        \/\/ Record in announces table\n        db.prepare('INSERT OR IGNORE INTO announces (id, username, object) VALUES (?,?,?)')\n          .run(announceId, username, objectId);\n\n        \/\/ 2. \uc6d0\uae00 \ub0b4\uc6a9 \uac00\uc838\uc640\uc11c inbox_posts\uc5d0 \uc800\uc7a5 (\ud0c0\uc784\ub77c\uc778\uc5d0 \ub728\uac8c)\n        \/\/ Retrieve the original post content and save it to inbox_posts (so it appears on the timeline)\n        try {\n          const noteRes = await fetch(objectId, {\n            headers: { Accept: 'application\/activity+json' }\n          });\n          if (noteRes.ok) {\n            const note = await noteRes.json();\n            const longId = note.id || objectId;\n            const shortId = `${longId.split('\/').pop()}_boost_${Date.now()}`; \/\/ \ubd80\uc2a4\ud2b8\ub294 \ubcc4\ub3c4 id\n            const content = note.content || note.summary || '';\n\n            db.prepare(`\n              INSERT OR IGNORE INTO inbox_posts (id, actor, content, username, original_id, created_at) \n              VALUES (?, ?, ?, ?, ?, ?)\n            `).run(shortId, actorId, content, username, longId, body.published || new Date().toISOString());\n            console.log(`\u2705 &#91;${username}] \ubd80\uc2a4\ud2b8 inbox_posts \uc800\uc7a5 \/ Boost inbox_posts save: ${shortId}`);\n          }\n        } catch (fetchErr) {\n          console.log(`\u26a0 \uc6d0\uae00 fetch \uc2e4\ud328, content \uc5c6\uc774 \uc800\uc7a5`, fetchErr);\n          \/\/ fetch \uc2e4\ud328\ud574\ub3c4 \ubd80\uc2a4\ud2b8 \uae30\ub85d\uc740 \ub0a8\uae40 \/ Boost records are saved even if fetch fails.\n          db.prepare(`\n            INSERT OR IGNORE INTO inbox_posts (id, actor, content, username, original_id, created_at) \n            VALUES (?, ?, ?, ?, ?, ?)\n          `).run(`boost_${Date.now()}`, actorId, `&#91;Boost] ${objectId}`, username, objectId, new Date().toISOString());\n        }\n\n        console.log(`\u2705 &#91;${username}] announces \uc800\uc7a5 \uc644\ub8cc \/ Announcements saved.: ${announceId}`);\n      } catch (e) {\n        console.error(`\u274c Announce \uc800\uc7a5 \uc2e4\ud328 \/ Failed to save Announce.`, e);\n      }\n      return new Response('', { status: 202 });\n    }<\/code><\/pre>\n\n\n\n<p>&#8212; \ubd80\uc2a4\ud2b8 \ucde8\uc18c\ubc1b\uae30 \/ Cancel Boost(Undo Announce)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    \/\/ \u2705 myapp25 - Undo Announce (\ubd80\uc2a4\ud2b8 \ucde8\uc18c \ubc1b\uae30)\n    if (body.type === 'Undo') {\n      \/\/ \uc704\uc5d0\uc11c \uc774\ubbf8 Follow, Like Undo \ucc98\ub9ac\ud588\uc73c\ub2c8\uae4c \uc5ec\uae30\uc11c\ub294 Announce Undo\ub9cc\n      const obj = body.object;\n      if (typeof obj === 'object' &amp;&amp; obj.type === 'Announce') {\n        const announceId = obj.id;\n        const objectId = typeof obj.object === 'string' ? obj.object : obj.object?.id;\n        console.log(`\u21a9 &#91;${username}] Undo Announce: ${actorId} -> ${objectId}`);\n        \n        db.prepare('DELETE FROM announces WHERE id = ?').run(announceId);\n        \/\/ inbox_posts\uc5d0\uc11c \ubd80\uc2a4\ud2b8 \uae00\ub3c4 \uc0ad\uc81c (\uc120\ud0dd)\n        db.prepare('DELETE FROM inbox_posts WHERE original_id = ? AND actor = ?').run(objectId, actorId);\n        console.log(`\ud83d\uddd1 &#91;${username}] \ubd80\uc2a4\ud2b8 \ucde8\uc18c \ucc98\ub9ac \uc644\ub8cc \/ Boost processing cancellation complete.`);\n        return new Response('', { status: 202 });\n      }\n    }<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \ud14c\uc2a4\ud2b8 \/ Test<\/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:\/\/mastodon.social\/users\/mcnees\"}'\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:\/\/mastodon.social\/users\/mcnees\"}'\n\n# \ubd80\uc2a4\ud2b8 \uc2e4\ud589 \/ Boost\ncurl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/announce \\\n -H \"Content-Type: application\/json\" \\\n -d '{\"username\":\"user1\",\"target\":\"<a href=\"https:\/\/mastodon.social\/@mcnees\/117089019419350090\">https:\/\/mastodon.social\/@mcnees\/117089019419350090<\/a>\"}'\n\n# \ubd80\uc2a4\ud2b8 \ucde8\uc18c \/ Cancle Boost\ncurl -X DELETE https:\/\/aloy-horizon.duckdns.org\/api\/announce \\\n -H \"Content-Type: application\/json\" \\\n -d '{\"username\":\"user1\",\"target\":\"<a href=\"https:\/\/mastodon.social\/@mcnees\/117089019419350090\">https:\/\/mastodon.social\/@mcnees\/117089019419350090<\/a>\"}'<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \ub9c8\uc2a4\ud1a0\ub3c8 \uc11c\ubc84\uc758 \uae00 \ubd80\uc2a4\ud2b8\ud558\uae30 \/ Boost a post on a Mastodon server<\/p>\n\n\n\n<p><a href=\"https:\/\/mastodon.social\/@mcnees\/117089019419350090\">https:\/\/mastodon.social\/@mcnees\/117089019419350090<\/a><\/p>\n\n\n\n<p>&#8212; \ud314\ub85c\uc6b0,\ubd80\uc2a4\ud2b8\uc2e4\ud589 \/ Execute Follow and Boost<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \ub9c8\uc2a4\ud1a0\ub3c8 \uc11c\ubc84\uc5d0 \ud314\ub85c\uc6b0 \uc694\uccad \/ Follow request to a Mastodon server\n\nmyapp25 % <strong>curl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/follow \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"username\":\"user1\",\"target\":\"https:\/\/mastodon.social\/users\/mcnees\"}'<\/strong>\n\n{\"ok\":true,\"inbox\":\"https:\/\/mastodon.social\/users\/mcnees\/inbox\",\"target\":\"https:\/\/mastodon.social\/users\/mcnees\",\"username\":\"user1\",\"result\":\"\",\"follow\":{\"@context\":\"https:\/\/www.w3.org\/ns\/activitystreams\",\"id\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\/follows\/1787878537250\",\"type\":\"Follow\",\"actor\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\",\"object\":\"https:\/\/mastodon.social\/users\/mcnees\"}}%                                                               \n\n# \ubd80\uc2a4\ud2b8 \uc2e4\ud589 \/ Run Boost\n\n myapp25 % <strong>curl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/announce \\\n -H \"Content-Type: application\/json\" \\\n -d '{\"username\":\"user1\",\"target\":\"https:\/\/mastodon.social\/@mcnees\/117089019419350090\"}'<\/strong>\n\n{\"ok\":true,\"result\":{\"ok\":true,\"status\":202,\"text\":\"\",\"announceDoc\":{\"@context\":\"https:\/\/www.w3.org\/ns\/activitystreams\",\"id\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\/announces\/15aad35a-32de-4de0-b832-9134498b94d5\",\"type\":\"Announce\",\"actor\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\",\"object\":\"https:\/\/mastodon.social\/users\/mcnees\/statuses\/117089019419350090\",\"published\":\"2026-08-28T00:56:17.391Z\",\"to\":&#91;\"https:\/\/www.w3.org\/ns\/activitystreams#Public\"],\"cc\":&#91;\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\/followers\",\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\"]}}}%                                         \ngimdaegyeong@gimdaegyeong-ui-MacBookAir myapp25 % <\/code><\/pre>\n\n\n\n<p>&#8212; \ub0b4 DB\uc5d0 \ubd80\uc2a4\ud2b8 \uc804\ub2ec\ud655\uc778 \/ Check Boost delivery status in my DB<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sqlite> select * from announces;\nhttps:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12WRSDN77HCBMPES6NH8A4Z|user1|https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M10AHFHCKGF9BY5G4H50VSHG|2026-08-28 00:36:59\nhttps:\/\/aloy-horizon.duckdns.org\/users\/user1\/announces\/9d4b9bc4-fa12-4073-b034-794c0dde40f8|user1|https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12X859S7WNSJJD42NWZS8T7|2026-08-28 00:46:46\nhttps:\/\/aloy-horizon.duckdns.org\/users\/user1\/announces\/15aad35a-32de-4de0-b832-9134498b94d5|user1|https:\/\/mastodon.social\/users\/mcnees\/statuses\/117089019419350090|2026-08-28 00:56:17\nsqlite> <\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f freelifemakers.com\uc5d0\uc11c \ubd80\uc2a4\ud2b8 \ud55c \uacbd\uc6b0<br>If you boosted via freelifemakers.com<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sqlite&gt; select * from announces;\nhttps:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12WRSDN77HCBMPES6NH8A4Z|user1|https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M10AHFHCKGF9BY5G4H50VSHG|2026-08-28 00:36:59<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f aloy-horizon.duckdns.org\uac00 freelifemakers.com\uc744 \ubd80\uc2a4\ud2b8\ud55c \uacbd\uc6b0<br>If aloy-horizon.duckdns.org has boosted freelifemakers.com<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \ubd80\uc2a4\ud2b8 \uc2e4\ud589 \/ Boost\ncurl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/announce \\\n -H \"Content-Type: application\/json\" \\\n -d \n'{\"username\":\"user1\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12X859S7WNSJJD42NWZS8T7\"}'\n\n# \ubd80\uc2a4\ud2b8 \ucde8\uc18c \/ Cancle Boost\ncurl -X DELETE https:\/\/aloy-horizon.duckdns.org\/api\/announce \\\n -H \"Content-Type: application\/json\" \\\n -d \n'{\"username\":\"user1\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12X859S7WNSJJD42NWZS8T7\"}'<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>myapp25 % <strong>curl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/announce \\\n -H \"Content-Type: application\/json\" \\\n -d '{\"username\":\"user1\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12X859S7WNSJJD42NWZS8T7\"}'<\/strong>\n\n{\"ok\":true,\"result\":{\"ok\":true,\"status\":202,\"text\":\"{\\\"status\\\":\\\"Accepted\\\"}\",\"announceDoc\":{\"@context\":\"https:\/\/www.w3.org\/ns\/activitystreams\",\"id\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\/announces\/9d4b9bc4-fa12-4073-b034-794c0dde40f8\",\"type\":\"Announce\",\"actor\":\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\",\"object\":\"https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12X859S7WNSJJD42NWZS8T7\",\"published\":\"2026-08-28T00:46:46.182Z\",\"to\":&#91;\"https:\/\/www.w3.org\/ns\/activitystreams#Public\"],\"cc\":&#91;\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\/followers\",\"https:\/\/aloy-horizon.duckdns.org\/users\/user1\"]}}}%      \n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>sqlite> <strong>select * from announces;<\/strong>\nhttps:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12WRSDN77HCBMPES6NH8A4Z|user1|https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M10AHFHCKGF9BY5G4H50VSHG|2026-08-28 00:36:59\n<strong>https:\/\/aloy-horizon.duckdns.org\/users\/user1\/announces\/9d4b9bc4-fa12-4073-b034-794c0dde40f8|user1|https:\/\/freelifemakers.com\/users\/user1\/statuses\/01M12X859S7WNSJJD42NWZS8T7|2026-08-28 00:46:46<\/strong>\nsqlite> <\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\uc694\ud55c\ubcf5\uc74c 8\uc7a5 32\uc808 \/ John 8:32<\/p>\n\n\n\n<p>&#8220;\uadf8\ub9ac\uace0 \ub108\ud76c\ub294 \uc9c4\ub9ac\ub97c \uc54c\uac8c \ub420 \uac83\uc774\uba70, \uc9c4\ub9ac\uac00 \ub108\ud76c\ub97c \uc790\uc720\ub86d\uac8c \ud560 \uac83\uc774\ub2e4.&#8221;<\/p>\n\n\n\n<p>&#8220;Then you will know the truth ,and the truth will set you free&#8221;<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb myapp25\uc5d0\uc11c\ub294 \ubd80\uc2a4\ud2b8\ud558\ub294 \uacbd\uc6b0 \ub0b4 \ud314\ub85c\uc6cc\uc5d0\uac8c \uae00\uc744 \uc804\ub2ec\ud558\ub294 \uae30\ub2a5\uc744 \uad6c\ud604\ud569\ub2c8\ub2e4.In myapp25, we are implementing a feature that delivers posts to your followers when you &#8220;boost&#8221; them. \ud83d\udcc1 \uc804\uccb4 \ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \/ Overall Project Structure \ud83d\udcc1 \ud504\ub85c\uc81d\ud2b8 \uc2dc\uc791(myapp25)Project Start (myapp25) \ud83d\udcc1 SQLite\uc124\uce58 \/ Installing SQLite \ud83d\udcc1 DDNS,https\uc124\uc815 \/ DDNS,https settings \ud83d\udcc1 \ub3c4\uba54\uc778\ud5c8\uc6a9, @userid \uc0ac\uc6a9\ud558\uae30Allowing domains, using [&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-8901","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\/8901","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=8901"}],"version-history":[{"count":50,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/8901\/revisions"}],"predecessor-version":[{"id":8954,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/8901\/revisions\/8954"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=8901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=8901"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=8901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}