Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Zoho Calendar #10429

Merged
merged 54 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
68ab3bf
feat: add zoho calendar
murtajaziad Apr 8, 2023
3d7a699
remove log.debug
murtajaziad Apr 8, 2023
8a51e76
Merge branch 'main' into app/zohocalendar
murtajaziad Apr 8, 2023
c64440e
fix types
murtajaziad Apr 8, 2023
3d8c819
lint
murtajaziad Apr 8, 2023
9ee3b12
fix types and lint
murtajaziad Apr 8, 2023
6b861fd
lint
murtajaziad Apr 8, 2023
b046b4e
Apply suggestions from code review
hariombalhara Apr 19, 2023
e6c3772
Make changes to comply with new app structure - followed by app-store…
hariombalhara Apr 19, 2023
10bf10d
Add dead import
hariombalhara Apr 19, 2023
d56a491
Merge remote-tracking branch 'origin/main' into app/zohocalendar
hariombalhara Apr 19, 2023
a91e12f
More cleanup
hariombalhara Apr 19, 2023
2cfc402
Use slug as dirName if not explicilty set
hariombalhara Apr 19, 2023
62c38e9
Added instructions for obtaining Zoho Calendar Client ID and Secret
murtajaziad May 1, 2023
0e65ec8
Merge remote-tracking branch 'origin/main' into app/zohocalendar
hariombalhara May 10, 2023
86c235f
Reuse code
hariombalhara May 10, 2023
249b54c
Fix TS error
hariombalhara May 11, 2023
29e7384
Merge remote-tracking branch 'origin/main' into app/zohocalendar
hariombalhara May 11, 2023
37518ee
fix missing title and missing uemail
murtajaziad Jun 22, 2023
5935818
Merge branch 'main' into app/zohocalendar
alannnc Jun 27, 2023
735d9bf
Fixing app seed, event start end time on zoho app missmatch and fetch…
alannnc Jun 28, 2023
436020e
Merge branch 'main' into app/zohocalendar
alannnc Jun 28, 2023
0451429
Merge branch 'main' into app/zohocalendar
alannnc Jun 28, 2023
0788823
Merge branch 'main' into app/zohocalendar
alannnc Jun 29, 2023
6ce4754
Adjust CalendarService to match code style
alannnc Jun 29, 2023
1cb5334
Merge branch 'main' into app/zohocalendar
joeauyeung Jul 6, 2023
2d03b43
Callback use app keys schema
joeauyeung Jul 18, 2023
86e00c6
Merge branch 'main' into app/zohocalendar
joeauyeung Jul 18, 2023
387b106
add required etag to edit & delete
murtajaziad Jul 27, 2023
e78349d
Merge branch 'calcom:app/zohocalendar' into app/zohocalendar
murtajaziad Jul 27, 2023
f0fa4c5
Merge branch 'main' into app/zohocalendar
joeauyeung Aug 16, 2023
72df29c
Merge branch 'main' into app/zohocalendar
joeauyeung Aug 17, 2023
76b8022
Merge branch 'main' into app/zohocalendar
joeauyeung Aug 21, 2023
fd932f2
use utc plugin for zohocalendar busyData
murtajaziad Aug 23, 2023
a508476
Merge branch 'main' into app/zohocalendar
joeauyeung Aug 23, 2023
72bad32
get zohocalendar availability for more than 31days
murtajaziad Aug 24, 2023
757e82f
Merge branch 'main' into app/zohocalendar
joeauyeung Sep 6, 2023
6c571e1
Merge branch 'main' into app/zohocalendar
joeauyeung Sep 7, 2023
39589eb
Merge branch 'main' into app/zohocalendar
PeerRich Sep 10, 2023
6d1eed5
Merge branch 'main' into app/zohocalendar
PeerRich Sep 10, 2023
688a36a
Merge branch 'main' into app/zohocalendar
PeerRich Sep 11, 2023
18648d3
fix destination calendar id getting from event
murtajaziad Sep 11, 2023
47a6eab
Merge branch 'main' into app/zohocalendar
aar2dee2 Sep 15, 2023
f817f2c
Merge branch 'main' into app/zohocalendar
aar2dee2 Sep 15, 2023
155ac84
update description, use separate env vars
aar2dee2 Sep 15, 2023
e590480
update readme
aar2dee2 Sep 17, 2023
442f403
Update turbo.json
aar2dee2 Sep 18, 2023
42a69ca
Update .env.appStore.example
aar2dee2 Sep 18, 2023
f500196
revert seed app-store
aar2dee2 Sep 18, 2023
08d3036
Merge branch 'main' into app/zohocalendar
aar2dee2 Sep 18, 2023
f527ae9
use createOAuthAppCredential
murtajaziad Sep 21, 2023
f539632
images change & add
murtajaziad Sep 21, 2023
5167226
extract oauth base url to variable
murtajaziad Sep 21, 2023
d134691
Update packages/app-store/zohocalendar/api/callback.ts
hariombalhara Sep 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .env.appStore.example
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,9 @@ SALESFORCE_CONSUMER_SECRET=""
ZOHOCRM_CLIENT_ID=""
ZOHOCRM_CLIENT_SECRET=""

