1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import { useRef, useEffect, useState } from "react";
3import { TownieIcon } from "./icons.tsx";
4import { Messages } from "./Messages.tsx";
189- **Imports:** Use `https://esm.sh` for npm and Deno dependencies to ensure compatibility on server and browser
190- **Storage Strategy:** Only use backend storage if explicitly required; prefer simple static client-side sites
191- **React Configuration:** When using React libraries, pin versions with `?deps=react@18.2.0,react-dom@18.2.0` and start the file with `/** @jsxImportSource https://esm.sh/react@18.2.0 */`
192- Ensure all React dependencies and sub-dependencies are pinned to the same version
193- **Styling:** Default to using TailwindCSS via `<script src="https://cdn.twind.style" crossorigin></script>` unless otherwise specified
194
275 - Always run table creation before querying
276
2773. **React Configuration:**
278 - All React dependencies must be pinned to 18.2.0
279 - Always include `@jsxImportSource https://esm.sh/react@18.2.0` at the top of React files
280 - Rendering issues often come from mismatched React versions
281
2824. **File Handling:**
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import { useState, useEffect, useContext, createContext } from "react";
3import { useParams } from "react-router";
4
5import { AppContext } from "./App.tsx";
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import { useMemo } from "react";
3import { useNavigate, useParams } from "react-router";
4import { useBranches } from "../hooks/useBranches.tsx";
5import { useCreateBranch } from "../hooks/useCreateBranch.tsx";
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import React, { createContext, useState } from "react";
3import { BrowserRouter, Link, Navigate, Outlet, Route, Routes, useLocation } from "react-router";
4import { useLocalStorage } from "react-use";
5import { useUser } from "../hooks/useUser.tsx";
6import { ChatRouteSingleColumn } from "./ChatRouteSingleColumn.tsx";
1# Discord Reaction to Linear Ticket Automation
2
3**How it works:** React to any Discord message with a configured emoji (like `:huss:` or `๐งฟ` - used as an example in this val) and it automatically becomes a Linear ticket with context from the Discord thread.
4
5_Team members can use custom emojis to identify themselves as the ticket creator._
26
271. **Create bot:** [Discord Developer Portal](https://discord.com/developers/applications) โ New Application โ Bot
282. **Set permissions:** OAuth2 โ URL Generator โ selecting `bot` unfurls a Bot Permissions dropdown below โ Select `View Channels`, `Read Message History`, `Add Reactions`
293. **Enable intents:** Bot โ Privileged Gateway Intents โ โ
Message Content Intent
304. **Invite bot:** Use generated URL to add bot to your server
32## How to Use
33
34- **`main.tsx`** - Main cron job that runs every minute checking for new reactions, you can also manually press `Run` to run it immediately
35- **Emoji Configuration** - Edit `backend/config.ts` to customize team member emojis:
36
5
6/**
7 * Cron job to check for new Discord reactions and create Linear tickets
8 * Runs every minute to check for messages with the target emoji reaction
9 */
10export default async function() {
11 console.log(`๐ Discord reaction cron job started at ${new Date().toISOString()}`);
12
13 // Get configuration directly
29 // Process each monitored channel
30 for (const channelId of monitoredChannels) {
31 console.log(`๐ Checking channel ${channelId} for new reactions...`);
32
33 try {
34 await processChannelReactions(discord, linear, serverId, channelId, teamId);
35 } catch (error) {
36 console.error(`โ Error processing channel ${channelId}:`, error);
38 }
39
40 console.log(`โ
Discord reaction cron job completed at ${new Date().toISOString()}`);
41}
42
43/**
44 * Process reactions for a specific channel
45 */
46async function processChannelReactions(
47 discord: DiscordAPI,
48 linear: LinearSDK,
55
56 for (const message of messages) {
57 const reactionResult = discord.findTargetReaction(message);
58 if (!reactionResult) continue;
59
60 const { reaction, createdBy } = reactionResult;
61 const emojiName = reaction.emoji.name;
62
63 // Check if already processed
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useEffect, useRef, useState } from "https://esm.sh/react@18.2.0";
3import type { MapWeatherPoint } from "../../shared/types.ts";
4import { getWeatherDescription, formatTemperature } from "../../shared/types.ts";
1/** @jsxImportSource https://esm.sh/react */
2import { render } from 'https://deno.land/x/resvg_wasm/mod.ts'
3import { Hono } from 'npm:hono'
26 <div tw="h-[270px]"></div>
27 <div tw="flex text-[100px] tracking-[-5px]">Mini App Demo</div>
28 <div tw="flex text-[30px] opacity-50 tracking-[-1px]">Hono + React + Tailwind Demo Project on Val Town</div>
29 </div>
30 </div>
1/** @jsxImportSource https://esm.sh/react@19 */
2import fcsdk from "https://esm.sh/@farcaster/frame-sdk";
3import { useEffect, useState } from "https://esm.sh/react@19";
4
5import { ShareButton } from "./ui.tsx";