From 2075aaac89da4234e53511e5b64ed4fea50e4d11 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Fri, 9 May 2025 10:56:58 -0300 Subject: [PATCH 1/5] slicktext init --- .../actions/edit-contact/edit-contact.mjs | 75 ++++++++++ .../actions/opt-in-contact/opt-in-contact.mjs | 88 ++++++++++++ .../send-message-to-contact.mjs | 42 ++++++ components/slicktext/slicktext.app.mjs | 132 ++++++++++++++++++ 4 files changed, 337 insertions(+) create mode 100644 components/slicktext/actions/edit-contact/edit-contact.mjs create mode 100644 components/slicktext/actions/opt-in-contact/opt-in-contact.mjs create mode 100644 components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs create mode 100644 components/slicktext/slicktext.app.mjs diff --git a/components/slicktext/actions/edit-contact/edit-contact.mjs b/components/slicktext/actions/edit-contact/edit-contact.mjs new file mode 100644 index 0000000000000..b2f6bdadd525b --- /dev/null +++ b/components/slicktext/actions/edit-contact/edit-contact.mjs @@ -0,0 +1,75 @@ +import slicktext from "../../slicktext.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "slicktext-edit-contact", + name: "Edit Contact", + description: "Updates personal details of an existing contact. [See the documentation](https://api.slicktext.com/docs/v1/contacts#6)", + version: "0.0.{{ts}}", + type: "action", + props: { + slicktext, + contactId: { + propDefinition: [ + slicktext, + "contactId", + ], + }, + name: { + propDefinition: [ + slicktext, + "name", + ], + optional: true, + }, + emailAddress: { + propDefinition: [ + slicktext, + "emailAddress", + ], + optional: true, + }, + city: { + propDefinition: [ + slicktext, + "city", + ], + optional: true, + }, + state: { + propDefinition: [ + slicktext, + "state", + ], + optional: true, + }, + zipCode: { + propDefinition: [ + slicktext, + "zipCode", + ], + optional: true, + }, + country: { + propDefinition: [ + slicktext, + "country", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.slicktext.updateContact({ + contactId: this.contactId, + name: this.name, + emailAddress: this.emailAddress, + city: this.city, + state: this.state, + zipCode: this.zipCode, + country: this.country, + }); + + $.export("$summary", `Successfully updated contact with ID: ${this.contactId}`); + return response; + }, +}; diff --git a/components/slicktext/actions/opt-in-contact/opt-in-contact.mjs b/components/slicktext/actions/opt-in-contact/opt-in-contact.mjs new file mode 100644 index 0000000000000..4367857190c49 --- /dev/null +++ b/components/slicktext/actions/opt-in-contact/opt-in-contact.mjs @@ -0,0 +1,88 @@ +import slicktext from "../../slicktext.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "slicktext-opt-in-contact", + name: "Opt-In Contact", + description: "Add a new contact to your messaging list with a confirmation text. [See the documentation](https://api.slicktext.com/docs/v1/contacts)", + version: "0.0.{{ts}}", + type: "action", + props: { + slicktext, + contactNumber: { + propDefinition: [ + slicktext, + "contactNumber", + ], + }, + textwordId: { + propDefinition: [ + slicktext, + "textwordId", + ], + }, + doubleOptInMessage: { + type: "string", + label: "Double Opt-In Message", + description: "The confirmation message sent to the contact. They will need to reply YES to complete subscription. Must be 160 characters or less.", + optional: true, + }, + name: { + propDefinition: [ + slicktext, + "name", + ], + optional: true, + }, + emailAddress: { + propDefinition: [ + slicktext, + "emailAddress", + ], + optional: true, + }, + city: { + propDefinition: [ + slicktext, + "city", + ], + optional: true, + }, + state: { + propDefinition: [ + slicktext, + "state", + ], + optional: true, + }, + zipCode: { + propDefinition: [ + slicktext, + "zipCode", + ], + optional: true, + }, + country: { + propDefinition: [ + slicktext, + "country", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.slicktext.addContact({ + contactNumber: this.contactNumber, + textwordId: this.textwordId, + doubleOptInMessage: this.doubleOptInMessage, + name: this.name, + emailAddress: this.emailAddress, + city: this.city, + state: this.state, + zipCode: this.zipCode, + country: this.country, + }); + $.export("$summary", `Successfully initiated opt-in for contact with number: ${this.contactNumber}`); + return response; + }, +}; diff --git a/components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs b/components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs new file mode 100644 index 0000000000000..cf4aa73932069 --- /dev/null +++ b/components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs @@ -0,0 +1,42 @@ +import slicktext from "../../slicktext.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "slicktext-send-message-to-contact", + name: "Send Message to Contact", + description: "Deliver a text message to a single contact. [See the documentation](https://api.slicktext.com/docs/v1/messages)", + version: "0.0.1", + type: "action", + props: { + slicktext, + contactNumber: { + propDefinition: [ + slicktext, + "contactNumber", + ], + }, + messageContent: { + propDefinition: [ + slicktext, + "messageContent", + ], + }, + textwordId: { + propDefinition: [ + slicktext, + "textwordId", + ], + }, + }, + async run({ $ }) { + const response = await this.slicktext.sendMessage({ + contactNumber: this.contactNumber, + messageContent: this.messageContent, + textwordId: this.textwordId, + }); + + const messageId = response.messageId || response.id || "unknown"; + $.export("$summary", `Message sent successfully. Message ID: ${messageId}`); + return response; + }, +}; diff --git a/components/slicktext/slicktext.app.mjs b/components/slicktext/slicktext.app.mjs new file mode 100644 index 0000000000000..625a1da1b8a84 --- /dev/null +++ b/components/slicktext/slicktext.app.mjs @@ -0,0 +1,132 @@ +import { axios } from "@pipedream/platform"; + +export default { + type: "app", + app: "slicktext", + propDefinitions: { + contactId: { + type: "string", + label: "Contact ID", + description: "The ID of the contact to be updated", + }, + contactNumber: { + type: "string", + label: "Contact Number", + description: "The phone number of the contact. Must be at least 10 digits.", + }, + messageContent: { + type: "string", + label: "Message Content", + description: "The body of the text message you want to send.", + }, + textwordId: { + type: "string", + label: "Textword ID", + description: "The ID of the textword", + async options() { + const response = await this._makeRequest({ + path: "/textwords", + }); + return response.textwords.map((textword) => ({ + label: textword.word, + value: textword.id, + })); + }, + }, + name: { + type: "string", + label: "Name", + description: "The name of the contact", + optional: true, + }, + emailAddress: { + type: "string", + label: "Email Address", + description: "The email address of the contact", + optional: true, + }, + city: { + type: "string", + label: "City", + description: "The city of the contact", + optional: true, + }, + state: { + type: "string", + label: "State", + description: "The state of the contact", + optional: true, + }, + zipCode: { + type: "string", + label: "Zip Code", + description: "The zip code of the contact", + optional: true, + }, + country: { + type: "string", + label: "Country", + description: "The country of the contact", + optional: true, + }, + }, + methods: { + _baseUrl() { + return "https://api.slicktext.com/v1"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, + method = "POST", + path = "/", + headers, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + method, + url: this._baseUrl() + path, + headers: { + ...headers, + "Authorization": `Bearer ${this.$auth.api_key}`, + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + }, + async updateContact(opts = {}) { + return this._makeRequest({ + path: "/contacts", + data: { + action: "EDIT", + contactId: opts.contactId, + name: opts.name, + emailAddress: opts.emailAddress, + city: opts.city, + state: opts.state, + zipCode: opts.zipCode, + country: opts.country, + }, + }); + }, + async sendMessage(opts = {}) { + return this._makeRequest({ + path: "/messages", + data: { + action: "SEND", + contactNumber: opts.contactNumber, + messageContent: opts.messageContent, + textwordId: opts.textwordId, + }, + }); + }, + async addContact(opts = {}) { + return this._makeRequest({ + path: "/contacts", + data: { + action: "DOUBLEOPTIN", + contactNumber: opts.contactNumber, + }, + }); + }, + }, +}; From 58808feabbed0b41aef3cde9cb672e3c06bdae28 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 14 May 2025 15:57:02 -0300 Subject: [PATCH 2/5] [Components] slicktext #13364 Actions - Create Contact - Edit Contact - Add Contact To Lists --- components/slicktext/.gitignore | 3 - .../add-contact-to-lists.mjs | 39 ++++ components/slicktext/actions/common/base.mjs | 88 ++++++++ .../actions/create-contact/create-contact.mjs | 41 ++++ .../actions/edit-contact/edit-contact.mjs | 63 ++---- .../actions/opt-in-contact/opt-in-contact.mjs | 88 -------- .../send-message-to-contact.mjs | 42 ---- components/slicktext/app/slicktext.app.ts | 13 -- components/slicktext/common/constants.mjs | 15 ++ components/slicktext/common/utils.mjs | 36 ++++ components/slicktext/package.json | 8 +- components/slicktext/slicktext.app.mjs | 202 +++++++++++------- 12 files changed, 369 insertions(+), 269 deletions(-) delete mode 100644 components/slicktext/.gitignore create mode 100644 components/slicktext/actions/add-contact-to-lists/add-contact-to-lists.mjs create mode 100644 components/slicktext/actions/common/base.mjs create mode 100644 components/slicktext/actions/create-contact/create-contact.mjs delete mode 100644 components/slicktext/actions/opt-in-contact/opt-in-contact.mjs delete mode 100644 components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs delete mode 100644 components/slicktext/app/slicktext.app.ts create mode 100644 components/slicktext/common/constants.mjs create mode 100644 components/slicktext/common/utils.mjs diff --git a/components/slicktext/.gitignore b/components/slicktext/.gitignore deleted file mode 100644 index ec761ccab7595..0000000000000 --- a/components/slicktext/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.js -*.mjs -dist \ No newline at end of file diff --git a/components/slicktext/actions/add-contact-to-lists/add-contact-to-lists.mjs b/components/slicktext/actions/add-contact-to-lists/add-contact-to-lists.mjs new file mode 100644 index 0000000000000..59dfe575e25fd --- /dev/null +++ b/components/slicktext/actions/add-contact-to-lists/add-contact-to-lists.mjs @@ -0,0 +1,39 @@ +import { parseObject } from "../../common/utils.mjs"; +import slicktext from "../../slicktext.app.mjs"; + +export default { + key: "slicktext-add-contact-to-lists", + name: "Add Contact To Lists", + description: "Add a contact to lists. [See the documentation](https://api.slicktext.com/docs/v2/lists#scroll-to-add-contacts-to-lists)", + version: "0.0.1", + type: "action", + props: { + slicktext, + contactId: { + propDefinition: [ + slicktext, + "contactId", + ], + }, + listIds: { + propDefinition: [ + slicktext, + "listIds", + ], + }, + }, + async run({ $ }) { + const response = await this.slicktext.addContactToLists({ + $, + data: [ + { + contact_id: this.contactId, + lists: parseObject(this.listIds), + }, + ], + }); + + $.export("$summary", `Successfully added contact with ID: ${this.contactId} to lists with ID: ${parseObject(this.listIds).join()}`); + return response; + }, +}; diff --git a/components/slicktext/actions/common/base.mjs b/components/slicktext/actions/common/base.mjs new file mode 100644 index 0000000000000..3cf53cfdd2e7b --- /dev/null +++ b/components/slicktext/actions/common/base.mjs @@ -0,0 +1,88 @@ +import slicktext from "../../slicktext.app.mjs"; + +export const commonProps = { + firstName: { + propDefinition: [ + slicktext, + "firstName", + ], + optional: true, + }, + lastName: { + propDefinition: [ + slicktext, + "lastName", + ], + optional: true, + }, + email: { + propDefinition: [ + slicktext, + "email", + ], + optional: true, + }, + birthdate: { + propDefinition: [ + slicktext, + "birthdate", + ], + optional: true, + }, + address: { + propDefinition: [ + slicktext, + "address", + ], + optional: true, + }, + city: { + propDefinition: [ + slicktext, + "city", + ], + optional: true, + }, + state: { + propDefinition: [ + slicktext, + "state", + ], + optional: true, + }, + zip: { + propDefinition: [ + slicktext, + "zip", + ], + optional: true, + }, + country: { + propDefinition: [ + slicktext, + "country", + ], + optional: true, + }, + timezone: { + propDefinition: [ + slicktext, + "timezone", + ], + optional: true, + }, + language: { + propDefinition: [ + slicktext, + "language", + ], + optional: true, + }, + optInStatus: { + propDefinition: [ + slicktext, + "optInStatus", + ], + optional: true, + }, +}; diff --git a/components/slicktext/actions/create-contact/create-contact.mjs b/components/slicktext/actions/create-contact/create-contact.mjs new file mode 100644 index 0000000000000..e64467b8bd8ce --- /dev/null +++ b/components/slicktext/actions/create-contact/create-contact.mjs @@ -0,0 +1,41 @@ +import { objectCamelToSnakeCase } from "../../common/utils.mjs"; +import slicktext from "../../slicktext.app.mjs"; +import { commonProps } from "../common/base.mjs"; + +export default { + key: "slicktext-create-contact", + name: "Create Contact", + description: "Add a new contact to your messaging list. [See the documentation](https://api.slicktext.com/docs/v1/contacts)", + version: "0.0.1", + type: "action", + props: { + slicktext, + mobileNumber: { + propDefinition: [ + slicktext, + "mobileNumber", + ], + }, + ...commonProps, + forceDoubleOptIn: { + propDefinition: [ + slicktext, + "forceDoubleOptIn", + ], + optional: true, + }, + }, + async run({ $ }) { + const { + slicktext, + ...data + } = this; + + const response = await slicktext.createContact({ + $, + data: objectCamelToSnakeCase(data), + }); + $.export("$summary", `Successfully initiated opt-in for contact with number: ${this.contactNumber}`); + return response; + }, +}; diff --git a/components/slicktext/actions/edit-contact/edit-contact.mjs b/components/slicktext/actions/edit-contact/edit-contact.mjs index b2f6bdadd525b..ae9d9ffa84dc2 100644 --- a/components/slicktext/actions/edit-contact/edit-contact.mjs +++ b/components/slicktext/actions/edit-contact/edit-contact.mjs @@ -1,11 +1,12 @@ +import { objectCamelToSnakeCase } from "../../common/utils.mjs"; import slicktext from "../../slicktext.app.mjs"; -import { axios } from "@pipedream/platform"; +import { commonProps } from "../common/base.mjs"; export default { key: "slicktext-edit-contact", name: "Edit Contact", description: "Updates personal details of an existing contact. [See the documentation](https://api.slicktext.com/docs/v1/contacts#6)", - version: "0.0.{{ts}}", + version: "0.0.1", type: "action", props: { slicktext, @@ -15,58 +16,26 @@ export default { "contactId", ], }, - name: { + mobileNumber: { propDefinition: [ slicktext, - "name", - ], - optional: true, - }, - emailAddress: { - propDefinition: [ - slicktext, - "emailAddress", - ], - optional: true, - }, - city: { - propDefinition: [ - slicktext, - "city", - ], - optional: true, - }, - state: { - propDefinition: [ - slicktext, - "state", - ], - optional: true, - }, - zipCode: { - propDefinition: [ - slicktext, - "zipCode", - ], - optional: true, - }, - country: { - propDefinition: [ - slicktext, - "country", + "mobileNumber", ], optional: true, }, + ...commonProps, }, async run({ $ }) { - const response = await this.slicktext.updateContact({ - contactId: this.contactId, - name: this.name, - emailAddress: this.emailAddress, - city: this.city, - state: this.state, - zipCode: this.zipCode, - country: this.country, + const { + slicktext, + contactId, + ...data + } = this; + + const response = await slicktext.updateContact({ + $, + contactId, + data: objectCamelToSnakeCase(data), }); $.export("$summary", `Successfully updated contact with ID: ${this.contactId}`); diff --git a/components/slicktext/actions/opt-in-contact/opt-in-contact.mjs b/components/slicktext/actions/opt-in-contact/opt-in-contact.mjs deleted file mode 100644 index 4367857190c49..0000000000000 --- a/components/slicktext/actions/opt-in-contact/opt-in-contact.mjs +++ /dev/null @@ -1,88 +0,0 @@ -import slicktext from "../../slicktext.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "slicktext-opt-in-contact", - name: "Opt-In Contact", - description: "Add a new contact to your messaging list with a confirmation text. [See the documentation](https://api.slicktext.com/docs/v1/contacts)", - version: "0.0.{{ts}}", - type: "action", - props: { - slicktext, - contactNumber: { - propDefinition: [ - slicktext, - "contactNumber", - ], - }, - textwordId: { - propDefinition: [ - slicktext, - "textwordId", - ], - }, - doubleOptInMessage: { - type: "string", - label: "Double Opt-In Message", - description: "The confirmation message sent to the contact. They will need to reply YES to complete subscription. Must be 160 characters or less.", - optional: true, - }, - name: { - propDefinition: [ - slicktext, - "name", - ], - optional: true, - }, - emailAddress: { - propDefinition: [ - slicktext, - "emailAddress", - ], - optional: true, - }, - city: { - propDefinition: [ - slicktext, - "city", - ], - optional: true, - }, - state: { - propDefinition: [ - slicktext, - "state", - ], - optional: true, - }, - zipCode: { - propDefinition: [ - slicktext, - "zipCode", - ], - optional: true, - }, - country: { - propDefinition: [ - slicktext, - "country", - ], - optional: true, - }, - }, - async run({ $ }) { - const response = await this.slicktext.addContact({ - contactNumber: this.contactNumber, - textwordId: this.textwordId, - doubleOptInMessage: this.doubleOptInMessage, - name: this.name, - emailAddress: this.emailAddress, - city: this.city, - state: this.state, - zipCode: this.zipCode, - country: this.country, - }); - $.export("$summary", `Successfully initiated opt-in for contact with number: ${this.contactNumber}`); - return response; - }, -}; diff --git a/components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs b/components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs deleted file mode 100644 index cf4aa73932069..0000000000000 --- a/components/slicktext/actions/send-message-to-contact/send-message-to-contact.mjs +++ /dev/null @@ -1,42 +0,0 @@ -import slicktext from "../../slicktext.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "slicktext-send-message-to-contact", - name: "Send Message to Contact", - description: "Deliver a text message to a single contact. [See the documentation](https://api.slicktext.com/docs/v1/messages)", - version: "0.0.1", - type: "action", - props: { - slicktext, - contactNumber: { - propDefinition: [ - slicktext, - "contactNumber", - ], - }, - messageContent: { - propDefinition: [ - slicktext, - "messageContent", - ], - }, - textwordId: { - propDefinition: [ - slicktext, - "textwordId", - ], - }, - }, - async run({ $ }) { - const response = await this.slicktext.sendMessage({ - contactNumber: this.contactNumber, - messageContent: this.messageContent, - textwordId: this.textwordId, - }); - - const messageId = response.messageId || response.id || "unknown"; - $.export("$summary", `Message sent successfully. Message ID: ${messageId}`); - return response; - }, -}; diff --git a/components/slicktext/app/slicktext.app.ts b/components/slicktext/app/slicktext.app.ts deleted file mode 100644 index cf7f22419a1a3..0000000000000 --- a/components/slicktext/app/slicktext.app.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineApp } from "@pipedream/types"; - -export default defineApp({ - type: "app", - app: "slicktext", - propDefinitions: {}, - methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); - }, - }, -}); diff --git a/components/slicktext/common/constants.mjs b/components/slicktext/common/constants.mjs new file mode 100644 index 0000000000000..38b6153fb48fc --- /dev/null +++ b/components/slicktext/common/constants.mjs @@ -0,0 +1,15 @@ +export const LIMIT = 250; + +export const OPT_IN_STATUS_OPTIONS = [ + "not subscribed", + "subscribed", + "unsubscribed", + "blocked", +]; + +export const TIMEZONE_OPTIONS = [ + "America/New_York", + "America/Chicago", + "America/Denver", + "America/Los_Angeles", +]; diff --git a/components/slicktext/common/utils.mjs b/components/slicktext/common/utils.mjs new file mode 100644 index 0000000000000..f8a334dda44cb --- /dev/null +++ b/components/slicktext/common/utils.mjs @@ -0,0 +1,36 @@ +export const objectCamelToSnakeCase = (obj) => { + return Object.entries(obj).reduce((acc, [ + key, + value, + ]) => { + const newKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`); + acc[newKey] = value; + return acc; + } + , {}); +}; + +export const parseObject = (obj) => { + if (!obj) return undefined; + + 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") { + try { + return JSON.parse(obj); + } catch (e) { + return obj; + } + } + return obj; +}; diff --git a/components/slicktext/package.json b/components/slicktext/package.json index 7d77925292b8a..d0777228bc4a7 100644 --- a/components/slicktext/package.json +++ b/components/slicktext/package.json @@ -1,16 +1,18 @@ { "name": "@pipedream/slicktext", - "version": "0.0.3", + "version": "0.1.0", "description": "Pipedream SlickText Components", - "main": "dist/app/slicktext.app.mjs", + "main": "slicktext.app.mjs", "keywords": [ "pipedream", "slicktext" ], - "files": ["dist"], "homepage": "https://pipedream.com/apps/slicktext", "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } } diff --git a/components/slicktext/slicktext.app.mjs b/components/slicktext/slicktext.app.mjs index 625a1da1b8a84..6e076e5581e7d 100644 --- a/components/slicktext/slicktext.app.mjs +++ b/components/slicktext/slicktext.app.mjs @@ -1,4 +1,7 @@ import { axios } from "@pipedream/platform"; +import { + LIMIT, OPT_IN_STATUS_OPTIONS, TIMEZONE_OPTIONS, +} from "./common/constants.mjs"; export default { type: "app", @@ -8,124 +11,177 @@ export default { type: "string", label: "Contact ID", description: "The ID of the contact to be updated", + async options({ page }) { + const { data } = await this.listContacts({ + params: { + limit: LIMIT, + offset: LIMIT * page, + }, + }); + + return data.map(({ + contact_id: value, first_name: fName, last_name: lName, email, + }) => ({ + label: `${fName} ${lName} (${email})`, + value, + })); + }, }, - contactNumber: { - type: "string", - label: "Contact Number", - description: "The phone number of the contact. Must be at least 10 digits.", + listIds: { + type: "string[]", + label: "List IDs", + description: "A list of **List IDs** that represent the list(s) the contact will be added to", + async options({ page }) { + const { data } = await this.listLists({ + params: { + limit: LIMIT, + offset: LIMIT * page, + }, + }); + + return data.map(({ + contact_list_id: value, name: label, + }) => ({ + label, + value, + })); + }, }, - messageContent: { + mobileNumber: { type: "string", - label: "Message Content", - description: "The body of the text message you want to send.", + label: "Mobile Number", + description: "The US phone number of the contact. Must be at least 10 digits. It will be normalized to digits-only, preceded by a +", }, - textwordId: { + firstName: { type: "string", - label: "Textword ID", - description: "The ID of the textword", - async options() { - const response = await this._makeRequest({ - path: "/textwords", - }); - return response.textwords.map((textword) => ({ - label: textword.word, - value: textword.id, - })); - }, + label: "First Name", + description: "The first name of contact", }, - name: { + lastName: { type: "string", - label: "Name", - description: "The name of the contact", - optional: true, + label: "Last Name", + description: "The last name of contact", }, - emailAddress: { + email: { type: "string", label: "Email Address", description: "The email address of the contact", - optional: true, + }, + birthdate: { + type: "string", + label: "Birthdate", + description: "The birthday of the contact formatted as: YYYY-MM-DD", + }, + address: { + type: "string", + label: "Address", + description: "The street address of the contact", }, city: { type: "string", label: "City", description: "The city of the contact", - optional: true, }, state: { type: "string", label: "State", description: "The state of the contact", - optional: true, }, - zipCode: { + zip: { type: "string", label: "Zip Code", description: "The zip code of the contact", - optional: true, }, country: { type: "string", label: "Country", description: "The country of the contact", - optional: true, + }, + timezone: { + type: "string", + label: "Timezone", + description: "The time zone of contact", + options: TIMEZONE_OPTIONS, + }, + language: { + type: "string", + label: "Language", + description: "The primary language of contact (“en”)", + }, + optInStatus: { + type: "string", + label: "Opt-in Status", + description: "The opt-in status of contact (Default is not subscribed)", + options: OPT_IN_STATUS_OPTIONS, + }, + forceDoubleOptIn: { + type: "boolean", + label: "Force Double Opt-in", + description: "Set to “true” to force the user to agree to subscribing via double opt-in message", }, }, methods: { _baseUrl() { - return "https://api.slicktext.com/v1"; - }, - async _makeRequest(opts = {}) { - const { - $ = this, - method = "POST", - path = "/", - headers, - ...otherOpts - } = opts; + return "https://dev.slicktext.com/v1"; + }, + _headers() { + return { + authorization: `Bearer ${this.$auth.private_api_key}`, + }; + }, + _makeRequest({ + $ = this, path, ...opts + }) { return axios($, { - ...otherOpts, - method, url: this._baseUrl() + path, - headers: { - ...headers, - "Authorization": `Bearer ${this.$auth.api_key}`, - "Content-Type": "application/x-www-form-urlencoded", - }, + headers: this._headers(), + ...opts, + }); + }, + async getBrandId() { + const response = await this._makeRequest({ + path: "/brands", + }); + return response.brand_id; + }, + async listContacts(opts = {}) { + const brandId = await this.getBrandId(); + return this._makeRequest({ + path: `/brands/${brandId}/contacts`, + ...opts, + }); + }, + async listLists(opts = {}) { + const brandId = await this.getBrandId(); + return this._makeRequest({ + path: `/brands/${brandId}/lists`, + ...opts, }); }, - async updateContact(opts = {}) { + async createContact(opts = {}) { + const brandId = await this.getBrandId(); return this._makeRequest({ - path: "/contacts", - data: { - action: "EDIT", - contactId: opts.contactId, - name: opts.name, - emailAddress: opts.emailAddress, - city: opts.city, - state: opts.state, - zipCode: opts.zipCode, - country: opts.country, - }, + method: "POST", + path: `/brands/${brandId}/contacts`, + ...opts, }); }, - async sendMessage(opts = {}) { + async updateContact({ + contactId, ...opts + }) { + const brandId = await this.getBrandId(); return this._makeRequest({ - path: "/messages", - data: { - action: "SEND", - contactNumber: opts.contactNumber, - messageContent: opts.messageContent, - textwordId: opts.textwordId, - }, + method: "PUT", + path: `/brands/${brandId}/contacts/${contactId}`, + ...opts, }); }, - async addContact(opts = {}) { + async addContactToLists(opts = {}) { + const brandId = await this.getBrandId(); return this._makeRequest({ - path: "/contacts", - data: { - action: "DOUBLEOPTIN", - contactNumber: opts.contactNumber, - }, + method: "POST", + path: `/brands/${brandId}/lists/contacts`, + ...opts, }); }, }, From baba587ba0f2cc3978f0896ad37f7e140db84dd4 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 14 May 2025 15:59:51 -0300 Subject: [PATCH 3/5] pnpm update --- pnpm-lock.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c3b8832f2cc43..d583c81a55a11 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12134,7 +12134,11 @@ importers: components/slack_demo_app_1: {} - components/slicktext: {} + components/slicktext: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/slite: dependencies: From fc91541f7244d69ba9281ec0b24c75b44dadb383 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 15 May 2025 17:30:18 -0300 Subject: [PATCH 4/5] fix api key constant name --- components/slicktext/slicktext.app.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/slicktext/slicktext.app.mjs b/components/slicktext/slicktext.app.mjs index 6e076e5581e7d..a36812d5e550e 100644 --- a/components/slicktext/slicktext.app.mjs +++ b/components/slicktext/slicktext.app.mjs @@ -126,7 +126,7 @@ export default { }, _headers() { return { - authorization: `Bearer ${this.$auth.private_api_key}`, + authorization: `Bearer ${this.$auth.public_api_key}`, }; }, _makeRequest({ From 8edc06cdf53a54cbf34f7df258dac0e15cc9c657 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 15 May 2025 17:31:17 -0300 Subject: [PATCH 5/5] Update components/slicktext/actions/create-contact/create-contact.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- components/slicktext/actions/create-contact/create-contact.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/slicktext/actions/create-contact/create-contact.mjs b/components/slicktext/actions/create-contact/create-contact.mjs index e64467b8bd8ce..d336836b36847 100644 --- a/components/slicktext/actions/create-contact/create-contact.mjs +++ b/components/slicktext/actions/create-contact/create-contact.mjs @@ -35,7 +35,7 @@ export default { $, data: objectCamelToSnakeCase(data), }); - $.export("$summary", `Successfully initiated opt-in for contact with number: ${this.contactNumber}`); + $.export("$summary", `Successfully initiated opt-in for contact with number: ${this.mobileNumber}`); return response; }, };