# - ZOHOCALENDAR
# Used for the Zoho Calendar integration
ZOHOCALENDAR_CLIENT_ID=""
ZOHOCALENDAR_CLIENT_SECRET=""
aar2dee2 marked this conversation as resolved.
Show resolved Hide resolved
aar2dee2 marked this conversation as resolved.
Show resolved Hide resolved

# *********************************************************************************************************
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,9 @@ For example, `Cal.com (support@cal.com)`.
9. Click the "Save"/ "UPDATE" button at the bottom footer.
10. You're good to go. Now you can easily add your ZohoCRM integration in the Cal.com settings.

### Obtaining Zoho Calendar Client ID and Secret

[Follow these steps](./packages/app-store/zohocalendar/)
### Obtaining Zoho Bigin Client ID and Secret

[Follow these steps](./packages/app-store/zoho-bigin/)
Expand Down
2 changes: 2 additions & 0 deletions packages/app-store/apps.keys-schemas.generated.ts
joeauyeung marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { appKeysSchema as webex_zod_ts } from "./webex/zod";
import { appKeysSchema as wordpress_zod_ts } from "./wordpress/zod";
import { appKeysSchema as zapier_zod_ts } from "./zapier/zod";
import { appKeysSchema as zoho_bigin_zod_ts } from "./zoho-bigin/zod";
import { appKeysSchema as zohocalendar_zod_ts } from "./zohocalendar/zod";
import { appKeysSchema as zohocrm_zod_ts } from "./zohocrm/zod";
import { appKeysSchema as zoomvideo_zod_ts } from "./zoomvideo/zod";

Expand Down Expand Up @@ -62,6 +63,7 @@ export const appKeysSchemas = {
wordpress: wordpress_zod_ts,
zapier: zapier_zod_ts,
"zoho-bigin": zoho_bigin_zod_ts,
zohocalendar: zohocalendar_zod_ts,
zohocrm: zohocrm_zod_ts,
zoomvideo: zoomvideo_zod_ts,
};
2 changes: 2 additions & 0 deletions packages/app-store/apps.metadata.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import { metadata as wipemycalother__metadata_ts } from "./wipemycalother/_metad
import wordpress_config_json from "./wordpress/config.json";
import { metadata as zapier__metadata_ts } from "./zapier/_metadata";
import zoho_bigin_config_json from "./zoho-bigin/config.json";
import zohocalendar_config_json from "./zohocalendar/config.json";
import zohocrm_config_json from "./zohocrm/config.json";
import { metadata as zoomvideo__metadata_ts } from "./zoomvideo/_metadata";

