## Download [Get the build here]($downloadUrl)
/** * Create a new thread (first release). */ export async function createThread( post: F95Post, token: string ): Promise< threadId: string; url: string > const payload = title: post.title, body: post.body, category: post.category, tags: post.tags ?? [], ; const data = await authFetch( "https://api.f95zone.to/v1/threads", token, method: "POST", body: JSON.stringify(payload) ); return threadId: data.id, url: data.url ;
// store threadId for later updates await context.state.set("f95_thread_id", threadId); context.ui.notify(`Thread created: $url`); jsk studio f95zone
If F95Zone does expose a public API , the Bridge can fall back to HTML scraping (with a small cheerio ‑style parser). All scraping logic lives behind an abstraction layer so the same UI works no matter which method is used. 5️⃣ Security & Privacy Considerations | Concern | Mitigation | |---------|------------| | OAuth token leakage | Store token encrypted using the IDE’s secret‑vault (e.g., VS Code secret storage). Refresh tokens are never written to disk unencrypted. | | Cross‑site request forgery | All POST/PUT calls use the Bearer token header; no cookies are used. | | User‑generated markdown | Escape any raw HTML before posting; only allow a whitelist of tags ( <b> , <i> , <img> ). | | Rate limiting | The bridge respects the Retry‑After header from F95Zone and backs off exponentially. | | Data retention | No forum content is persisted longer than 30 days on the local machine; the user can clear the cache from the settings page. | 6️⃣ Sample Code – Minimal Node/TypeScript Client The snippet below shows the core “post‑or‑update” logic. It can be dropped into the plugin’s backend ( src/backend/f95Client.ts ). // f95Client.ts import fetch from "node-fetch";
$coverImgUrl ? `\n` : "" ## Download [Get the build here]($downloadUrl) /** *
The goal is to give developers who use (a generic game‑development environment) a safe, low‑maintenance way to keep their games visible on F95Zone (a popular community forum for indie/erotic games) without having to manually copy‑paste URLs, screenshots, or update threads. 1️⃣ Feature Overview Name – JSK Studio F95Zone Bridge (or simply JSK‑F95Connector ).
async function publishRelease(context) const token = await context.secrets.get("f95_token"); // encrypted store const threadId, url = await createThread( title: `$context.game.title v$context.version`, body: buildReleaseMarkdown( version: context.version, changelog: context.changelog, downloadUrl: context.downloadUrl, coverImgUrl: context.coverImg, ), category: "Adult Game", , token ); All scraping logic lives behind an abstraction layer
/** * Pull unread replies (used for badge count). */ export async function getUnreadCount( threadId: string, token: string ): Promise<number> const data = await authFetch( `https://api.f95zone.to/v1/threads/$threadId/replies?unread=true`, token ); return data.unreadCount ?? 0;