@fluxy-chat/create-fluxy-chat 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@fluxy-chat/create-fluxy-chat",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "bin": {
7
+ "create-fluxy-chat": "./dist/index.js"
8
+ },
9
+ "engines": {
10
+ "node": "\u003e=20.12"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "templates",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsup src/index.ts --format esm --dts",
19
+ "dev": "tsup src/index.ts --format esm --watch",
20
+ "typecheck": "tsc --noEmit",
21
+ "prepublishOnly": "pnpm run build"
22
+ },
23
+ "dependencies": {
24
+ "@clack/prompts": "^0.7.0",
25
+ "picocolors": "^1.1.1"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.0.0",
29
+ "tsup": "^8.3.5",
30
+ "typescript": "^5.6.0"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/AlessandroFare/fluxychat.git",
35
+ "directory": "packages/create-fluxy-chat"
36
+ },
37
+ "homepage": "https://github.com/AlessandroFare/fluxychat/tree/main/packages/create-fluxy-chat#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/AlessandroFare/fluxychat/issues"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "license": "MIT"
45
+ }
package/readme.md ADDED
@@ -0,0 +1,89 @@
1
+ # create-fluxy-chat
2
+
3
+ Scaffold a new [FluxyChat](https://github.com/AlessandroFare/fluxychat) bot project with a single command.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx create-fluxy-chat my-bot
9
+ ```
10
+
11
+ This launches an interactive prompt to configure your bot project.
12
+
13
+ ## Non-Interactive Usage
14
+
15
+ ```bash
16
+ # Create a Slack bot with pnpm
17
+ npx create-fluxy-chat my-bot --adapter slack --pm pnpm
18
+
19
+ # Create a Telegram bot, skip install
20
+ npx create-fluxy-chat my-bot --adapter telegram --skip-install
21
+
22
+ # Create a Discord bot with defaults
23
+ npx create-fluxy-chat my-bot -y --adapter discord
24
+
25
+ # Create a basic webhook bot
26
+ npx create-fluxy-chat my-bot --adapter basic
27
+ ```
28
+
29
+ ## Options
30
+
31
+ | Flag | Short | Description |
32
+ | --- | --- | --- |
33
+ | `--adapter <type>` | `-a` | Adapter: `basic`, `slack`, `telegram`, `discord`, `web` |
34
+ | `--pm <manager>` | | Package manager: `npm`, `pnpm`, `yarn` |
35
+ | `--language <lang>` | `-l` | Language: `typescript` (default) or `javascript` |
36
+ | `--yes` | `-y` | Skip prompts and accept defaults |
37
+ | `--skip-install` | | Skip dependency installation |
38
+ | `--no-git` | | Skip git repository initialization |
39
+ | `--help` | `-h` | Show help |
40
+
41
+ ## Adapters
42
+
43
+ | Adapter | Description | Platform |
44
+ | --- | --- | --- |
45
+ | `basic` | Generic webhook bot | Cloudflare Workers |
46
+ | `slack` | Slack Events API bot | Slack |
47
+ | `telegram` | Telegram webhook bot | Telegram |
48
+ | `discord` | Discord interactions bot | Discord |
49
+ | `web` | Web chat HTTP API bot | Any HTTP client |
50
+
51
+ ## What You Get
52
+
53
+ Each generated project includes:
54
+
55
+ - **`src/index.ts`** — Cloudflare Workers entry point with route handling
56
+ - **`src/bot.ts`** — Bot handler using `@fluxy-chat/sdk`
57
+ - **`wrangler.toml`** — Cloudflare Workers deployment config
58
+ - **`.dev.vars`** — Local development environment variables
59
+ - **`.env.example`** — Example environment variables for your adapter
60
+ - **`tsconfig.json`** — TypeScript configuration (for TS projects)
61
+ - **`README.md`** — Project-specific setup instructions
62
+ - **`.gitignore`** — Standard ignore patterns
63
+
64
+ ## Package Manager Detection
65
+
66
+ The CLI auto-detects your package manager from lockfiles:
67
+
68
+ - `pnpm-lock.yaml` → pnpm
69
+ - `yarn.lock` → yarn
70
+ - `package-lock.json` or none → npm
71
+
72
+ You can override with `--pm`.
73
+
74
+ ## Development
75
+
76
+ ```bash
77
+ # Install dependencies
78
+ pnpm install
79
+
80
+ # Build the CLI
81
+ pnpm build
82
+
83
+ # Run locally
84
+ node dist/index.js my-test-bot -y --adapter basic
85
+ ```
86
+
87
+ ## License
88
+
89
+ MIT
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "fluxy-bot-basic",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "wrangler dev",
8
+ "deploy": "wrangler deploy",
9
+ "type-check": "tsc --noEmit"
10
+ },
11
+ "dependencies": {
12
+ "@fluxy-chat/sdk": "latest"
13
+ },
14
+ "devDependencies": {
15
+ "@cloudflare/workers-types": "^4.0.0",
16
+ "typescript": "^5.6.0",
17
+ "wrangler": "^3.0.0"
18
+ }
19
+ }
@@ -0,0 +1,36 @@
1
+ # fluxy-bot-basic
2
+
3
+ A basic webhook bot built with [FluxyChat](https://github.com/AlessandroFare/fluxychat) and deployed on Cloudflare Workers.
4
+
5
+ ## Getting Started
6
+
7
+ 1. Copy the example environment file:
8
+
9
+ ```bash
10
+ cp .env.example .dev.vars
11
+ ```
12
+
13
+ 2. Start the dev server:
14
+
15
+ ```bash
16
+ pnpm dev
17
+ ```
18
+
19
+ 3. Deploy to Cloudflare Workers:
20
+
21
+ ```bash
22
+ pnpm deploy
23
+ ```
24
+
25
+ ## Endpoints
26
+
27
+ - Health check: `/`
28
+ - Webhook: `/webhook`
29
+
30
+ ## Environment Variables
31
+
32
+ See `.env.example` for all required environment variables.
33
+
34
+ ## License
35
+
36
+ MIT
@@ -0,0 +1,40 @@
1
+ import { FluxyChatClient } from "@fluxy-chat/sdk";
2
+
3
+ interface BotEnv {
4
+ FLUXY_BASE_URL: string;
5
+ FLUXY_API_KEY: string;
6
+ }
7
+
8
+ export async function handleWebhook(
9
+ request: Request,
10
+ env: BotEnv,
11
+ ): Promise<Response> {
12
+ const body = await request.json() as {
13
+ roomId?: string;
14
+ message?: string;
15
+ userId?: string;
16
+ };
17
+
18
+ const client = new FluxyChatClient({
19
+ baseUrl: env.FLUXY_BASE_URL,
20
+ userId: body.userId ?? "bot",
21
+ apiKey: env.FLUXY_API_KEY,
22
+ });
23
+
24
+ try {
25
+ if (body.roomId && body.message) {
26
+ await client.createMessage(body.roomId, body.message);
27
+ }
28
+
29
+ return new Response(
30
+ JSON.stringify({ ok: true }),
31
+ { status: 200, headers: { "Content-Type": "application/json" } },
32
+ );
33
+ } catch (error) {
34
+ console.error("Webhook error:", error);
35
+ return new Response(
36
+ JSON.stringify({ error: "Internal server error" }),
37
+ { status: 500, headers: { "Content-Type": "application/json" } },
38
+ );
39
+ }
40
+ }
@@ -0,0 +1,17 @@
1
+ import { handleWebhook } from "./bot.js";
2
+
3
+ export default {
4
+ async fetch(request: Request, env: Record<string, string>): Promise<Response> {
5
+ const url = new URL(request.url);
6
+
7
+ if (url.pathname === "/webhook" && request.method === "POST") {
8
+ return handleWebhook(request, env);
9
+ }
10
+
11
+ if (url.pathname === "/") {
12
+ return new Response("FluxyChat bot is running!", { status: 200 });
13
+ }
14
+
15
+ return new Response("Not Found", { status: 404 });
16
+ },
17
+ };
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022"],
7
+ "types": ["@cloudflare/workers-types"],
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "allowSyntheticDefaultImports": true,
14
+ "noEmit": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }
@@ -0,0 +1,9 @@
1
+ name = "fluxy-bot-basic"
2
+ main = "src/index.ts"
3
+ compatibility_date = "2024-12-01"
4
+
5
+ [vars]
6
+ FLUXY_BASE_URL = "https://your-fluxychat-worker.example.com"
7
+
8
+ # Set these via `wrangler secret put` for production
9
+ # wrangler secret put FLUXY_API_KEY
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "fluxy-bot-discord",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "wrangler dev",
8
+ "deploy": "wrangler deploy",
9
+ "type-check": "tsc --noEmit"
10
+ },
11
+ "dependencies": {
12
+ "@fluxy-chat/sdk": "latest",
13
+ "discord.js": "^14.0.0"
14
+ },
15
+ "devDependencies": {
16
+ "@cloudflare/workers-types": "^4.0.0",
17
+ "typescript": "^5.6.0",
18
+ "wrangler": "^3.0.0"
19
+ }
20
+ }
@@ -0,0 +1,37 @@
1
+ # fluxy-bot-discord
2
+
3
+ A Discord bot built with [FluxyChat](https://github.com/AlessandroFare/fluxychat) and deployed on Cloudflare Workers.
4
+
5
+ ## Getting Started
6
+
7
+ 1. Copy the example environment file:
8
+
9
+ ```bash
10
+ cp .env.example .dev.vars
11
+ ```
12
+
13
+ 2. Create a Discord application at https://discord.com/developers/applications and get your bot token, application ID, and public key.
14
+
15
+ 3. Start the dev server:
16
+
17
+ ```bash
18
+ pnpm dev
19
+ ```
20
+
21
+ 4. Set the Discord Interactions Endpoint URL to point to your worker's `/discord/interactions` endpoint.
22
+
23
+ ## Endpoints
24
+
25
+ - Discord Interactions: `/discord/interactions`
26
+
27
+ ## Environment Variables
28
+
29
+ - `FLUXY_BASE_URL` — Your FluxyChat worker URL
30
+ - `FLUXY_API_KEY` — FluxyChat API key
31
+ - `DISCORD_BOT_TOKEN` — Discord bot token
32
+ - `DISCORD_APPLICATION_ID` — Discord application ID
33
+ - `DISCORD_PUBLIC_KEY` — Discord public key (for signature verification)
34
+
35
+ ## License
36
+
37
+ MIT
@@ -0,0 +1,59 @@
1
+ import { FluxyChatClient } from "@fluxy-chat/sdk";
2
+
3
+ interface BotEnv {
4
+ FLUXY_BASE_URL: string;
5
+ FLUXY_API_KEY: string;
6
+ DISCORD_BOT_TOKEN: string;
7
+ DISCORD_PUBLIC_KEY: string;
8
+ }
9
+
10
+ export async function handleDiscordInteraction(
11
+ request: Request,
12
+ env: BotEnv,
13
+ ): Promise<Response> {
14
+ const body = await request.text();
15
+
16
+ const client = new FluxyChatClient({
17
+ baseUrl: env.FLUXY_BASE_URL,
18
+ userId: "discord-bot",
19
+ apiKey: env.FLUXY_API_KEY,
20
+ });
21
+
22
+ try {
23
+ const interaction = JSON.parse(body);
24
+
25
+ // Handle Discord ping (verification)
26
+ if (interaction.type === 1) {
27
+ return new Response(JSON.stringify({ type: 1 }), {
28
+ headers: { "Content-Type": "application/json" },
29
+ });
30
+ }
31
+
32
+ // Handle application command
33
+ if (interaction.type === 2) {
34
+ const commandName = interaction.data?.name;
35
+
36
+ if (commandName === "chat") {
37
+ const userId = interaction.member?.user?.id ?? interaction.user?.id ?? "unknown";
38
+ const text = interaction.data?.options?.[0]?.value ?? "";
39
+
40
+ // Forward to FluxyChat
41
+ const roomId = `discord-${interaction.channel_id}`;
42
+ await client.createMessage(roomId, String(text));
43
+
44
+ return new Response(
45
+ JSON.stringify({
46
+ type: 4,
47
+ data: { content: "Message forwarded to FluxyChat!" },
48
+ }),
49
+ { headers: { "Content-Type": "application/json" } },
50
+ );
51
+ }
52
+ }
53
+
54
+ return new Response("Unknown interaction type", { status: 400 });
55
+ } catch (error) {
56
+ console.error("Discord interaction error:", error);
57
+ return new Response("Internal Server Error", { status: 500 });
58
+ }
59
+ }
@@ -0,0 +1,17 @@
1
+ import { handleDiscordInteraction } from "./bot.js";
2
+
3
+ export default {
4
+ async fetch(request: Request, env: Record<string, string>): Promise<Response> {
5
+ const url = new URL(request.url);
6
+
7
+ if (url.pathname === "/discord/interactions" && request.method === "POST") {
8
+ return handleDiscordInteraction(request, env);
9
+ }
10
+
11
+ if (url.pathname === "/") {
12
+ return new Response("FluxyChat Discord bot is running!", { status: 200 });
13
+ }
14
+
15
+ return new Response("Not Found", { status: 404 });
16
+ },
17
+ };
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "fluxy-bot-slack",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "wrangler dev",
8
+ "deploy": "wrangler deploy",
9
+ "type-check": "tsc --noEmit"
10
+ },
11
+ "dependencies": {
12
+ "@fluxy-chat/sdk": "latest",
13
+ "@slack/bolt": "^4.0.0",
14
+ "@slack/web-api": "^7.0.0"
15
+ },
16
+ "devDependencies": {
17
+ "@cloudflare/workers-types": "^4.0.0",
18
+ "typescript": "^5.6.0",
19
+ "wrangler": "^3.0.0"
20
+ }
21
+ }
@@ -0,0 +1,37 @@
1
+ # fluxy-bot-slack
2
+
3
+ A Slack bot built with [FluxyChat](https://github.com/AlessandroFare/fluxychat) and deployed on Cloudflare Workers.
4
+
5
+ ## Getting Started
6
+
7
+ 1. Copy the example environment file:
8
+
9
+ ```bash
10
+ cp .env.example .dev.vars
11
+ ```
12
+
13
+ 2. Create a Slack app at https://api.slack.com/apps and get your bot token and signing secret.
14
+
15
+ 3. Start the dev server:
16
+
17
+ ```bash
18
+ pnpm dev
19
+ ```
20
+
21
+ 4. Set up the Slack Event Subscriptions URL to point to your worker's `/slack/events` endpoint.
22
+
23
+ ## Endpoints
24
+
25
+ - Slack Events API: `/slack/events`
26
+ - Slack Interactive: `/slack/interactive`
27
+
28
+ ## Environment Variables
29
+
30
+ - `FLUXY_BASE_URL` — Your FluxyChat worker URL
31
+ - `FLUXY_API_KEY` — FluxyChat API key
32
+ - `SLACK_BOT_TOKEN` — Slack bot token (xoxb-...)
33
+ - `SLACK_SIGNING_SECRET` — Slack signing secret
34
+
35
+ ## License
36
+
37
+ MIT
@@ -0,0 +1,58 @@
1
+ import { FluxyChatClient } from "@fluxy-chat/sdk";
2
+
3
+ interface BotEnv {
4
+ FLUXY_BASE_URL: string;
5
+ FLUXY_API_KEY: string;
6
+ SLACK_BOT_TOKEN: string;
7
+ SLACK_SIGNING_SECRET: string;
8
+ }
9
+
10
+ export interface SlackBot {
11
+ fluxyClient: FluxyChatClient;
12
+ }
13
+
14
+ export function createSlackBot(): SlackBot {
15
+ return {
16
+ fluxyClient: null as unknown as FluxyChatClient,
17
+ };
18
+ }
19
+
20
+ export async function handleSlackRequest(
21
+ request: Request,
22
+ env: BotEnv,
23
+ bot: SlackBot,
24
+ ): Promise<Response> {
25
+ const body = await request.text();
26
+
27
+ const client = new FluxyChatClient({
28
+ baseUrl: env.FLUXY_BASE_URL,
29
+ userId: "slack-bot",
30
+ apiKey: env.FLUXY_API_KEY,
31
+ });
32
+
33
+ try {
34
+ const payload = JSON.parse(body);
35
+
36
+ // Handle Slack URL verification challenge
37
+ if (payload.type === "url_verification") {
38
+ return new Response(JSON.stringify({ challenge: payload.challenge }), {
39
+ headers: { "Content-Type": "application/json" },
40
+ });
41
+ }
42
+
43
+ // Handle events
44
+ if (payload.event) {
45
+ const event = payload.event;
46
+
47
+ if (event.type === "message" && !event.bot_id) {
48
+ const roomId = `slack-${event.channel}`;
49
+ await client.createMessage(roomId, event.text || "");
50
+ }
51
+ }
52
+
53
+ return new Response("OK", { status: 200 });
54
+ } catch (error) {
55
+ console.error("Slack event error:", error);
56
+ return new Response("Internal Server Error", { status: 500 });
57
+ }
58
+ }
@@ -0,0 +1,19 @@
1
+ import { handleSlackRequest, createSlackBot } from "./bot.js";
2
+
3
+ const bot = createSlackBot();
4
+
5
+ export default {
6
+ async fetch(request: Request, env: Record<string, string>): Promise<Response> {
7
+ const url = new URL(request.url);
8
+
9
+ if (url.pathname === "/slack/events" || url.pathname === "/slack/interactive") {
10
+ return handleSlackRequest(request, env, bot);
11
+ }
12
+
13
+ if (url.pathname === "/") {
14
+ return new Response("FluxyChat Slack bot is running!", { status: 200 });
15
+ }
16
+
17
+ return new Response("Not Found", { status: 404 });
18
+ },
19
+ };
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "fluxy-bot-telegram",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "wrangler dev",
8
+ "deploy": "wrangler deploy",
9
+ "type-check": "tsc --noEmit"
10
+ },
11
+ "dependencies": {
12
+ "@fluxy-chat/sdk": "latest",
13
+ "node-telegram-bot-api": "^0.66.0"
14
+ },
15
+ "devDependencies": {
16
+ "@cloudflare/workers-types": "^4.0.0",
17
+ "typescript": "^5.6.0",
18
+ "wrangler": "^3.0.0"
19
+ }
20
+ }
@@ -0,0 +1,39 @@
1
+ # fluxy-bot-telegram
2
+
3
+ A Telegram bot built with [FluxyChat](https://github.com/AlessandroFare/fluxychat) and deployed on Cloudflare Workers.
4
+
5
+ ## Getting Started
6
+
7
+ 1. Copy the example environment file:
8
+
9
+ ```bash
10
+ cp .env.example .dev.vars
11
+ ```
12
+
13
+ 2. Create a Telegram bot via [@BotFather](https://t.me/BotFather) and get your bot token.
14
+
15
+ 3. Start the dev server:
16
+
17
+ ```bash
18
+ pnpm dev
19
+ ```
20
+
21
+ 4. Set the Telegram webhook to point to your worker's `/telegram/webhook` endpoint:
22
+
23
+ ```bash
24
+ curl "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook?url=https://your-worker.example.com/telegram/webhook"
25
+ ```
26
+
27
+ ## Endpoints
28
+
29
+ - Telegram Webhook: `/telegram/webhook`
30
+
31
+ ## Environment Variables
32
+
33
+ - `FLUXY_BASE_URL` — Your FluxyChat worker URL
34
+ - `FLUXY_API_KEY` — FluxyChat API key
35
+ - `TELEGRAM_BOT_TOKEN` — Telegram bot token from BotFather
36
+
37
+ ## License
38
+
39
+ MIT
@@ -0,0 +1,47 @@
1
+ import { FluxyChatClient } from "@fluxy-chat/sdk";
2
+
3
+ interface BotEnv {
4
+ FLUXY_BASE_URL: string;
5
+ FLUXY_API_KEY: string;
6
+ TELEGRAM_BOT_TOKEN: string;
7
+ }
8
+
9
+ export async function handleTelegramUpdate(
10
+ update: Record<string, unknown>,
11
+ env: BotEnv,
12
+ ): Promise<Response> {
13
+ const client = new FluxyChatClient({
14
+ baseUrl: env.FLUXY_BASE_URL,
15
+ userId: "telegram-bot",
16
+ apiKey: env.FLUXY_API_KEY,
17
+ });
18
+
19
+ try {
20
+ const message = update.message as
21
+ | { chat?: { id?: number }; text?: string; from?: { first_name?: string } }
22
+ | undefined;
23
+
24
+ if (message?.chat?.id && message.text) {
25
+ const roomId = `telegram-${message.chat.id}`;
26
+
27
+ // Forward to FluxyChat
28
+ await client.createMessage(roomId, message.text);
29
+
30
+ // Send reply back to Telegram
31
+ const telegramApiUrl = `https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage`;
32
+ await fetch(telegramApiUrl, {
33
+ method: "POST",
34
+ headers: { "Content-Type": "application/json" },
35
+ body: JSON.stringify({
36
+ chat_id: message.chat.id,
37
+ text: `Hi ${message.from?.first_name ?? "there"}! Message received.`,
38
+ }),
39
+ });
40
+ }
41
+
42
+ return new Response("OK", { status: 200 });
43
+ } catch (error) {
44
+ console.error("Telegram update error:", error);
45
+ return new Response("Internal Server Error", { status: 500 });
46
+ }
47
+ }
@@ -0,0 +1,18 @@
1
+ import { handleTelegramUpdate } from "./bot.js";
2
+
3
+ export default {
4
+ async fetch(request: Request, env: Record<string, string>): Promise<Response> {
5
+ const url = new URL(request.url);
6
+
7
+ if (url.pathname === "/telegram/webhook" && request.method === "POST") {
8
+ const update = await request.json();
9
+ return handleTelegramUpdate(update, env);
10
+ }
11
+
12
+ if (url.pathname === "/") {
13
+ return new Response("FluxyChat Telegram bot is running!", { status: 200 });
14
+ }
15
+
16
+ return new Response("Not Found", { status: 404 });
17
+ },
18
+ };