Expand Down Expand Up @@ -142,6 +143,7 @@ export const appStoreMetadata = {
wordpress: wordpress_config_json,
zapier: zapier__metadata_ts,
"zoho-bigin": zoho_bigin_config_json,
zohocalendar: zohocalendar_config_json,
zohocrm: zohocrm_config_json,
zoomvideo: zoomvideo__metadata_ts,
};
2 changes: 2 additions & 0 deletions packages/app-store/apps.schemas.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { appDataSchema as webex_zod_ts } from "./webex/zod";
import { appDataSchema as wordpress_zod_ts } from "./wordpress/zod";
import { appDataSchema as zapier_zod_ts } from "./zapier/zod";
import { appDataSchema as zoho_bigin_zod_ts } from "./zoho-bigin/zod";
import { appDataSchema as zohocalendar_zod_ts } from "./zohocalendar/zod";
import { appDataSchema as zohocrm_zod_ts } from "./zohocrm/zod";
import { appDataSchema as zoomvideo_zod_ts } from "./zoomvideo/zod";

Expand Down Expand Up @@ -62,6 +63,7 @@ export const appDataSchemas = {
wordpress: wordpress_zod_ts,
zapier: zapier_zod_ts,
"zoho-bigin": zoho_bigin_zod_ts,
zohocalendar: zohocalendar_zod_ts,
zohocrm: zohocrm_zod_ts,
zoomvideo: zoomvideo_zod_ts,
};
1 change: 1 addition & 0 deletions packages/app-store/apps.server.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const apiHandlers = {
wordpress: import("./wordpress/api"),
zapier: import("./zapier/api"),
"zoho-bigin": import("./zoho-bigin/api"),
zohocalendar: import("./zohocalendar/api"),
zohocrm: import("./zohocrm/api"),
zoomvideo: import("./zoomvideo/api"),
};
1 change: 1 addition & 0 deletions packages/app-store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const appStore = {
exchangecalendar: () => import("./exchangecalendar"),
facetime: () => import("./facetime"),
sylapsvideo: () => import("./sylapsvideo"),
zohocalendar: () => import("./zohocalendar"),
"zoho-bigin": () => import("./zoho-bigin"),
basecamp3: () => import("./basecamp3"),
telegramvideo: () => import("./telegram"),
Expand Down
6 changes: 6 additions & 0 deletions packages/app-store/zohocalendar/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
items:
- ZCal1.jpg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add more screenshots. We can show installation steps, if needed.
See other calendar apps for reference

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

---

Zoho Calendar is an online business calendar that makes scheduling easy for you. Use this app to sync your Cal bookings with your Zoho Calendar.
14 changes: 14 additions & 0 deletions packages/app-store/zohocalendar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Zoho Calendar

### Obtaining Zoho Calendar Client ID and Secret

1. Open [Zoho API Console](https://api-console.zoho.com/) and sign into your account, or create a new one.
2. From within the API console page, go to "Applications".
3. Click "ADD CLIENT" button top right and select "Server-based Applications".
4. Fill in any information you want in the "Client Details" tab
5. Go to tab "Client Secret" tab.
6. Now copy the Client ID and Client Secret into your app keys in the Cal.com admin panel (`<Cal.com>/settings/admin/apps`).
7. Back in Zoho API Console, set the Redirect URL for OAuth `<Cal.com URL>/api/integrations/zohocalendar/callback` replacing Cal.com URL with the URI at which your application runs.
8. In the "Settings" section check the "Multi-DC" option if you wish to use the same OAuth credentials for all data centers.
9. Click the "Save"/ "UPDATE" button at the bottom footer.
10. You're good to go. Now you can easily add your Zoho Calendar integration in the Cal.com settings.
40 changes: 40 additions & 0 deletions packages/app-store/zohocalendar/api/add.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { stringify } from "querystring";

import { WEBAPP_URL } from "@calcom/lib/constants";
import { defaultHandler, defaultResponder } from "@calcom/lib/server";

import { encodeOAuthState } from "../../_utils/encodeOAuthState";
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import config from "../config.json";
import { appKeysSchema as zohoKeysSchema } from "../zod";

async function getHandler(req: NextApiRequest, res: NextApiResponse) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hariombalhara
do we need to modify AppDeclarativeHandler for apps with Oauth?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that would be a good idea. We can create a task for it.

const appKeys = await getAppKeysFromSlug(config.slug);
const { client_id } = zohoKeysSchema.parse(appKeys);

const state = encodeOAuthState(req);

const params = {
client_id,
response_type: "code",
redirect_uri: WEBAPP_URL + "/api/integrations/zohocalendar/callback",
scope: [
"ZohoCalendar.calendar.ALL",
"ZohoCalendar.event.ALL",
"ZohoCalendar.freebusy.READ",
"AaaServer.profile.READ",
],
access_type: "offline",
state,
prompt: "consent",
};

const query = stringify(params);

res.status(200).json({ url: `https://accounts.zoho.com/oauth/v2/auth?${query}` });
}

export default defaultHandler({
GET: Promise.resolve({ default: defaultResponder(getHandler) }),
});
82 changes: 82 additions & 0 deletions packages/app-store/zohocalendar/api/callback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { stringify } from "querystring";

import { WEBAPP_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import logger from "@calcom/lib/logger";
import { defaultHandler, defaultResponder } from "@calcom/lib/server";
import prisma from "@calcom/prisma";

import { decodeOAuthState } from "../../_utils/decodeOAuthState";
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
import getInstalledAppPath from "../../_utils/getInstalledAppPath";
import config from "../config.json";
import type { ZohoAuthCredentials } from "../types/ZohoCalendar";
import { appKeysSchema as zohoKeysSchema } from "../zod";

const log = logger.getChildLogger({ prefix: [`[[zohocalendar/api/callback]`] });

async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const { code } = req.query;
const state = decodeOAuthState(req);

if (code && typeof code !== "string") {
res.status(400).json({ message: "`code` must be a string" });
return;
}

if (!req.session?.user?.id) {
return res.status(401).json({ message: "You must be logged in to do this" });
}

const appKeys = await getAppKeysFromSlug(config.slug);
const { client_id, client_secret } = zohoKeysSchema.parse(appKeys);

const params = {
client_id,
grant_type: "authorization_code",
client_secret,
redirect_uri: `${WEBAPP_URL}/api/integrations/${config.slug}/callback`,
code,
};

const query = stringify(params);

const response = await fetch(`https://accounts.zoho.com/oauth/v2/token?${query}`, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can have a variable for the base url here https://accounts.zoho.com/oauth/v2 so that it can be updated later
this is referenced in /api/add and /api/callback both

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8",
},
});

