Skip to content

Commit

Permalink
feat: implement zoom connector
Browse files Browse the repository at this point in the history
  • Loading branch information
jaymesC committed Oct 7, 2024
1 parent 2b62442 commit 2fc6bf4
Show file tree
Hide file tree
Showing 6 changed files with 429 additions and 1 deletion.
3 changes: 2 additions & 1 deletion connectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import (
"github.com/wakflo/extensions/internal/connectors/woocommerce"
"github.com/wakflo/extensions/internal/connectors/xero"
"github.com/wakflo/extensions/internal/connectors/zohoinventory"
"github.com/wakflo/extensions/internal/connectors/zoom"
"github.com/wakflo/extensions/internal/logger"
sdk "github.com/wakflo/go-sdk/connector"
)
Expand Down Expand Up @@ -103,7 +104,7 @@ func RegisterConnectors() []*sdk.ConnectorPlugin {
stripe.NewConnector, // Stripe
openai.NewConnector, // OpenAI
googlecalendar.NewConnector, // Google Calendar

zoom.NewConnector, // Zoom
}

// 🛑Do-Not-Edit
Expand Down
35 changes: 35 additions & 0 deletions internal/connectors/zoom/lib.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2022-present Wakflo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package zoom

import (
sdk "github.com/wakflo/go-sdk/connector"
)

func NewConnector() (*sdk.ConnectorPlugin, error) {
return sdk.CreateConnector(&sdk.CreateConnectorArgs{
Name: "Zoom",
Description: "Video conferencing, web conferencing, webinars, screen sharing",
Logo: "logos:zoom",
Version: "0.0.1",
Category: sdk.Apps,
Authors: []string{"Wakflo <integrations@wakflo.com>"},
Triggers: []sdk.ITrigger{},
Operations: []sdk.IOperation{
NewCreateMeetingOperation(),
NewCreateMeetingRegistrantOperation(),
},
})
}
21 changes: 21 additions & 0 deletions internal/connectors/zoom/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package zoom

type MeetingRegistrant struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name,omitempty"`
Email string `json:"email"`
Address string `json:"address,omitempty"`
City string `json:"city,omitempty"`
State string `json:"state,omitempty"`
Zip string `json:"zip,omitempty"`
Country string `json:"country,omitempty"`
Phone string `json:"phone,omitempty"`
Comments string `json:"comments,omitempty"`
Industry string `json:"industry,omitempty"`
JobTitle string `json:"job_title,omitempty"`
NumberOfEmployees string `json:"no_of_employees,omitempty"`
Organization string `json:"org,omitempty"`
PurchasingTimeFrame string `json:"purchasing_time_frame,omitempty"`
RoleInPurchaseProcess string `json:"role_in_purchase_process,omitempty"`
Language string `json:"language,omitempty"`
}
167 changes: 167 additions & 0 deletions internal/connectors/zoom/operation_create_meeting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// Copyright 2022-present Wakflo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package zoom

import (
"encoding/json"

"github.com/wakflo/go-sdk/autoform"
sdk "github.com/wakflo/go-sdk/connector"
sdkcore "github.com/wakflo/go-sdk/core"
)

type createMeetingOperationProps struct {
Topic string `json:"topic"`
StartTime string `json:"start_time"`
ScheduleFor string `json:"schedule_for"`
Duration int `json:"duration"`
PreSchedule string `json:"pre_schedule"`
Password string `json:"password"`
Agenda string `json:"agenda"`
JoinURL string `json:"join_url"`
}

type CreateMeetingOperation struct {
options *sdk.OperationInfo
}

