Untitled

 avatar
unknown
plain_text
2 years ago
35 kB
4
Indexable
"use node";
import { api, internal } from "../_generated/api";
import { Doc, Id } from "../_generated/dataModel";
import { action, internalAction } from "../_generated/server";
import { PMSPlatform, SlackMultiChannelConfig } from "../types";
import { stringToNumber } from "../utils/helpers";
import SlackIntegration, {
    getSlackAccessToken,
    revokeAccessToken,
} from "./utils/slackIntegration";
import { logSlackError } from "./utils/slackLogger";

export const fetchAndStoreAccessToken = internalAction(
    async (
        { runQuery, runMutation },
        { userId, code }: { userId: string; code: string }
    ): Promise<any> => {
        const user: Doc<"users"> | null = await runQuery(
            internal.users.getByUserId,
            {
                userId: userId as Id<"users">,
            }
        );
        if (!user) throw new Error("User not found");

        const response: any = await getSlackAccessToken(code);
        const { access_token, incoming_webhook } = response;

        if (!access_token || !incoming_webhook)
            throw new Error("Invalid response from Slack");

        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            access_token
        );
        await SlackMessenger.joinChannel(incoming_webhook.channel_id);

        await runMutation(
            internal.slackIntegration.slackIntegrations.addIntegration,
            {
                userId: userId as Id<"users">,
                accessToken: access_token,
                channelId: incoming_webhook.channel_id,
                status: "on",
            }
        );
        return response;
    }
);

export const revokeAndRemoveAccessToken = action(
    async ({ runQuery, runMutation }): Promise<any> => {
        const user: Doc<"users"> | null = await runQuery(api.users.getUser);
        if (!user) throw new Error("User not found");
        const userId = user._id;

        const integration = await runQuery(
            internal.slackIntegration.slackIntegrations.getByUserId,
            {
                userId,
            }
        );

        if (!integration) throw new Error("Integration not found");

        const response: any = await revokeAccessToken(integration.accessToken);
        console.log(response);

        // turn off all listings
        await runMutation(internal.listings.turnOffChatForAllListings, {
            userId,
        });

        // clear slack channel for all listings
        await runMutation(internal.listings.clearSlackChannelIdForAllListings, {
            userId,
        });

        await runMutation(
            internal.slackIntegration.slackIntegrations.removeIntegration,
            {
                userId,
            }
        );
        return response;
    }
);

export const allocateChannelsAndUpdate = internalAction(
    async (
        { runQuery, runMutation, runAction },
        {
            userId,
            channelNameToListingIds,
        }: {
            userId: Id<"users">;
            channelNameToListingIds: SlackMultiChannelConfig;
        }
    ): Promise<{ updated: boolean }> => {
        const integration = await runQuery(
            internal.slackIntegration.slackIntegrations.getByUserId,
            {
                userId,
            }
        );
        if (!integration) return { updated: false };

        const channelNames: string[] = Object.keys(channelNameToListingIds);
        const nameToId: { [key: string]: string } | null = await runAction(
            internal.actions.slackIntegration.createChannels,
            {
                userId,
                integration,
                channelNames,
            }
        );

        if (!nameToId) return { updated: false };

        for (const channelName of channelNames) {
            const listingIds = channelNameToListingIds[channelName];
            for (const listingId of listingIds) {
                await runMutation(internal.listings.updateSlackChannelId, {
                    userId,
                    listingId,
                    slackChannelId: nameToId[channelName],
                });
            }
        }

        return { updated: true };
    }
);

export const addSingleChannelAndUpdate = action(
    async (
        { runQuery, runMutation, runAction },
        {
            channelName,
            listingIds,
        }: {
            channelName: string;
            listingIds: (string | number)[];
        }
    ): Promise<{ success: boolean }> => {
        const user = await runQuery(api.users.getUser);

        if (!user) return { success: false };

        const userId = user._id;

        const integration = await runQuery(
            internal.slackIntegration.slackIntegrations.getByUserId,
            {
                userId,
            }
        );

        if (!integration) return { success: false };

        const existingChannelNames = integration.channels;
        // if exists, fail
        if (
            existingChannelNames &&
            existingChannelNames.find(
                (channel: any) => channel.name === channelName
            )
        )
            return { success: false };

        const nameToId: { [key: string]: string } | null = await runAction(
            internal.actions.slackIntegration.createChannels,
            {
                userId,
                integration,
                channelNames: [channelName],
            }
        );

        if (!nameToId) return { success: false };

        console.log("Successfully created channel");

        await runMutation(
            internal.slackIntegration.slackIntegrations.addChannels,
            {
                userId,
                channels: [
                    {
                        id: nameToId[channelName],
                        name: channelName,
                    },
                ],
            }
        );

        for (const listingId of listingIds) {
            await runMutation(internal.listings.updateSlackChannelId, {
                userId,
                listingId,
                slackChannelId: nameToId[channelName],
            });
        }

        console.log("Successfully added channel");

        return { success: true };
    }
);