const responseBody = await response.json();
console.log(responseBody);
hariombalhara marked this conversation as resolved.
Show resolved Hide resolved

if (!response.ok || responseBody.error) {
log.error("get access_token failed", responseBody);
return res.redirect("/apps/installed?error=" + JSON.stringify(responseBody));
}

const key: ZohoAuthCredentials = {
access_token: responseBody.access_token,
refresh_token: responseBody.refresh_token,
expires_in: Math.round(+new Date() / 1000 + responseBody.expires_in),
};

await prisma.credential.create({
data: {
type: config.type,
key,
userId: req.session.user.id,
appId: config.slug,
},
});
hariombalhara marked this conversation as resolved.
Show resolved Hide resolved

res.redirect(
getSafeRedirectUrl(state?.returnTo) ?? getInstalledAppPath({ variant: config.variant, slug: config.slug })
);
}

export default defaultHandler({
GET: Promise.resolve({ default: defaultResponder(getHandler) }),
});
2 changes: 2 additions & 0 deletions packages/app-store/zohocalendar/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as add } from "./add";
export { default as callback } from "./callback";
16 changes: 16 additions & 0 deletions packages/app-store/zohocalendar/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Zoho Calendar",
"description": "Zoho Calendar is an online business calendar that makes scheduling easy for you. You can use it to stay on top of your schedule and also share calendars with your team to keep everyone on the same page.",
"slug": "zohocalendar",
"type": "zoho_calendar",
"title": "Zoho Calendar",
"variant": "calendar",
"category": "calendar",
"categories": [
"calendar"
],
"logo": "icon.svg",
"publisher": "Cal.com",
"url": "https://cal.com/",
"email": "help@cal.com"
}
2 changes: 2 additions & 0 deletions packages/app-store/zohocalendar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * as api from "./api";
export * as lib from "./lib";
Loading
Loading