opencode-discord-bot 0.0.5 → 0.0.6
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
CHANGED
|
@@ -142,6 +142,27 @@ describe("makeChatSdkDiscord", () => {
|
|
|
142
142
|
])
|
|
143
143
|
})
|
|
144
144
|
|
|
145
|
+
test("normalizes Discord user mention wrappers before chat-sdk output conversion", async () => {
|
|
146
|
+
const adapter = new FakeDiscordAdapter()
|
|
147
|
+
const discord = makeChatSdkDiscord(adapter)
|
|
148
|
+
|
|
149
|
+
const posted = await Effect.runPromise(discord.postMessage(scope, "hello <@999> and <@!888>"))
|
|
150
|
+
await Effect.runPromise(discord.editMessage(scope, posted.id, "edited <@777>"))
|
|
151
|
+
await Effect.runPromise(discord.postChannelMessage("g1", "c2", "channel <@666>"))
|
|
152
|
+
|
|
153
|
+
expect(adapter.calls).toEqual([
|
|
154
|
+
["encodeThreadId", { guildId: "g1", channelId: "c1", threadId: "t1" }],
|
|
155
|
+
["postMessage", { threadId: "discord:g1:c1:t1", message: "hello @999 and @888" }],
|
|
156
|
+
["encodeThreadId", { guildId: "g1", channelId: "c1", threadId: "t1" }],
|
|
157
|
+
["editMessage", { threadId: "discord:g1:c1:t1", messageId: "posted-1", message: "edited @777" }],
|
|
158
|
+
["encodeThreadId", { guildId: "g1", channelId: "c2" }],
|
|
159
|
+
["fetchChannelInfo", { channelId: "discord:g1:c2" }],
|
|
160
|
+
["postChannelMessage", { channelId: "discord:g1:c2", message: "channel @666" }]
|
|
161
|
+
])
|
|
162
|
+
})
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
describe("makeChatSdkDiscord REST operations", () => {
|
|
145
166
|
test("routes channel posts, deletes, and raw REST adapter gaps", async () => {
|
|
146
167
|
const adapter = new FakeDiscordAdapter()
|
|
147
168
|
const requests: Array<readonly [string, RequestInit]> = []
|
|
@@ -142,6 +142,8 @@ const rawDiscord = (options: RawDiscordOptions | undefined, path: string, init:
|
|
|
142
142
|
return await response.json()
|
|
143
143
|
})
|
|
144
144
|
|
|
145
|
+
const normalizeMentionsForChatAdapter = (content: string): string => content.replace(/<@!?(\w+)>/g, "@$1")
|
|
146
|
+
|
|
145
147
|
export const makeChatSdkDiscord = (adapter: ChatDiscordAdapter, raw: RawDiscordOptions | undefined = undefined): DiscordService => ({
|
|
146
148
|
fetchContext: (scope, limit) =>
|
|
147
149
|
tryAdapter(async () => {
|
|
@@ -158,11 +160,13 @@ export const makeChatSdkDiscord = (adapter: ChatDiscordAdapter, raw: RawDiscordO
|
|
|
158
160
|
sendTyping: (scope) => tryAdapter(() => adapter.startTyping(threadIdFromScope(adapter, scope))).pipe(Effect.asVoid),
|
|
159
161
|
postMessage: (scope, content) =>
|
|
160
162
|
tryAdapter(async () => {
|
|
161
|
-
const result = await adapter.postMessage(threadIdFromScope(adapter, scope), content)
|
|
163
|
+
const result = await adapter.postMessage(threadIdFromScope(adapter, scope), normalizeMentionsForChatAdapter(content))
|
|
162
164
|
return { id: result.id }
|
|
163
165
|
}),
|
|
164
166
|
editMessage: (scope, messageId, content) =>
|
|
165
|
-
tryAdapter(() => adapter.editMessage(threadIdFromScope(adapter, scope), messageId, content)).pipe(
|
|
167
|
+
tryAdapter(() => adapter.editMessage(threadIdFromScope(adapter, scope), messageId, normalizeMentionsForChatAdapter(content))).pipe(
|
|
168
|
+
Effect.asVoid
|
|
169
|
+
),
|
|
166
170
|
deleteMessage: (scope, messageId) =>
|
|
167
171
|
tryAdapter(() => adapter.deleteMessage(threadIdFromScope(adapter, scope), messageId)).pipe(Effect.asVoid),
|
|
168
172
|
addReaction: (scope, messageId, emoji) =>
|
|
@@ -184,7 +188,10 @@ export const makeChatSdkDiscord = (adapter: ChatDiscordAdapter, raw: RawDiscordO
|
|
|
184
188
|
tryAdapter(async () => {
|
|
185
189
|
const encodedChannelId = adapter.encodeThreadId({ guildId, channelId })
|
|
186
190
|
await validateGuildChannel(adapter, guildId, encodedChannelId)
|
|
187
|
-
const result = await adapter.postChannelMessage(
|
|
191
|
+
const result = await adapter.postChannelMessage(
|
|
192
|
+
encodedChannelId,
|
|
193
|
+
normalizeMentionsForChatAdapter(sanitizeGuildContent(guildId, content))
|
|
194
|
+
)
|
|
188
195
|
return { id: result.id }
|
|
189
196
|
}),
|
|
190
197
|
pinMessage: (scope, messageId) =>
|
|
@@ -42,6 +42,7 @@ test("maps Discord messages through the chat-sdk adapter facade", async () => {
|
|
|
42
42
|
const parsed = adapter.parseMessage(withAttachment)
|
|
43
43
|
|
|
44
44
|
expect(adapter.encodeThreadId({ guildId: "g1", channelId: "c1", threadId: "t1" })).toBe("discord:g1:c1:t1")
|
|
45
|
+
expect(adapter.userName).toBe("self")
|
|
45
46
|
expect(adapter.decodeThreadId("discord:g1:c1:t1")).toEqual({ guildId: "g1", channelId: "c1", threadId: "t1" })
|
|
46
47
|
expect(adapter.channelIdFromThreadId("discord:g1:c1:t1")).toBe("c1")
|
|
47
48
|
expect(parsed.threadId).toBe("discord:g1:c1")
|
|
@@ -175,7 +175,7 @@ const unsupported = (operation: string): Promise<never> => Promise.reject(new Er
|
|
|
175
175
|
|
|
176
176
|
export const makeGatewayAdapter = (bot: BotIdentity): Adapter<DiscordScope, DiscordMessage> => ({
|
|
177
177
|
name: "discord",
|
|
178
|
-
userName:
|
|
178
|
+
userName: bot.userId,
|
|
179
179
|
botUserId: bot.userId,
|
|
180
180
|
lockScope: "thread",
|
|
181
181
|
initialize: () => Promise.resolve(),
|
|
@@ -208,7 +208,7 @@ export const makeChatGatewayIntake = (options: ChatGatewayIntakeOptions): ChatGa
|
|
|
208
208
|
const chat = new Chat({
|
|
209
209
|
adapters: { discord: adapter },
|
|
210
210
|
state: makeTransientChatState(),
|
|
211
|
-
userName:
|
|
211
|
+
userName: options.bot.userId,
|
|
212
212
|
concurrency: "concurrent",
|
|
213
213
|
dedupeTtlMs: 5 * 60 * 1000
|
|
214
214
|
})
|