+16
-1
.env.example
+16
-1
.env.example
···
+97
-3
README.md
+97
-3
README.md
······Channel and user mappings are stored in a SQLite database (`bridge.db`). You can manage them through:······The bridge connects to `irc.hackclub.com:6667` (no TLS) and forwards messages bidirectionally based on channel mappings:+- **NickServ Authentication**: If `NICKSERV_PASSWORD` is configured, the bridge authenticates on connect- **IRC โ Slack**: Messages from mapped IRC channels appear in their corresponding Slack channels- **Slack โ IRC**: Messages from mapped Slack channels are sent to their corresponding IRC channels+- User display names: Uses name from Slack event if available, otherwise Cachet API (if `CACHET_ENABLED=true`), then Slack API fallback+- Thread messages are prefixed with `@xxxxx` (5-char thread ID) to show they're part of a thread+- **User mappings** allow custom IRC nicknames for specific Slack users and enable proper mentions both ways+- **Permissions**: Only channel creators, channel managers, or global admins can bridge/unbridge channelsIf you want to report an issue the main repo is [the tangled repo](https://tangled.org/dunkirk.sh/irc-slack-bridge) and the github is just a mirror.
+37
biome.json
+37
biome.json
···
+21
-21
package.json
+21
-21
package.json
···
+5
-1
slack-manifest.yaml
+5
-1
slack-manifest.yaml
·········
+96
src/commands.test.ts
+96
src/commands.test.ts
···
+502
-120
src/commands.ts
+502
-120
src/commands.ts
···+text: "โ You don't have permission to manage this channel. You must be the channel creator, a channel manager, or an admin.",+text: `โ IRC channel ${ircChannel} is already bridged to <#${existingIrcMapping.slack_channel_id}>`,+text: "โ You don't have permission to manage this channel. You must be the channel creator, a channel manager, or an admin.",+text: `โ IRC nick *${ircNick}* is already linked to <@${existingIrcMapping.slack_user_id}>`,
-87
src/db.ts
-87
src/db.ts
···-return db.query("SELECT * FROM channel_mappings WHERE slack_channel_id = ?").get(slackChannelId) as ChannelMapping | null;-return db.query("SELECT * FROM channel_mappings WHERE irc_channel = ?").get(ircChannel) as ChannelMapping | null;-return db.query("SELECT * FROM user_mappings WHERE slack_user_id = ?").get(slackUserId) as UserMapping | null;-return db.query("SELECT * FROM user_mappings WHERE irc_nick = ?").get(ircNick) as UserMapping | null;
+385
-147
src/index.ts
+385
-147
src/index.ts
···-`๐ Server Started in ${Bun.nanoseconds() / 1000000} milliseconds on version: ${version}!\n\n----------------------------------\n`,+`๐ Server Started in ${Bun.nanoseconds() / 1000000} milliseconds on version: ${version}!\n\n----------------------------------\n`,
+44
src/lib/avatars.test.ts
+44
src/lib/avatars.test.ts
···
+19
src/lib/avatars.ts
+19
src/lib/avatars.ts
···+"https://hc-cdn.hel1.your-objectstorage.com/s/v3/4183627c4d26c56c915e104a8a7374f43acd1733_pfp__1_.png",+"https://hc-cdn.hel1.your-objectstorage.com/s/v3/389b1e6bd4248a7e5dd88e14c1adb8eb01267080_pfp__2_.png",+"https://hc-cdn.hel1.your-objectstorage.com/s/v3/03011a5e59548191de058f33ccd1d1cb1d64f2a0_pfp__3_.png",+"https://hc-cdn.hel1.your-objectstorage.com/s/v3/f9c57b88fbd4633114c1864bcc2968db555dbd2a_pfp__4_.png",+"https://hc-cdn.hel1.your-objectstorage.com/s/v3/e61a8cabee5a749588125242747b65122fb94205_pfp.png",
+21
src/lib/cachet.ts
+21
src/lib/cachet.ts
···
+21
src/lib/cdn.ts
+21
src/lib/cdn.ts
···
+160
src/lib/db.test.ts
+160
src/lib/db.test.ts
···
+255
src/lib/db.ts
+255
src/lib/db.ts
···+const hasIrcChannelUnique = channelSchema?.sql?.includes("irc_channel TEXT NOT NULL UNIQUE") ?? false;+"SELECT irc_channel, COUNT(*) as count FROM channel_mappings GROUP BY irc_channel HAVING count > 1",+"Warning: Found duplicate IRC channel mappings. Keeping only the most recent mapping for each IRC channel.",+"Warning: Found duplicate IRC nick mappings. Keeping only the most recent mapping for each IRC nick.",+"INSERT OR REPLACE INTO thread_timestamps (thread_ts, thread_id, slack_channel_id, last_message_time) VALUES (?, ?, ?, ?)",
+56
src/lib/mentions.test.ts
+56
src/lib/mentions.test.ts
···
+79
src/lib/mentions.ts
+79
src/lib/mentions.ts
···
+137
src/lib/parser.test.ts
+137
src/lib/parser.test.ts
···
+88
src/lib/parser.ts
+88
src/lib/parser.ts
···
+99
src/lib/permissions.ts
+99
src/lib/permissions.ts
···
+106
src/lib/threads.test.ts
+106
src/lib/threads.test.ts
···
+51
src/lib/threads.ts
+51
src/lib/threads.ts
···
+168
src/lib/user-cache.test.ts
+168
src/lib/user-cache.test.ts
···
+104
src/lib/user-cache.ts
+104
src/lib/user-cache.ts
···
-89
src/parser.ts
-89
src/parser.ts
···
+7
src/types.ts
+7
src/types.ts
+24
-24
tsconfig.json
+24
-24
tsconfig.json
···