calcom/packages/app-store/slackmessaging/lib/actions/createEvent.ts
sean-brydon 02dbb88e6b
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 ede0e98e1f.

* Tweak/gitignore prisma zod (#1905)

* Extracts ignored createEventTypeBaseInput

* Adds postinstall script

* Revert "Tweak/gitignore prisma zod (#1905)" (#1906)

This reverts commit 15bfeb30d7.

* 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

142 lines
4.3 KiB
TypeScript

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" });
});
}