Skip to content

Commit

Permalink
New Components - acuity-scheduling (PipedreamHQ#11404)
Browse files Browse the repository at this point in the history
* acuity_scheduling init

* [Components] acuity-scheduling PipedreamHQ#11390
Sources
 - New Appointment (Instant)
 - New Product Order (Instant)
 - New Appointment Canceled (Instant)

Actions
 - Find Appointments By Client Info
 - Add Blocked Time Off

* pnpm update

* add newline

* update package.json

* pnpm update

* Update components/acuity_scheduling/sources/common/base.mjs

Co-authored-by: michelle0927 <[email protected]>

* some adjusts

* remove New Product Order Source

* some adjusts

---------

Co-authored-by: michelle0927 <[email protected]>
  • Loading branch information
luancazarine and michelle0927 authored Apr 19, 2024
1 parent 12493c0 commit dc0332e
Show file tree
Hide file tree
Showing 11 changed files with 489 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import acuityScheduling from "../../acuity_scheduling.app.mjs";

export default {
key: "acuity_scheduling-add-blocked-off-time",
name: "Add Blocked Off Time",
description: "Blocks a specific time slot on your schedule to prevent the scheduling of any appointments during this particular time range. [See the documentation](https://developers.acuityscheduling.com/reference/post-blocks)",
version: "0.0.1",
type: "action",
props: {
acuityScheduling,
startTime: {
propDefinition: [
acuityScheduling,
"startTime",
],
},
endTime: {
propDefinition: [
acuityScheduling,
"endTime",
],
},
calendarId: {
propDefinition: [
acuityScheduling,
"calendarId",
],
},
notes: {
type: "string",
label: "Notes",
description: "Any notes to include for the blocked off time",
optional: true,
},
},
async run({ $ }) {
const response = await this.acuityScheduling.blockTime({
$,
data: {
start: this.startTime,
end: this.endTime,
calendarID: this.calendarId,
notes: this.notes,
},
});

$.export("$summary", `Successfully blocked off time from ${this.startTime} to ${this.endTime}`);
return response;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import acuityScheduling from "../../acuity_scheduling.app.mjs";
import { parseObject } from "../../common/utils.mjs";

export default {
key: "acuity_scheduling-find-appointments-by-client-info",
name: "Find Appointments by Client Info",
description: "Retrieves existing appointments using the client's information, allowing you to track all the appointments associated with a specific client. [See the documentation](https://developers.acuityscheduling.com/reference/get-appointments)",
version: "0.0.1",
type: "action",
props: {
acuityScheduling,
calendarID: {
propDefinition: [
acuityScheduling,
"calendarId",
],
optional: true,
},
appointmentTypeID: {
propDefinition: [
acuityScheduling,
"appointmentTypeId",
],
optional: true,
},
firstName: {
type: "string",
label: "First Name",
description: "Filter appointments for client first name.",
optional: true,
},
lastName: {
type: "string",
label: "Last Name",
description: "Filter appointments for client last name.",
optional: true,
},
email: {
type: "string",
label: "Email",
description: "Filter appointments for client email address.",
optional: true,
},
phone: {
type: "string",
label: "Phone",
description: "Filter appointments for client phone.",
optional: true,
},
customFields: {
type: "object",
label: "Custom Field",
description: "Filter appointments matching a particular custom intake form field **eg. ?field:1234=Hello**",
optional: true,
},
showAll: {
type: "boolean",
label: "Show All",
description: "To retrieve both canceled and scheduled appointments.",
optional: true,
},
},
async run({ $ }) {
let params = {
calendarID: this.calendarID,
appointmentTypeID: this.appointmentTypeID,
firstName: this.firstName,
lastName: this.lastName,
email: this.email,
phone: this.phone,
showAll: this.showAll,
};

if (this.customFields) {
params = {
...params,
...parseObject(this.customFields),
};
}
const appointments = await this.acuityScheduling.listAppointments({
$,
params,
});

$.export("$summary", `Found ${appointments.length} appointments for the search!`);
return appointments;
},
};
108 changes: 104 additions & 4 deletions components/acuity_scheduling/acuity_scheduling.app.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,111 @@
import { axios } from "@pipedream/platform";

export default {
type: "app",
app: "acuity_scheduling",
propDefinitions: {},
propDefinitions: {
startTime: {
type: "string",
label: "Start Time",
description: "The starting time to block off (e.g., '2023-01-01T00:00:00Z').",
},
endTime: {
type: "string",
label: "End Time",
description: "The ending time of the blocked off period (e.g., '2023-01-01T01:00:00Z').",
},
appointmentTypeId: {
type: "string",
label: "Appointment Type ID",
description: "Show only appointments of this type.",
async options() {
const data = await this.listAppointmentTypes();

return data.filter((item) => item.active).map(({
name: label, id: value,
}) => ({
label,
value,
}));
},
},
calendarId: {
type: "string",
label: "Calendar ID",
description: "Show only appointments on calendar with specified ID.",
async options() {
const data = await this.listCalendars();

return data.map(({
name: label, id: value,
}) => ({
label,
value,
}));
},
},
},
methods: {
// this.$auth contains connected account data
authKeys() {
console.log(Object.keys(this.$auth));
_baseUrl() {
return "https://acuityscheduling.com/api/v1";
},
_headers() {
return {
"Authorization": `Bearer ${this.$auth.oauth_access_token}`,
};
},
_makeRequest({
$ = this, path, ...otherOpts
}) {
return axios($, {
...otherOpts,
url: this._baseUrl() + path,
headers: this._headers(),
});
},
listAppointmentTypes() {
return this._makeRequest({
path: "/appointment-types",
});
},
listCalendars() {
return this._makeRequest({
path: "/calendars",
});
},
listAppointments(opts = {}) {
return this._makeRequest({
path: "/appointments",
...opts,
});
},
getAppointment({
id, ...opts
}) {
return this._makeRequest({
path: `/appointments/${id}`,
...opts,
});
},
blockTime(opts = {}) {
return this._makeRequest({
method: "POST",
path: "/blocks",
...opts,
});
},
createHook(opts = {}) {
return this._makeRequest({
method: "POST",
path: "/webhooks",
...opts,
});
},
deleteHook(webhookId) {
return this._makeRequest({
method: "DELETE",
path: `/webhooks/${webhookId}`,
});
},
},
};
18 changes: 18 additions & 0 deletions components/acuity_scheduling/common/utils.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const parseObject = (obj) => {
if (Array.isArray(obj)) {
return obj.map((item) => {
if (typeof item === "string") {
try {
return JSON.parse(item);
} catch (e) {
return item;
}
}
return item;
});
}
if (typeof obj === "string") {
return JSON.parse(obj);
}
return obj;
};
19 changes: 19 additions & 0 deletions components/acuity_scheduling/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@pipedream/acuity_scheduling",
"version": "0.1.0",
"description": "Pipedream Acuity Scheduling Components",
"main": "acuity_scheduling.app.mjs",
"keywords": [
"pipedream",
"acuity_scheduling"
],
"homepage": "https://pipedream.com/apps/acuity_scheduling",
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@pipedream/platform": "^1.5.1"
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import common from "../common/base.mjs";
import sampleEmit from "./test-event.mjs";

export default {
...common,
key: "acuity_scheduling-appointment-canceled-instant",
name: "New Appointment Canceled (Instant)",
description: "Emit new event when an appointment is canceled.",
version: "0.0.1",
type: "source",
dedupe: "unique",
methods: {
getEvent() {
return "appointment.canceled";
},
getSummary(details) {
return `New appointment canceled with Id: ${details.id}`;
},
},
sampleEmit,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export default {
"id": 54321,
"firstName": "Bob",
"lastName": "McTest",
"phone": "",
"email": "[email protected]",
"date": "June 17, 2013",
"time": "10:15am",
"endTime": "11:15am",
"dateCreated": "July 2, 2013",
"datetime": "2013-06-17T10:15:00-0700",
"price": "10.00",
"paid": "no",
"amountPaid": "0.00",
"type": "Regular Visit",
"appointmentTypeID": 1,
"classID": null,
"duration": "60",
"calendar": "My Calendar",
"calendarID": 27238,
"canClientCancel": false,
"canClientReschedule": false,
"canceled": true,
"location": "",
"certificate": null,
"confirmationPage": "https://acuityscheduling.com/schedule.php?owner=11145481&id[]=1220aa9f41091c50c0cc659385cfa1d0&action=appt",
"formsText": "...",
"notes": "Notes",
"timezone": "America/New_York",
"scheduledBy": null,
"forms": [
{
"id": 1,
"name": "Example Intake Form",
"values": [
{
"value": "yes",
"name": "Is this your first visit?",
"fieldID": 1,
"id": 21502993
},
{
"value": "Ninja",
"name": "What is your goal for this appointment?",
"fieldID": 2,
"id": 21502994
}
]
}
],
"labels": [
{
"id": 3,
"name": "Completed",
"color": "pink"
}
],
}
Loading

0 comments on commit dc0332e

Please sign in to comment.