export const editSingleChannelAndUpdate = action(
    async (
        { runQuery, runMutation },
        {
            channelName,
            channelId,
            listingIds,
        }: {
            channelName: string;
            channelId: string;
            listingIds: (string | number)[];
        }
    ): Promise<{ success: boolean }> => {
        const user = await runQuery(api.users.getUser);

        if (!user) return { success: false };

        const userId = user._id;

        const integration = await runQuery(
            internal.slackIntegration.slackIntegrations.getByUserId,
            {
                userId,
            }
        );

        if (!integration) return { success: false };

        const existingChannelNames = integration.channels;

        // if doesn't exist, means its different from before so edit
        if (
            existingChannelNames &&
            existingChannelNames.find(
                (channel: any) =>
                    channel.id === channelId && channel.name !== channelName
            )
        ) {
            const SlackChannelManager: SlackIntegration = new SlackIntegration(
                userId,
                integration.accessToken
            );

            const resEdit = await SlackChannelManager.editChannelName(
                channelId,
                channelName
            );

            if (!resEdit || !resEdit.ok) return { success: false };

            await runMutation(
                internal.slackIntegration.slackIntegrations.editChannelName,
                {
                    userId,
                    channelId,
                    channelName,
                }
            );
        }

        // existing listings in channel
        const existingListingIds = await runQuery(
            internal.listings.listByUserChannelId,
            {
                userId,
                channelId,
            }
        );

        // remove channelId for listings that are not in the new listingIds
        const listingIdsToRemove = existingListingIds
            .map((listing) => listing.listingId)
            .filter(
                (listingId: number | string) => !listingIds.includes(listingId)
            );

        for (const listingIdToRemove of listingIdsToRemove) {
            await runMutation(internal.listings.updateSlackChannelId, {
                userId,
                listingId: listingIdToRemove,
                slackChannelId: "",
            });
        }

        // edit channelId for listings that are in the new listingIds
        for (const listingId of listingIds) {
            await runMutation(internal.listings.updateSlackChannelId, {
                userId,
                listingId,
                slackChannelId: channelId,
            });
        }

        return { success: true };
    }
);

export const createChannels = internalAction(
    async (
        { runQuery, runMutation },
        {
            userId,
            integration,
            channelNames,
        }: {
            userId: Id<"users">;
            integration: Doc<"slackIntegrations">;
            channelNames: string[];
        }
    ): Promise<{ [key: string]: string } | null> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        const nameToId: { [key: string]: string } = {};

        for (const name of channelNames) {
            const createdRes = await SlackMessenger.createChannel(name);
            console.log(createdRes);
            if (!createdRes || !createdRes.ok) return null;

            nameToId[name] = createdRes.channel.id;

            const users = await SlackMessenger.listUsers();
            if (!users || !users.members) return null;

            const userCommaSep = users.members
                .filter(
                    (user: any) =>
                        !user.is_bot &&
                        !user.deleted &&
                        !user.is_restricted &&
                        !user.is_ultra_restricted
                )
                .map((user: any) => user.id)
                .join(",");

            const res = await SlackMessenger.inviteToChannel(
                createdRes.channel.id,
                userCommaSep
            );
            console.log(res);

            if (!res || !res.ok) console.error(res);
        }

        if (Object.keys(nameToId).length === 0) return null;

        console.log(nameToId);

        return nameToId;
    }
);

