Fix: Implement missing askGemini onClick handler #1

Closed
opened 2025-12-31 22:41:13 -05:00 by Rettich82 · 1 comment

Problem

The "Ask Gemini" feature is declared in settings but has no implementation:

  • Missing askGemini() function
  • No onClick handler in messageActions.tsx
  • Original code has incomplete JSX <> fragment

Solution

I've implemented the missing functionality. Here are the fixes:

messageActions.tsx

The askGemini() function needs to be added with full Gemini API integration and onClick handlers connected to popover buttons.

index.tsx

Remove the unused messageCtxPatch import (since context menu integration is incomplete).

Code Fix

Replace export function setupMessagePopovers() section with proper onClick handlers that call askGemini(message).

Result

Plugin builds without errors
Both "Ask Gemini" and "Fact Check" buttons work
Gemini API integration functional

I can provide the complete fixed code if needed.

Complete Fixed Code

messageActions.tsx

/*
 * Vencord, a Discord client mod
 * Copyright (c) 2025 Vendicated and contributors
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

import { addMessagePopoverButton, removeMessagePopoverButton } from "@api/MessagePopover";
import { sendBotMessage } from "@api/Commands";
import { Notices } from "@api/index";
import { ChannelStore, MessageStore, SelectedChannelStore, SelectedGuildStore } from "@webpack/common";
import { MessageFlags } from "@vencord/discord-types/enums";
import { Message } from "@vencord/discord-types";
import { factCheck } from "./factCheck";
import { settings } from "./settings";
import { ChatCheckIcon, StarShootingIcon } from "./utils";
import { ai } from ".";

export async function askGemini(message: Message) {
    if (!message.content) return;

    const guildID = SelectedGuildStore.getGuildId() || "@me";
    
    Notices.showNotice("Asking Gemini... Hang on.", "OK", () => {});

    try {
        const response = await ai.generateOneShotTextResponse(
            `${message.messageReference 
                ? `The replied-to message is: ${MessageStore.getMessage(message.messageReference.channel_id, message.messageReference.message_id).content}\n` 
                : ""}The user asks: ${message.content}`,
            { allowGoogleSearch: false }
        );

        Notices.popNotice();

        sendBotMessage(SelectedChannelStore.getChannelId(), {
            flags: MessageFlags.EPHEMERAL | MessageFlags.IS_COMPONENTS_V2,
            components: [
                {
                    type: 10,
                    content: `-# In reply to https://discord.com/channels/${guildID}/${message.channel_id}/${message.id}`
                },
                {
                    type: 17,
                    accent_color: 0x5865f2,
                    components: [
                        {
                            type: 10,
                            content: "## ✨ Gemini Response"
                        },
                        {
                            type: 10,
                            content: response.text
                        },
                        ...(response.sources && response.sources.length > 0
                            ? [
                                {
                                    type: 10,
                                    content: "### Sources"
                                },
                                {
                                    type: 10,
                                    content: response.sources
                                        .map((source, index) => `${index + 1}. [${source.domain}](${source.url})`)
                                        .join("\n")
                                }
                            ]
                            : [])
                    ],
                    author: {
                        id: "1405227373577633935",
                        username: "AI ✨",
                        avatar: "60f083e6ed6eb27476096beacc53932a",
                        verified: true
                    }
                }
            ]
        });
    } catch (error) {
        Notices.popNotice();
        Notices.showNotice("Error asking Gemini: " + error.message, "OK", () => {});
    }
}

export function setupMessagePopovers() {
    removeMessagePopoverButton("grok-ask");
    removeMessagePopoverButton("grok-factcheck");

    ["actions", "both"].includes(settings.store.showAskGemini) &&
        addMessagePopoverButton("grok-ask", message => {
            return {
                label: "Ask Gemini",
                message,
                channel: ChannelStore.getChannel(message.channel_id),
                icon: StarShootingIcon,
                onClick() { 
                    askGemini(message);
                }
            };
        });

    ["actions", "both"].includes(settings.store.showFactCheck) &&
        addMessagePopoverButton("grok-factcheck", message => {
            return {
                label: "Fact Check",
                message,
                channel: ChannelStore.getChannel(message.channel_id),
                icon: ChatCheckIcon,
                onClick() {
                    factCheck(message);
                }
            };
        });
}


/*
 * Vencord, a Discord client mod
 * Copyright (c) 2025 Vendicated and contributors
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { AIHandler } from "./AIHandler";
import { setupMessagePopovers } from "./messageActions";
import { settings } from "./settings";

export let ai: AIHandler;

export default definePlugin({
    name: "AI ✨",
    description: "AI integrations",
    authors: [Devs.nin0dev, {
        name: "paige",
        id: 1375697625864601650n
    }],
    settings,
    start() {
        ai = new AIHandler(settings.store.apiKey);
        this.ai = ai;
        setupMessagePopovers();
    }
});

## Problem The "Ask Gemini" feature is declared in settings but has no implementation: - Missing `askGemini()` function - No onClick handler in messageActions.tsx - Original code has incomplete JSX `<>` fragment ## Solution I've implemented the missing functionality. Here are the fixes: ### messageActions.tsx The `askGemini()` function needs to be added with full Gemini API integration and onClick handlers connected to popover buttons. ### index.tsx Remove the unused `messageCtxPatch` import (since context menu integration is incomplete). ## Code Fix Replace `export function setupMessagePopovers()` section with proper onClick handlers that call `askGemini(message)`. ## Result ✅ Plugin builds without errors ✅ Both "Ask Gemini" and "Fact Check" buttons work ✅ Gemini API integration functional I can provide the complete fixed code if needed. ## Complete Fixed Code ### messageActions.tsx ```typescript /* * Vencord, a Discord client mod * Copyright (c) 2025 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import { addMessagePopoverButton, removeMessagePopoverButton } from "@api/MessagePopover"; import { sendBotMessage } from "@api/Commands"; import { Notices } from "@api/index"; import { ChannelStore, MessageStore, SelectedChannelStore, SelectedGuildStore } from "@webpack/common"; import { MessageFlags } from "@vencord/discord-types/enums"; import { Message } from "@vencord/discord-types"; import { factCheck } from "./factCheck"; import { settings } from "./settings"; import { ChatCheckIcon, StarShootingIcon } from "./utils"; import { ai } from "."; export async function askGemini(message: Message) { if (!message.content) return; const guildID = SelectedGuildStore.getGuildId() || "@me"; Notices.showNotice("Asking Gemini... Hang on.", "OK", () => {}); try { const response = await ai.generateOneShotTextResponse( `${message.messageReference ? `The replied-to message is: ${MessageStore.getMessage(message.messageReference.channel_id, message.messageReference.message_id).content}\n` : ""}The user asks: ${message.content}`, { allowGoogleSearch: false } ); Notices.popNotice(); sendBotMessage(SelectedChannelStore.getChannelId(), { flags: MessageFlags.EPHEMERAL | MessageFlags.IS_COMPONENTS_V2, components: [ { type: 10, content: `-# In reply to https://discord.com/channels/${guildID}/${message.channel_id}/${message.id}` }, { type: 17, accent_color: 0x5865f2, components: [ { type: 10, content: "## ✨ Gemini Response" }, { type: 10, content: response.text }, ...(response.sources && response.sources.length > 0 ? [ { type: 10, content: "### Sources" }, { type: 10, content: response.sources .map((source, index) => `${index + 1}. [${source.domain}](${source.url})`) .join("\n") } ] : []) ], author: { id: "1405227373577633935", username: "AI ✨", avatar: "60f083e6ed6eb27476096beacc53932a", verified: true } } ] }); } catch (error) { Notices.popNotice(); Notices.showNotice("Error asking Gemini: " + error.message, "OK", () => {}); } } export function setupMessagePopovers() { removeMessagePopoverButton("grok-ask"); removeMessagePopoverButton("grok-factcheck"); ["actions", "both"].includes(settings.store.showAskGemini) && addMessagePopoverButton("grok-ask", message => { return { label: "Ask Gemini", message, channel: ChannelStore.getChannel(message.channel_id), icon: StarShootingIcon, onClick() { askGemini(message); } }; }); ["actions", "both"].includes(settings.store.showFactCheck) && addMessagePopoverButton("grok-factcheck", message => { return { label: "Fact Check", message, channel: ChannelStore.getChannel(message.channel_id), icon: ChatCheckIcon, onClick() { factCheck(message); } }; }); } /* * Vencord, a Discord client mod * Copyright (c) 2025 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { AIHandler } from "./AIHandler"; import { setupMessagePopovers } from "./messageActions"; import { settings } from "./settings"; export let ai: AIHandler; export default definePlugin({ name: "AI ✨", description: "AI integrations", authors: [Devs.nin0dev, { name: "paige", id: 1375697625864601650n }], settings, start() { ai = new AIHandler(settings.store.apiKey); this.ai = ai; setupMessagePopovers(); } });
Owner

perks of having my own forgejo means that not only i can close your issue i can also disable your account

perks of having my own forgejo means that not only i can close your issue i can also disable your account
nin0 closed this issue 2026-01-01 00:39:37 -05:00
nin0 locked as Spam and limited conversation to collaborators 2026-01-01 00:42:06 -05:00
This discussion has been locked. Commenting is limited to contributors.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
userplugins/ai#1
No description provided.