func NewCreateMeetingOperation() *CreateMeetingOperation {
return &CreateMeetingOperation{
options: &sdk.OperationInfo{
Name: "Create Zoom Meeting",
Description: "Create a new Zoom Meeting",
Auth: sharedAuth,
Input: map[string]*sdkcore.AutoFormSchema{
"topic": autoform.NewShortTextField().
SetDisplayName("Meeting's topic").
SetDescription("The meeting topic").
SetRequired(true).Build(),
"start_time": autoform.NewShortTextField().
SetDisplayName("Start Time").
SetDescription("Meeting start date-time").
SetRequired(false).Build(),
"schedule_for": autoform.NewShortTextField().
SetDisplayName("Schedule for").
SetDescription("The email address or user ID of the user to schedule a meeting for.").
SetRequired(false).Build(),
"duration": autoform.NewNumberField().
SetDisplayName("Duration (in Minutes)").
SetDescription("Duration of the meeting").
SetRequired(false).Build(),
"pre_schedule": autoform.NewBooleanField().
SetDisplayName("Pre Schedule").
SetDescription("Whether the prescheduled meeting was created via the GSuite app.").
SetRequired(false).Build(),
"password": autoform.NewShortTextField().
SetDisplayName("Password").
SetDescription("The password required to join the meeting. By default, a password can only have a maximum length of 10 characters and only contain alphanumeric characters and the @, -, _, and * characters.").
SetRequired(false).Build(),
"agenda": autoform.NewLongTextField().
SetDisplayName("Agenda").
SetDescription("The meeting's agenda").
SetRequired(false).Build(),
"join_url": autoform.NewLongTextField().
SetDisplayName("Join URL").
SetDescription("URL for participants to join the meeting.").
SetRequired(false).Build(),
},
SampleOutput: map[string]interface{}{},
ErrorSettings: sdkcore.StepErrorSettings{
ContinueOnError: false,
RetryOnError: false,
},
RequireAuth: true,
},
}
}

func (c *CreateMeetingOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) {
input := sdk.InputToType[createMeetingOperationProps](ctx)

data := map[string]interface{}{
"topic": input.Topic,
"agenda": "My Meeting",
"default_password": false,
//nolint:mnd
"duration": 30,
"pre_schedule": false,
"timezone": "UTC",
//nolint:mnd
"type": 2,
"settings": map[string]interface{}{
"allow_multiple_devices": true,
//nolint:mnd
"approval_type": 2,
"audio": "telephony",
"calendar_type": 1,
"close_registration": false,
"email_notification": true,
"host_video": true,
"join_before_host": false,
"meeting_authentication": true,
"mute_upon_entry": false,
"participant_video": false,
"private_meeting": false,
"registrants_confirmation_email": true,
"registrants_email_notification": true,
"registration_type": 1,
"show_share_button": true,
"host_save_video_order": true,
},
}

if input.Duration != 0 {
data["duration"] = input.Duration
}
if input.PreSchedule != "" {
data["pre_schedule"] = input.PreSchedule
}
if input.StartTime != "" {
data["start_time"] = input.StartTime
}
if input.ScheduleFor != "" {
data["schedule_for"] = input.ScheduleFor
}
if input.Agenda != "" {
data["agenda"] = input.Agenda
}
if input.JoinURL != "" {
data["join_url"] = input.JoinURL
}
if input.Password != "" {
data["[password]"] = input.Password
}

meeting, err := json.Marshal(data)
if err != nil {
return nil, err
}

reqURL := "https://api.zoom.us/v2/users/me/meetings"

resp, err := zoomRequest(ctx.Auth.AccessToken, reqURL, meeting)
if err != nil {
return nil, err
}
return resp, nil
}

func (c *CreateMeetingOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) {
return c.Run(ctx)
}

func (c *CreateMeetingOperation) GetInfo() *sdk.OperationInfo {
return c.options
}
144 changes: 144 additions & 0 deletions internal/connectors/zoom/operation_create_meeting_registration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright 2022-present Wakflo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package zoom

import (
"encoding/json"
"fmt"

"github.com/wakflo/go-sdk/autoform"
sdk "github.com/wakflo/go-sdk/connector"
sdkcore "github.com/wakflo/go-sdk/core"
)

type createMeetingRegistrantOperationProps struct {
MeetingID string `json:"meeting_id"`
MeetingRegistrant
}

type CreateMeetingRegistrantOperation struct {
options *sdk.OperationInfo
}