export const sendSentReplyMessage = internalAction(
    async (
        { runQuery },
        {
            userId,
            response,
            integration,
            listing,
            conversation,
        }: {
            userId: Id<"users">;
            listing: Doc<"listings">;
            integration: Doc<"slackIntegrations">;
            conversation: Doc<"conversations">;
            response: string;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        await SlackMessenger.sendSentMessageNotification({
            basicSlackInfo: {
                channelId: listing.slackChannelId || integration.channelId,
                guestName: conversation.recipientName || "N/A",
                guestMessage: "",
                hostResponse: response,
                listingAddress: listing.address,
                listingCity: listing.city || "",
                listingImageUrl: listing.listingImage.url,
            },
        });
    }
);

export const sendAutopilotMessage = internalAction(
    async (
        { scheduler },
        {
            userId,
            integration,
            autopilotSetting,
            hours,
        }: {
            userId: Id<"users">;
            integration: Doc<"slackIntegrations">;
            autopilotSetting: "on" | "off";
            hours: number;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        const res = await SlackMessenger.sendAutopilotNotification({
            channelId: integration.channelId,
            autopilotSetting,
            hours,
        });
        const {
            message: { ts },
        } = res;

        if (!ts) return;

        const hoursToMs = hours * 60 * 60 * 1000;
        const expireTime = hoursToMs || 30 * 1000;
        await scheduler.runAfter(
            expireTime,
            internal.actions.slackIntegration.removeMessage,
            {
                userId,
                integration,
                ts,
            }
        );
    }
);

export const removeMessage = internalAction(
    async (
        {},
        {
            integration,
            userId,
            ts,
        }: {
            userId: Id<"users">;
            integration: Doc<"slackIntegrations">;
            ts: string;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        await SlackMessenger.deleteMessage(integration.channelId, ts);
    }
);

export const queueTrainingModeMessage = internalAction(
    async (
        { runMutation },
        {
            userId,
            listingSlackChannelId,
            integration,
            conversation,
            listing,
            combinedMessage,
            combinedResponse,
            lastMessageId,
        }: {
            userId: Id<"users">;
            listingSlackChannelId: string | undefined;
            integration: Doc<"slackIntegrations">;
            conversation: Doc<"conversations">;
            listing: Doc<"listings">;
            combinedMessage: string;
            combinedResponse: string;
            lastMessageId: string | number;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        const response: any = await SlackMessenger.queueTrainingModeMessage({
            userId,
            conversationId: conversation.conversationId.toString(),
            messageId: lastMessageId.toString(),
            basicSlackInfo: {
                channelId: listingSlackChannelId || integration.channelId,
                guestName: conversation.recipientName || "N/A",
                guestMessage: combinedMessage,
                listingAddress: listing.address,
                listingCity: listing.city || "",
                listingImageUrl: listing.listingImage.url,
                hostResponse: combinedResponse,
            },
        });

        if (!response.ok) {
            return;
        }

        const { message } = response;

        await runMutation(
            internal.slackIntegration.slackMessageQueue.addMessage,
            {
                userId,
                conversationId: conversation.conversationId,
                listingId: listing.listingId,
                pmsPlatform: conversation.pmsPlatform as PMSPlatform,
                lastMessageId,
                guestMessage: combinedMessage,
                hostResponse: combinedResponse,
                slackTs: message.ts,
                channelId: listingSlackChannelId || integration.channelId,
            }
        );
    }
);

export const queueUrgentMessage = internalAction(
    async (
        { runMutation },
        {
            userId,
            lastMessageId,
            integration,
            conversation,
            listing,
            combinedMessage,
        }: {
            userId: Id<"users">;
            lastMessageId: string | number;
            integration: Doc<"slackIntegrations">;
            conversation: Doc<"conversations">;
            listing: Doc<"listings">;
            combinedMessage: string;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        const response: any = await SlackMessenger.queueUrgentMessage({
            userId,
            conversationId: conversation.conversationId.toString(),
            messageId: lastMessageId.toString(),
            basicSlackInfo: {
                channelId: listing.slackChannelId || integration.channelId,
                guestName: conversation.recipientName || "N/A",
                guestMessage: combinedMessage,
                listingAddress: listing.address,
                listingCity: listing.city || "",
                listingImageUrl: listing.listingImage.url,
            },
        });

        if (!response.ok) {
            return;
        }

        const { message } = response;
        await runMutation(
            internal.slackIntegration.slackMessageQueue.addMessage,
            {
                userId,
                conversationId: conversation.conversationId,
                pmsPlatform: conversation.pmsPlatform as PMSPlatform,
                listingId: listing.listingId,
                lastMessageId,
                guestMessage: combinedMessage,
                slackTs: message.ts,
                channelId: listing.slackChannelId || integration.channelId,
            }
        );
    }
);

export const expireMessage = internalAction(
    async (
        { runMutation, runQuery },
        {
            userId,
            lastMessageId,
            listing,
            integration,
            conversation,
        }: {
            userId: Id<"users">;
            lastMessageId: string | number;
            listing: Doc<"listings">;
            integration: Doc<"slackIntegrations">;
            conversation: Doc<"conversations">;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        const slackMessage = await runQuery(
            internal.slackIntegration.slackMessageQueue
                .getByUserConversationMessageId,
            {
                userId,
                conversationId: conversation.conversationId,
                messageId: lastMessageId,
            }
        );

        if (!slackMessage) return;

        await SlackMessenger.deleteMessage(
            listing.slackChannelId || integration.channelId,
            slackMessage.slackTs
        );

        await runMutation(internal.slackIntegration.slackMessageQueue.remove, {
            _id: slackMessage._id,
        });

        // remove all previous messages from queue and slack that are older than this message in the same conversation
        const allMessages = await runQuery(
            internal.slackIntegration.slackMessageQueue
                .listPastByUserConversationId,
            {
                userId,
                conversationId: conversation.conversationId,
                creationTime: slackMessage._creationTime,
            }
        );

        for (let i = 0; i < allMessages.length; i++) {
            await SlackMessenger.deleteMessage(
                listing.slackChannelId || integration.channelId,
                allMessages[i].slackTs
            );

            await runMutation(
                internal.slackIntegration.slackMessageQueue.remove,
                {
                    _id: allMessages[i]._id,
                }
            );
        }
    }
);

export const sendErrorMessage = internalAction(
    async (
        {},
        {
            userId,
            conversation,
            listing,
            hostResponse,
            integration,
        }: {
            userId: Id<"users">;
            conversation: Doc<"conversations">;
            listing: Doc<"listings">;
            integration: Doc<"slackIntegrations">;
            hostResponse: string;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        await SlackMessenger.sendErrorMessageNotification({
            guestName: conversation.recipientName || "N/A",
            hostResponse,
            channelId: listing.slackChannelId || integration.channelId,
        });
    }
);

export const sendMessageNotification = internalAction(
    async (
        {},
        {
            userId,
            listing,
            conversation,
            combinedMessage,
            urgency,
            integration,
        }: {
            userId: Id<"users">;
            listing: Doc<"listings">;
            conversation: Doc<"conversations">;
            combinedMessage: string;
            urgency: "not urgent" | "urgent";
            integration: Doc<"slackIntegrations">;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );
        const textUrgency = urgency === "not urgent" ? "Not Urgent" : "Urgent";

        await SlackMessenger.sendGuestMessageNotification({
            urgency: textUrgency,
            basicSlackInfo: {
                channelId: listing.slackChannelId || integration.channelId,
                guestName: conversation.recipientName || "N/A",
                guestMessage: combinedMessage,
                listingAddress: listing.address,
                listingCity: listing.city || "",
                listingImageUrl: listing.listingImage.url,
            },
        });
    }
);

export const sendUrgentResponseNotification = internalAction(
    async (
        {},
        {
            dhours,
            dmins,
            userId,
            guestMessage,
            response,
            integration,
            listing,
            conversation,
        }: {
            dhours: number;
            dmins: number;
            userId: Id<"users">;
            guestMessage: string;
            listing: Doc<"listings">;
            integration: Doc<"slackIntegrations">;
            conversation: Doc<"conversations">;
            response: string;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        await SlackMessenger.sendUrgentResponseNotification({
            dhours,
            dmins,
            basicSlackInfo: {
                channelId: integration.channelId,
                guestName: conversation.recipientName || "N/A",
                guestMessage: guestMessage,
                hostResponse: response,
                listingAddress: listing.address,
                listingCity: listing.city || "",
                listingImageUrl: listing.listingImage.url,
            },
        });
    }
);

export const sendReservationModificationNotification = internalAction(
    async (
        {},
        {
            userId,
            listing,
            conversation,
            combinedMessage,
            integration,
        }: {
            userId: Id<"users">;
            listing: Doc<"listings">;
            conversation: Doc<"conversations">;
            combinedMessage: string;
            integration: Doc<"slackIntegrations">;
        }
    ): Promise<any> => {
        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );
        await SlackMessenger.sendReservationModificationRequestNotification({
            basicSlackInfo: {
                channelId: listing.slackChannelId || integration.channelId,
                guestName: conversation.recipientName || "N/A",
                guestMessage: combinedMessage,
                listingAddress: listing.address,
                listingCity: listing.city || "",
                listingImageUrl: listing.listingImage.url,
            },
        });
    }
);

export const processPayloadAction = internalAction(
    async (
        { runQuery, runAction, scheduler },
        {
            payload,
        }: {
            payload: any;
        }
    ): Promise<any> => {
        const { value } = payload.actions[0];
        const [userId, conversationId, messageId, action] = value.split(";");
        console.log(action);

        const queueItem = await runQuery(
            internal.slackIntegration.slackMessageQueue
                .getByUserConversationMessageId,
            {
                userId,
                conversationId: stringToNumber(conversationId),
                messageId: stringToNumber(messageId),
            }
        );

        const integration = await runQuery(
            internal.slackIntegration.slackIntegrations.getByUserId,
            {
                userId,
            }
        );

        if (!queueItem || !integration) return;

        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        const listing = await runQuery(
            internal.listings.getByUserAndListingId,
            {
                userId,
                listingId: queueItem.listingId,
            }
        );
        const conversation = await runQuery(api.conversations.getById, {
            userId,
            conversationId: queueItem.conversationId,
        });

        if (!listing || !conversation) return;

        const {
            address: listingAddress,
            listingImage: { url: listingImageUrl },
        } = listing;

        const { recipientName: guestName } = conversation;

        // Handle training mode message
        if (
            (action === "approve" || action === "reject") &&
            queueItem.hostResponse
        ) {
            const {
                pmsPlatform,
                hostResponse,
                slackTs,
                channelId,
                guestMessage,
            } = queueItem;

            let sent: boolean = false;

            // send message
            if (action === "approve") {
                sent = await runAction(
                    internal.actions.messages.sendMessageInternal,
                    {
                        userId,
                        message: hostResponse,
                        conversationId: stringToNumber(conversationId),
                        pmsPlatform: pmsPlatform as PMSPlatform,
                        generated: true,
                    }
                );
            }
            // update slack message
            await SlackMessenger.updateTrainingModeMessage({
                ts: slackTs,
                basicSlackInfo: {
                    channelId,
                    guestName: guestName || "N/A",
                    guestMessage,
                    hostResponse,
                    listingAddress,
                    listingCity: listing.city || "",
                    listingImageUrl,
                },
                isApproved: action === "approve",
                isReply: false,
            });

            // remove from queue
            // await scheduler.runAfter(
            //     0,
            //     internal.slackIntegration.slackMessageQueue.remove,
            //     {
            //         _id: queueItem._id,
            //     }
            // );

            // schedule to expire message after 10 seconds
            await scheduler.runAfter(
                10 * 1000,
                internal.actions.slackIntegration.expireMessage,
                {
                    userId,
                    listing,
                    lastMessageId: stringToNumber(messageId),
                    integration,
                    conversation,
                }
            );
        }

        // maybe we can optimize this a bit more to pop modal earlier
        if (action === "reject_and_reply" || action === "urgent") {
            await SlackMessenger.openModal({
                triggerId: payload.trigger_id,
                basicSlackInfo: {
                    channelId: listing.slackChannelId || integration.channelId,
                    guestName: guestName || "N/A",
                    hostResponse: queueItem.hostResponse || "",
                    guestMessage: queueItem.guestMessage,
                    listingAddress,
                    listingCity: listing.city || "",
                    listingImageUrl,
                },
                value,
            });
        }

        await scheduler.runAfter(
            1000,
            internal.trainingModeMessages.addByUserId,
            {
                userId,
                item: {
                    pmsPlatform: conversation.pmsPlatform as PMSPlatform,
                    conversationId,
                    body: queueItem.hostResponse as string,
                    approvalStatus:
                        action === "approve" ? "approved" : "rejected",
                },
            }
        );
    }
);

export const processPayloadView = internalAction(
    async (
        { runQuery, runAction, scheduler },
        {
            payload,
        }: {
            payload: any;
        }
    ): Promise<any> => {
        const {
            private_metadata,
            state: {
                values: {
                    input_block: {
                        plain_text_input_action: { value: hostResponse },
                    },
                },
            },
        } = payload.view;
        const [userId, conversationId, messageId, action] =
            private_metadata.split(";");
        console.log(action);

        const queueItem = await runQuery(
            internal.slackIntegration.slackMessageQueue
                .getByUserConversationMessageId,
            {
                userId,
                conversationId: stringToNumber(conversationId),
                messageId: stringToNumber(messageId),
            }
        );

        const integration = await runQuery(
            internal.slackIntegration.slackIntegrations.getByUserId,
            {
                userId,
            }
        );

        if (!queueItem || !integration) return;

        const SlackMessenger: SlackIntegration = new SlackIntegration(
            userId,
            integration.accessToken
        );

        const listing = await runQuery(
            internal.listings.getByUserAndListingId,
            {
                userId,
                listingId: queueItem.listingId,
            }
        );
        const conversation = await runQuery(api.conversations.getById, {
            userId,
            conversationId: queueItem.conversationId,
        });

        if (!listing || !conversation) return;

        const {
            address: listingAddress,
            listingImage: { url: listingImageUrl },
        } = listing;

        const { recipientName: guestName } = conversation;

        const { pmsPlatform, slackTs, channelId, guestMessage } = queueItem;

        if (action === "reject_and_reply" || action === "urgent") {
            const sent: boolean = await runAction(
                internal.actions.messages.sendMessageInternal,
                {
                    userId,
                    message: hostResponse,
                    conversationId: stringToNumber(conversationId),
                    pmsPlatform: pmsPlatform as PMSPlatform,
                    generated: false,
                }
            );

            if (action === "urgent") {
                // update slack message
                await SlackMessenger.updateUrgentMessage({
                    ts: slackTs,
                    basicSlackInfo: {
                        channelId,
                        guestName: guestName || "N/A",
                        guestMessage,
                        hostResponse,
                        listingCity: listing.city || "",
                        listingAddress,
                        listingImageUrl,
                    },
                    sent,
                });
            } else {
                await SlackMessenger.updateTrainingModeMessage({
                    ts: slackTs,
                    basicSlackInfo: {
                        channelId,
                        guestName: guestName || "N/A",
                        guestMessage,
                        hostResponse,
                        listingAddress,
                        listingCity: listing.city || "",
                        listingImageUrl,
                    },
                    isApproved: false,
                    isReply: true,
                });
            }

            // remove from queue
            // await scheduler.runAfter(
            //     0,
            //     internal.slackIntegration.slackMessageQueue.remove,
            //     {
            //         _id: queueItem._id,
            //     }
            // );

            // schedule to expire message after 10 seconds
            await scheduler.runAfter(
                10 * 1000,
                internal.actions.slackIntegration.expireMessage,
                {
                    userId,
                    listing,
                    lastMessageId: stringToNumber(messageId),
                    integration,
                    conversation,
                }
            );
        }
    }
);

export const processSlashCommand = internalAction(
    async (
        { runQuery, runAction, runMutation },
        {
            body,
        }: {
            body: string;
        }
    ): Promise<string> => {
        const params = new URLSearchParams(body);
        const command: string | null = params.get("command");

        if (!command) return "Error: Please try again";

        switch (command) {
            case "/on_autopilot":
            case "/off_autopilot":
                const channelId = params.get("channel_id");
                if (!channelId) return "Error: Channel not found";

                let hours = Number(params.get("text"));
                hours = isNaN(hours) ? 0 : hours;

                const integration = await runQuery(
                    internal.slackIntegration.slackIntegrations.getByChannelId,
                    {
                        channelId,
                    }
                );

                if (!integration) return "Error: Integration not found";

                await runMutation(internal.aiSettings.switchAutopilot, {
                    userId: integration.userId,
                    on: command === "/on_autopilot" ? true : false,
                    hours,
                    slackIntegration: integration,
                });

                return "Success: Autopilot mode has been turned " + command;
            default:
                return "Default case processed";
        }
    }
);
Editor is loading...
Leave a Comment