Skip to content

Commit

Permalink
feat(wasm): add Calendly Wasm FDW (#364)
Browse files Browse the repository at this point in the history
* feat: add Calendly Wasm FDW

* update README

* format test code
  • Loading branch information
burmecia authored Nov 14, 2024
1 parent cf4d84a commit e2bdb28
Show file tree
Hide file tree
Showing 12 changed files with 1,086 additions and 14 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"wrappers",
]
exclude = [
"wasm-wrappers/fdw/calendly_fdw",
"wasm-wrappers/fdw/helloworld_fdw",
"wasm-wrappers/fdw/snowflake_fdw",
"wasm-wrappers/fdw/paddle_fdw",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
| [Notion](./wasm-wrappers/fdw/notion_fdw) | A Wasm FDW for [Notion](https://www.notion.so/) |||
| [Snowflake](./wasm-wrappers/fdw/snowflake_fdw) | A Wasm FDW for [Snowflake](https://www.snowflake.com/) |||
| [Paddle](./wasm-wrappers/fdw/paddle_fdw) | A Wasm FDW for [Paddle](https://www.paddle.com/) |||
| [Calendly](./wasm-wrappers/fdw/calendly_fdw) | A Wasm FDW for [Calendly](https://www.calendly.com/) |||

### Warning

Expand Down
282 changes: 282 additions & 0 deletions docs/catalog/calendly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
---
source:
documentation:
author: supabase
tags:
- wasm
- official
---

# Calendly

[Calendly](https://calendly.com/) is a scheduling platform used for teams to schedule, prepare and follow up on external meetings.

The Calendly Wrapper is a WebAssembly(Wasm) foreign data wrapper which allows you to read data from your Calendly for use within your Postgres database.

!!! warning

Restoring a logical backup of a database with a materialized view using a foreign table can fail. For this reason, either do not use foreign tables in materialized views or use them in databases with physical backups enabled.

## Supported Data Types

| Postgres Data Type | Calendly Data Type |
| ------------------ | ------------------ |
| boolean | Boolean |
| bigint | Number |
| double precision | Number |
| text | String |
| timestamp | Time |
| timestamptz | Time |
| jsonb | Json |

The Calendly API uses JSON formatted data, please refer to [Calendly API docs](https://developer.calendly.com/api-docs) for more details.

## Available Versions

| Version | Wasm Package URL | Checksum |
| ------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| 0.1.0 | `https://github.com/supabase/wrappers/releases/download/wasm_calendly_fdw_v0.1.0/calendly_fdw.wasm` | `tbd` |

## Preparation

Before you get started, make sure the `wrappers` extension is installed on your database:

```sql
create extension if not exists wrappers with schema extensions;
```

and then create the Wasm foreign data wrapper:

```sql
create foreign data wrapper wasm_wrapper
handler wasm_fdw_handler
validator wasm_fdw_validator;
```

### Secure your credentials (optional)

By default, Postgres stores FDW credentials inside `pg_catalog.pg_foreign_server` in plain text. Anyone with access to this table will be able to view these credentials. Wrappers is designed to work with [Vault](https://supabase.com/docs/guides/database/vault), which provides an additional level of security for storing credentials. We recommend using Vault to store your credentials.

```sql
-- Save your Calendly API key in Vault and retrieve the `key_id`
insert into vault.secrets (name, secret)
values (
'calendly',
'<Calendly API Key>' -- Calendly personal access token
)
returning key_id;
```

### Connecting to Calendly

We need to provide Postgres with the credentials to access Calendly and any additional options. We can do this using the `create server` command:

=== "With Vault"

```sql
create server calendly_server
foreign data wrapper wasm_wrapper
options (
fdw_package_url 'https://github.com/supabase/wrappers/releases/download/wasm_calendly_fdw_v0.1.0/calendly_fdw.wasm',
fdw_package_name 'supabase:calendly-fdw',
fdw_package_version '0.1.0',
fdw_package_checksum 'tbd',
-- find your organization uri using foreign table 'calendly.current_user', see below example for details
organization 'https://api.calendly.com/organizations/81da9c7f-3e19-434a-c3d2-0325e375cdef',
api_url 'https://api.calendly.com', -- optional
api_key_id '<key_ID>' -- The Key ID from above.
);
```

=== "Without Vault"

```sql
create server calendly_server
foreign data wrapper wasm_wrapper
options (
fdw_package_url 'https://github.com/supabase/wrappers/releases/download/wasm_calendly_fdw_v0.1.0/calendly_fdw.wasm',
fdw_package_name 'supabase:calendly-fdw',
fdw_package_version '0.1.0',
fdw_package_checksum 'tbd',
-- find your organization uri using foreign table 'calendly.current_user', see below example for details
organization 'https://api.calendly.com/organizations/81da9c7f-3e19-434a-c3d2-0325e375cdef',
api_url 'https://api.calendly.com', -- optional
api_key 'eyJraWQiOiIxY2UxZ...' -- Calendly personal access token
);
```

Note the `fdw_package_*` options are required, which specify the Wasm package metadata. You can get the available package version list from [above](#available-versions).

### Create a schema

We recommend creating a schema to hold all the foreign tables:

```sql
create schema if not exists calendly;
```

## Creating Foreign Tables

The Calendly Wrapper supports data reads from below objects in calendly.

| Integration | Select | Insert | Update | Delete | Truncate |
| ----------------------- | :----: | :----: | :----: | :----: | :------: |
| Current User ||||||
| Event Types ||||||
| Groups ||||||
| Organization Membership ||||||
| Scheduled Events ||||||

For example:

```sql
-- Get the current user used for the API request
-- Note: we can query this table to retrieve the organization uri:
-- select attrs->>'current_organization' as org_uri
-- from calendly.current_user;
create foreign table calendly.current_user (
uri text,
slug text,
created_at timestamp,
updated_at timestamp,
attrs jsonb
)
server calendly_server
options (
object 'current_user'
);

create foreign table calendly.event_types (
uri text,
created_at timestamp,
updated_at timestamp,
attrs jsonb
)
server calendly_server
options (
object 'event_types'
);

create foreign table calendly.groups (
uri text,
created_at timestamp,
updated_at timestamp,
attrs jsonb
)
server calendly_server
options (
object 'groups'
);

create foreign table calendly.organization_memberships (
uri text,
created_at timestamp,
updated_at timestamp,
attrs jsonb
)
server calendly_server
options (
object 'organization_memberships'
);

create foreign table calendly.scheduled_events (
uri text,
created_at timestamp,
updated_at timestamp,
attrs jsonb
)
server calendly_server
options (
object 'scheduled_events'
);
```

!!! note

- All the supported columns are listed above, other columns are not allowd.
- The `attrs` is a special column which stores all the object attributes in JSON format, you can extract any attributes needed from it. See more examples below.

### Foreign table options

The full list of foreign table options are below:

- `object` - Object name in Calendly, required.

Supported objects are listed below:

| Object name |
| ------------------------ |
| current_user |
| event_types |
| groups |
| organization_memberships |
| scheduled_events |

## Query Pushdown Support

This FDW doesn't support query pushdown.

## Examples

Below are some examples on how to use Calendly foreign tables.

### Basic example

This example will create a "foreign table" inside your Postgres database and query its data. First, we can create a schema to hold all the Calendly foreign tables.

```sql
create schema if not exists calendly;
```

Then create the foreign table and query it, for example:

```sql
create foreign table calendly.current_user (
uri text,
slug text,
created_at timestamp,
updated_at timestamp,
attrs jsonb
)
server calendly_server
options (
object 'current_user'
);

-- query current user used for the Calendly API request
select * from calendly.current_user;
```

`attrs` is a special column which stores all the object attributes in JSON format, you can extract any attributes needed from it. See more examples below.

### Query JSON attributes

```sql
-- extract organization uri from current user
select attrs->>'current_organization' as org_uri
from calendly.current_user;

-- then update foreign server option using the organization uri
alter server calendly_server options (set organization '<org_uri>');
```

Some other examples,

```sql
create foreign table calendly.event_types (
uri text,
created_at timestamp,
updated_at timestamp,
attrs jsonb
)
server calendly_server
options (
object 'event_types'
);

select attrs->'profile'->>'name' as profile_name
from calendly.event_types;

select attrs->'custom_questions'->0->>'name' as first_question_name
from calendly.event_types;
```
4 changes: 3 additions & 1 deletion docs/catalog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ hide:
| Auth0 |||||||
| AWS Cognito |||||||
| BigQuery |||||||
| Calendly |||||||
| ClickHouse |||||||
| Firebase |||||||
| Logflare |||||||
Expand All @@ -32,6 +33,7 @@ See [Developing a Wasm Wrapper](../guides/create-wasm-wrapper.md) for instructio

| Integration | Developer | Docs | Source |
| ----------- | :------------------------------: | :----------------------------------: | :------------------------------------------------------------------------------------: |
| Calendly | [Supabase](https://supabase.com) | [Link](calendly.md) | [Link](https://github.com/supabase/wrappers/tree/main/wasm-wrappers/fdw/calendly_fdw) |
| Notion | [Supabase](https://supabase.com) | [Link](notion.md) | [Link](https://github.com/supabase/wrappers/tree/main/wasm-wrappers/fdw/notion_fdw) |
| Paddle | [Supabase](https://supabase.com) | [Link](paddle.md) | [Link](https://github.com/supabase/wrappers/tree/main/wasm-wrappers/fdw/paddle_fdw) |
| Snowflake | [Supabase](https://supabase.com) | [Link](snowflake.md) | [Link](https://github.com/supabase/wrappers/tree/main/wasm-wrappers/fdw/snowflake_fdw) |
| Notion | [Supabase](https://supabase.com) | [Link](notion.md) | [Link](https://github.com/supabase/wrappers/tree/main/wasm-wrappers/fdw/notion_fdw) |
36 changes: 24 additions & 12 deletions docs/catalog/wasm/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ Foreign data wrappers built with Wasm which can be used on Supabase platform.

<div class="grid cards" markdown>

- :simple-webassembly: &nbsp; **[Calendly](../calendly.md)**

----

Foreign data wrapper for [Calendly](https://calendly.com/).

Supported by [Supabase](https://www.supabase.com)

:octicons-tag-24: [v0.1.0](https://github.com/supabase/wrappers/releases/tag/calendly_fdw_v0.1.0) &nbsp;
:octicons-code-24: [source](https://github.com/supabase/wrappers/tree/wasm_calendly_fdw_v0.1.0/wasm-wrappers/fdw/calendly_fdw) &nbsp;
:material-file-document: [docs](../calendly.md)

- :simple-webassembly: &nbsp; **[Notion](../notion.md)**

----

Foreign data wrapper for [Notion](https://notion.so/).

Supported by [Supabase](https://www.supabase.com)

:octicons-tag-24: [v0.1.0](https://github.com/supabase/wrappers/releases/tag/wasm_notion_fdw_v0.1.0) &nbsp;
:octicons-code-24: [source](https://github.com/supabase/wrappers/tree/wasm_notion_fdw_v0.1.0/wasm-wrappers/fdw/notion_fdw) &nbsp;
:material-file-document: [docs](../notion.md)

- :simple-webassembly: &nbsp; **[Paddle](../paddle.md)**

----
Expand All @@ -37,16 +61,4 @@ Foreign data wrappers built with Wasm which can be used on Supabase platform.
:octicons-code-24: [source](https://github.com/supabase/wrappers/tree/wasm_snowflake_fdw_v0.1.1/wasm-wrappers/fdw/snowflake_fdw) &nbsp;
:material-file-document: [docs](../snowflake.md)

- :simple-webassembly: &nbsp; **[Notion](../notion.md)**

----

Foreign data wrapper for [Notion](https://notion.so/).

Supported by [Supabase](https://www.supabase.com)

:octicons-tag-24: [v0.1.0](https://github.com/supabase/wrappers/releases/tag/wasm_notion_fdw_v0.1.0) &nbsp;
:octicons-code-24: [source](https://github.com/supabase/wrappers/tree/wasm_notion_fdw_v0.1.0/wasm-wrappers/fdw/notion_fdw) &nbsp;
:material-file-document: [docs](../notion.md)

</div>
3 changes: 2 additions & 1 deletion mkdocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ nav:
- SQL Server: 'catalog/mssql.md'
- Wasm:
- catalog/wasm/index.md
- Calendly: 'catalog/calendly.md'
- Notion: 'catalog/notion.md'
- Paddle: 'catalog/paddle.md'
- Snowflake: 'catalog/snowflake.md'
- Notion: 'catalog/notion.md'
- Guides:
- Native vs Wasm Wrappers: 'guides/native-wasm.md'
- Query Pushdown: 'guides/query-pushdown.md'
Expand Down
Loading

0 comments on commit e2bdb28

Please sign in to comment.