cal.pub0.org/packages/app-store/slackmessaging/lib/actions/createEvent.ts

143 lines
4.3 KiB
TypeScript
Raw Normal View History

Slack App Integration (#2041) * patch applied * patch applied * We shouldn't pollute global css * Build fixes * Updates typings * WIP extracting zoom to package * Revert "Upgrades next to 12.1 (#1895)" (#1903) This reverts commit ede0e98e1f7d462fe7196c6ce0de29490c00331e. * Tweak/gitignore prisma zod (#1905) * Extracts ignored createEventTypeBaseInput * Adds postinstall script * Revert "Tweak/gitignore prisma zod (#1905)" (#1906) This reverts commit 15bfeb30d7ce22a44f6dce9a74803a97ef43e2e6. * Eslint fixes (#1898) * Eslint fixes * Docs build fixes * Upgrade to next 12.1 (#1904) * Upgrades next to 12.1 * Fixes build * Updaters e2e test pipelines Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Fix URL by removing slash and backslash (#1733) * Fix URl by removing slash and backslash * Implement slugify * Add data type * Fixing folder structure * Solve zod-utils conflict * Build fixes (#1929) * Build fixes * Fixes type error * WIP * Conflict fixes * Removes unused file * TODO * WIP * Type fixes * Linting * WIP * Moved App definition to types * WIP * WIP * WIP * WIP WIP * Renamed zoomvideo app * Import fix * Daily.co app (#2022) * Daily.co app * Update packages/app-store/dailyvideo/lib/VideoApiAdapter.ts Co-authored-by: Omar López <zomars@me.com> * Update packages/app-store/dailyvideo/lib/VideoApiAdapter.ts Co-authored-by: Omar López <zomars@me.com> * Missing deps for newly added contants to lib Co-authored-by: Omar López <zomars@me.com> * WIP * WIP * WIP * Daily fixes * Updated type info * Slack Oauth integration - api route ideas * Adds getLocationOptions * Type fixes * Adds location option for daily video * Revert "Slack Oauth integration - api route ideas" This reverts commit 35ffa78e929339c4badb98cdab4e4b953ecc7cca. * Slack Oauth + verify sig * Slack Oauth + verify sig Implementing connect slack with workspace OAuth Implemented the ability for slack to send requests on events (commands etc) - This only works if slacks signature matches with our signature * Revert "Slack Oauth + verify sig" This reverts commit ee95795e0f0ae6d06be4e0a423afb8c315d9af7d. * WIP - Signature verifiaction failure * Huddle01 migration to app store (#2038) * Jitsi Video App migration * Removing uneeded dependencies * Missed unused reference * Missing dependency `@calcom/lib` is needed in the `locationOption.ts` file * Huddle01 migration to app store * WIP: PostData for creating event * Optimising Query Vital as we only have 3 seconds max to return the response to slack. * Jitsi Video App migration (#2027) * Jitsi Video App migration * Removing uneeded dependencies * Missed unused reference * Missing dependency `@calcom/lib` is needed in the `locationOption.ts` file Co-authored-by: Omar López <zomars@me.com> * Monorepo/app store MS Teams Integration (#2080) * Create teamsvideo package * Remove zoom specific refrences * Add teams video files * Rename to office365_video * Add call back to add crednetial type office365_teams * Rename to office_video to match type * Add MS Teams as a location option * Rename files * Add teams reponse interface and create meeting * Comment out Daily imports * Add check for Teams integration * Add token checking functions * Change template to create event rather than meeting * Add comment to test between create link and event * Add teams URL to booking * Ask for just onlineMeeting permission * Add MS Teams logo * Add message to have an enterprise account * Remove comments * Comment back hasDailyIntegration * Comment back daily credentials * Update link to MS Graph section of README * Move API calls to package Co-authored-by: Omar López <zomars@me.com> * Re-adds missing module for transpiling * Adding connect button if there is on user * Adds email as required field for app store metadata * WIP: migrates tandem to app store * Cleanup * Migrates tandem api routes to app store * Fixes tandem api handlers * Big WIP WIP * Show todays bookings. * No booking message to json * Transition into modals Better UX for submitting forms. * Create Bookings - Working * Fixing /today to show today and not all upcoming * Fixing message * Build fixes * WIP * Fixes annoying circular dependency bug I've spent a whole day on this.... * Location option cleanup * Type fixes * Update EventManager.ts * Update CalendarManager.ts * Merge branch 'monorepo/app-store' into sean-monorepo-slack-oauth * Moves CalendarService back to lib * Moves apple calendar to App Store * Cleanup * Booking Success * Merge branch 'main' into sean-monorepo-slack-oauth * Restored moved file * Delete TeamRole.tsx * Undoing unrelated changes * Cleanup * Cleanup * Updates website * Delete .env.example * Update yarn.lock * Adds instructions to README * Build fixes * Uses generic app store api handler * Adds install button and cleanup * Updates .env.example * Update README.md * Renames slackapp to slackmessaing * Update InstallAppButton.tsx * Delete locationOption.ts * Type fixes * Build fixes * Links + Fixing connection issue * fixed merge conflict * fixed merge conflict * Type fixes * Update index.ts Co-authored-by: zomars <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Juan Esteban Nieto Cifuentes <89233604+Jenietoc@users.noreply.github.com> Co-authored-by: Leo Giovanetti <hello@leog.me> Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: Peer Richelsen <peer@cal.com>
2022-04-06 12:37:06 +00:00
import { WebClient } from "@slack/web-api";
import dayjs from "dayjs";
import { NextApiRequest, NextApiResponse } from "next";
import { WEBAPP_URL } from "@calcom/lib/constants";
import db from "@calcom/prisma";
import { WhereCredsEqualsId } from "../WhereCredsEqualsID";
import { getUserEmail } from "../utils";
import BookingSuccess from "../views/BookingSuccess";
// TODO: Move this type to a shared location - being used in more than one package.
export type BookingCreateBody = {
email: string;
end: string;
web3Details?: {
userWallet: string;
userSignature: unknown;
};
eventTypeId: number;
guests?: string[];
location: string;
name: string;
notes?: string;
rescheduleUid?: string;
start: string;
timeZone: string;
user?: string | string[];
language: string;
customInputs: { label: string; value: string }[];
metadata: {
[key: string]: string;
};
};
export default async function createEvent(req: NextApiRequest, res: NextApiResponse) {
const {
user,
view: {
state: { values },
},
} = JSON.parse(req.body.payload);
// This is a mess I have no idea why slack makes getting infomation this hard.
const {
eventName: {
event_name: { value: selected_name },
},
eventType: {
"create.event.type": {
selected_option: { value: selected_event_id },
},
},
selectedUsers: {
invite_users: { selected_users },
},
eventDate: {
event_date: { selected_date },
},
eventTime: {
event_start_time: { selected_time },
},
} = values;
// Im sure this query can be made more efficient... The JSON filtering wouldnt work when doing it directly on user.
const foundUser = await db.credential
.findFirst({
rejectOnNotFound: true,
...WhereCredsEqualsId(user.id),
})
.user({
select: {
username: true,
email: true,
timeZone: true,
locale: true,
eventTypes: {
where: {
id: parseInt(selected_event_id),
},
select: {
id: true,
length: true,
locations: true,
},
},
credentials: {
...WhereCredsEqualsId(user.id),
},
},
});
const slackCredentials = foundUser?.credentials[0].key; // Only one slack credential for user
// @ts-ignore access_token must exist on slackCredentials otherwise we have wouldnt have reached this endpoint
const access_token = slackCredentials?.access_token;
// https://api.slack.com/authentication/best-practices#verifying since we verify the request is coming from slack we can store the access_token in the DB.
const client = new WebClient(access_token);
// This could get a bit weird as there is a 3 second limit until the post times ou
// Compute all users that have been selected and get their email.
const invitedGuestsEmails = selected_users.map(
async (userId: string) => await getUserEmail(client, userId)
);
const startDate = dayjs(`${selected_date} ${selected_time}`, "YYYY-MM-DD HH:mm");
const PostData: BookingCreateBody = {
start: dayjs(startDate).format(),
end: dayjs(startDate)
.add(foundUser?.eventTypes[0]?.length ?? 0, "minute")
.format(),
eventTypeId: foundUser?.eventTypes[0]?.id ?? 0,
user: foundUser?.username ?? "",
email: foundUser?.email ?? "",
name: foundUser?.username ?? "",
guests: await Promise.all(invitedGuestsEmails),
location: "inPerson", // TODO: Make this pickable in the future - defaulting to in person as any video provider that does not exist within the monorepo will crash the app.
timeZone: foundUser?.timeZone ?? "",
language: foundUser?.locale ?? "en",
customInputs: [{ label: "", value: "" }],
metadata: {},
notes: "This event was created with slack.",
};
fetch(`${WEBAPP_URL}/api/book/event`, {
method: "POST",
body: JSON.stringify(PostData),
headers: {
"Content-Type": "application/json",
},
})
.then(() => {
return res.status(200).send(""); // Slack requires a 200 to be sent to clear the modal. This makes it massive pain to update the user that the event has been created.
})
.catch(() => {
return res
.status(200)
.json({ text: "Event creation failed. Please try again", response_action: "update" });
});
}