all repos — clicker @ main

index.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
type ErrorResponse = {
  error: string;
  code: string;
};

type PostClicksSelfResponse = {
  success: true;
  dndSuppressed: boolean;
};

type WrappedResponse<T> =
  { data: T; error: null } | { data: null; error: ErrorResponse };

const API_KEY = process.env.TOKEN!;
const API_URL = "https://puppyclicker-api.boundfire.com/api/v2/clicks/self";

async function sendClick(
  message?: string,
): Promise<WrappedResponse<PostClicksSelfResponse>> {
  try {
    const res = await fetch(API_URL, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        ...(message ? { "Content-Type": "application/json" } : {}),
      },
      ...(message ? { body: JSON.stringify({ message }) } : {}),
    });

    const body = await res.json().catch(() => null);

    if (res.ok && body) {
      return { data: body as PostClicksSelfResponse, error: null };
    }

    return {
      data: null,
      error: (body as ErrorResponse) ?? {
        error: res.statusText || "Request failed",
        code: `HTTP_${res.status}`,
      },
    };
  } catch (err) {
    const message = err instanceof Error ? err.message : "Internal error";
    return {
      data: null,
      error: { error: message, code: "FETCH_ERROR" },
    };
  }
}

function parseMessage(body: unknown): string | undefined {
  if (
    typeof body === "object" &&
    body !== null &&
    "message" in body &&
    typeof body.message === "string"
  ) {
    return body.message;
  }
  return undefined;
}

const server = Bun.serve({
  routes: {
    "/": () => new Response(Bun.file("./index.html")),
    "/assets/main.css": () => new Response(Bun.file("./assets/main.css")),
    "/api/click": {
      POST: async (req) => {
        const body = await req.json().catch(() => null);
        const message = parseMessage(body);

        const result = await sendClick(message);
        const status = result.error ? 502 : 200;

        return Response.json(result, { status });
      },
    },
  },
});

console.log(`Server running at ${server.url}`);