func NewCreateMeetingRegistrantOperation() *CreateMeetingRegistrantOperation {
return &CreateMeetingRegistrantOperation{
options: &sdk.OperationInfo{
Name: "Create Zoom Meeting Registrant",
Description: "Create and submit a user's registration to a meeting.",
Auth: sharedAuth,
Input: map[string]*sdkcore.AutoFormSchema{
"meeting_id": autoform.NewShortTextField().
SetDisplayName("Meeting ID").
SetDescription("The meeting's ID").
SetRequired(true).Build(),
"first_name": autoform.NewShortTextField().
SetDisplayName("First Name").
SetDescription("First name").
SetRequired(true).Build(),
"last_name": autoform.NewShortTextField().
SetDisplayName("Last Name").
SetDescription("Last name").
SetRequired(false).Build(),
"email": autoform.NewShortTextField().
SetDisplayName("Email").
SetDescription("The registrant's email address.").
SetRequired(true).Build(),
"address": autoform.NewShortTextField().
SetDisplayName("Address").
SetDescription("The registrant's address.").
SetRequired(false).Build(),
"city": autoform.NewShortTextField().
SetDisplayName("City").
SetDescription("The registrant's city.").
SetRequired(false).Build(),
"state": autoform.NewShortTextField().
SetDisplayName("State").
SetDescription("The registrant's state or province.").
SetRequired(false).Build(),
"zip": autoform.NewShortTextField().
SetDisplayName("Zip").
SetDescription("The registrant's zip or postal code.").
SetRequired(false).Build(),
"country": autoform.NewShortTextField().
SetDisplayName("Country").
SetDescription("The registrant's two-letter country code.").
SetRequired(false).Build(),
"phone": autoform.NewShortTextField().
SetDisplayName("Phone").
SetDescription("The registrant's phone number.").
SetRequired(false).Build(),
"comments": autoform.NewLongTextField().
SetDisplayName("Phone").
SetDescription("The registrant's questions and comments.").
SetRequired(false).Build(),
"industry": autoform.NewShortTextField().
SetDisplayName("Industry").
SetDescription("The registrant's industry").
SetRequired(false).Build(),
"job_title": autoform.NewShortTextField().
SetDisplayName("Job Title").
SetDescription("The registrant's job title").
SetRequired(false).Build(),
"no_of_employees": autoform.NewShortTextField().
SetDisplayName("Number of Employees").
SetDescription("The registrant's number of employees.").
SetRequired(false).Build(),
"org": autoform.NewShortTextField().
SetDisplayName("Organization").
SetDescription("The registrant's organization.").
SetRequired(false).Build(),
"purchasing_time_frame": autoform.NewShortTextField().
SetDisplayName("Purchasing time frame").
SetDescription("The registrant's purchasing time frame.").
SetRequired(false).Build(),
"role_in_purchase_process": autoform.NewShortTextField().
SetDisplayName("Role in purchase process").
SetDescription("The registrant's role in purchase process").
SetRequired(false).Build(),
},
SampleOutput: map[string]interface{}{},
ErrorSettings: sdkcore.StepErrorSettings{
ContinueOnError: false,
RetryOnError: false,
},
RequireAuth: true,
},
}
}

func (c *CreateMeetingRegistrantOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) {
input := sdk.InputToType[createMeetingRegistrantOperationProps](ctx)

meetingRegistrant, err := json.Marshal(input)
if err != nil {
return nil, err
}

reqURL := fmt.Sprintf("https://api.zoom.us/v2/meetings/%s/registrants", input.MeetingID)

resp, err := zoomRequest(ctx.Auth.AccessToken, reqURL, meetingRegistrant)
if err != nil {
return nil, err
}
return resp, nil
}

func (c *CreateMeetingRegistrantOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) {
return c.Run(ctx)
}

func (c *CreateMeetingRegistrantOperation) GetInfo() *sdk.OperationInfo {
return c.options
}
Loading

0 comments on commit 2fc6bf4

Please sign in to comment.