diff --git a/components/firefish/actions/unsubscribe-email/unsubscribe-email.mjs b/components/firefish/actions/unsubscribe-email/unsubscribe-email.mjs new file mode 100644 index 0000000000000..2e3c55902b16c --- /dev/null +++ b/components/firefish/actions/unsubscribe-email/unsubscribe-email.mjs @@ -0,0 +1,54 @@ +import firefish from "../../firefish.app.mjs"; + +export default { + key: "firefish-unsubscribe-email", + name: "Unsubscribe Email", + description: "Removes a particular contact or candidate from all existing firefish email subscriptions. [See the documentatio](https://developer.firefishsoftware.com/#002bb8c0-0b41-4016-b33c-026a46b499b2)", + version: "0.0.1", + type: "action", + props: { + firefish, + email: { + type: "string", + label: "Email", + description: "The email address of the subscriber you want to remove", + }, + }, + async run({ $ }) { + const contacts = await this.firefish.searchContacts({ + $, + params: { + "email-address": this.email, + }, + }); + for (const contact of contacts) { + contact.EmailMarketing = false; + await this.firefish.updateContact({ + $, + contactId: contact.Ref, + data: contact, + }); + } + + const candidates = await this.firefish.searchCandidates({ + $, + params: { + "email-address": this.email, + }, + }); + for (const candidate of candidates) { + candidate.EmailMarketing = false; + await this.firefish.updateCandidate({ + $, + candidateId: candidate.Ref, + data: candidate, + }); + } + + $.export("$summary", `Successfully removed ${this.email} from email marketing`); + return { + contacts, + candidates, + }; + }, +}; diff --git a/components/firefish/firefish.app.mjs b/components/firefish/firefish.app.mjs index e5480983a331e..e157fdaba7120 100644 --- a/components/firefish/firefish.app.mjs +++ b/components/firefish/firefish.app.mjs @@ -1,11 +1,56 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "firefish", propDefinitions: {}, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://api.firefishsoftware.com/api/v1.0"; + }, + _makeRequest(opts = {}) { + const { + $ = this, + path, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + url: `${this._baseUrl()}${path}`, + headers: { + Authorization: `Bearer ${this.$auth.oauth_access_token}`, + }, + }); + }, + searchContacts(opts = {}) { + return this._makeRequest({ + path: "/contacts/search", + ...opts, + }); + }, + searchCandidates(opts = {}) { + return this._makeRequest({ + path: "/candidates/search", + ...opts, + }); + }, + updateContact({ + contactId, ...opts + }) { + return this._makeRequest({ + method: "PUT", + path: `/contacts/${contactId}`, + ...opts, + }); + }, + updateCandidate({ + candidateId, ...opts + }) { + return this._makeRequest({ + method: "PUT", + path: `/candidates/${candidateId}`, + ...opts, + }); }, }, -}; \ No newline at end of file +}; diff --git a/components/firefish/package.json b/components/firefish/package.json index 9c189fbce807d..b80e5bcd3d986 100644 --- a/components/firefish/package.json +++ b/components/firefish/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/firefish", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Firefish Components", "main": "firefish.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.1" } -} \ No newline at end of file +} diff --git a/components/firefish/sources/common/base.mjs b/components/firefish/sources/common/base.mjs new file mode 100644 index 0000000000000..2dfc6391be083 --- /dev/null +++ b/components/firefish/sources/common/base.mjs @@ -0,0 +1,57 @@ +import firefish from "../../firefish.app.mjs"; +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; + +export default { + props: { + firefish, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + hooks: { + async deploy() { + await this.processEvent(25); + }, + }, + methods: { + _getLastCreated() { + return this.db.get("lastCreated"); + }, + _setLastCreated(lastCreated) { + this.db.set("lastCreated", lastCreated); + }, + async processEvent(limit) { + const lastCreated = this._getLastCreated(); + const resourceFn = this.getResourceFn(); + const results = await resourceFn({ + params: { + "from-date": lastCreated && lastCreated.slice(0, 10), + }, + }); + if (!results?.length) { + return; + } + this._setLastCreated(results[0].Created); + if (limit && results.length > limit) { + results.length = limit; + } + results.reverse().forEach((result) => { + const meta = this.generateMeta(result); + this.$emit(result, meta); + }); + }, + getResourceFn() { + throw new Error("getResourceFn is not implemented"); + }, + generateMeta() { + throw new Error("generateMeta is not implemented"); + }, + }, + async run() { + await this.processEvent(); + }, +}; diff --git a/components/firefish/sources/new-candidate-created/new-candidate-created.mjs b/components/firefish/sources/new-candidate-created/new-candidate-created.mjs new file mode 100644 index 0000000000000..b788fc67f9d22 --- /dev/null +++ b/components/firefish/sources/new-candidate-created/new-candidate-created.mjs @@ -0,0 +1,26 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "firefish-new-candidate-created", + name: "New Candidate Created", + description: "Emit new event when a new candidate is created. [See the documentation](https://developer.firefishsoftware.com/#0dc51713-8397-4aaa-a85e-a66eb8f94d9d)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.firefish.searchCandidates; + }, + generateMeta(candidate) { + return { + id: candidate.Ref, + summary: `New Candidate ID: ${candidate.Ref}`, + ts: Date.parse(candidate.Created), + }; + }, + }, + sampleEmit, +}; diff --git a/components/firefish/sources/new-candidate-created/test-event.mjs b/components/firefish/sources/new-candidate-created/test-event.mjs new file mode 100644 index 0000000000000..0865176c4b4a2 --- /dev/null +++ b/components/firefish/sources/new-candidate-created/test-event.mjs @@ -0,0 +1,28 @@ +export default { + "Ref": 48889, + "FirstName": "Gerardo", + "Surname": "Smitho", + "DateOfBirth": null, + "JobTitle": null, + "EmailAddress": "gerard.firefish@gmail.com", + "Address": { + "Address1": null, + "Address2": null, + "Address3": null, + "Town": null, + "County": null, + "Country": null, + "PostCode": null + }, + "MobileNumber": "07595878736", + "HomeNumber": null, + "WorkNumber": null, + "IsArchived": false, + "CreatedBy": "Superuser Role", + "Created": "2024-02-09T09:39:01.383Z", + "UpdatedBy": "Gerardo Smitho", + "Updated": "2024-02-09T09:43:13.773Z", + "LastActionRef": 80198, + "LastActionName": "Advert Application", + "LastActionDate": "2024-02-09T09:51:56.007Z" +} \ No newline at end of file diff --git a/components/firefish/sources/new-contact-created/new-contact-created.mjs b/components/firefish/sources/new-contact-created/new-contact-created.mjs new file mode 100644 index 0000000000000..08ad4c6c8f710 --- /dev/null +++ b/components/firefish/sources/new-contact-created/new-contact-created.mjs @@ -0,0 +1,26 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "firefish-new-contact-created", + name: "New Contact Created", + description: "Emit new event when a new contact is created. [See the documentation](https://developer.firefishsoftware.com/#fcb38fee-8ad7-4aec-b1bd-ba7871e8258c)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.firefish.searchContacts; + }, + generateMeta(contact) { + return { + id: contact.Ref, + summary: `New Contact ID: ${contact.Ref}`, + ts: Date.parse(contact.Created), + }; + }, + }, + sampleEmit, +}; diff --git a/components/firefish/sources/new-contact-created/test-event.mjs b/components/firefish/sources/new-contact-created/test-event.mjs new file mode 100644 index 0000000000000..6075ad41917b7 --- /dev/null +++ b/components/firefish/sources/new-contact-created/test-event.mjs @@ -0,0 +1,20 @@ +export default { + "Ref": 48749, + "FirstName": "Kade", + "Surname": "Tran", + "Title": null, + "CompanyRef": null, + "CompanyName": null, + "JobTitle": "EMS Helicopter Pilot", + "EmailAddress": "Kade@dud.com", + "MobileNumber": null, + "WorkNumber": null, + "IsArchived": false, + "CreatedBy": "System Administrator", + "Created": "2020-03-24T08:53:00.830Z", + "UpdatedBy": "System Administrator", + "Updated": "2020-03-24T08:53:00.830Z", + "LastActionRef": 78075, + "LastActionName": "Create Contact - Manual", + "LastActionDate": "2020-03-24T08:53:00.847Z" +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ca71dd16f7a73..4717495443cff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3300,7 +3300,10 @@ importers: '@pipedream/platform': 3.0.0 components/firefish: - specifiers: {} + specifiers: + '@pipedream/platform': ^3.0.1 + dependencies: + '@pipedream/platform': 3.0.1 components/fireflies: specifiers: @@ -12665,6 +12668,55 @@ packages: - aws-crt dev: false + /@aws-sdk/client-sso-oidc/3.600.0_tdq3komn4zwyd65w7klbptsu34: + resolution: {integrity: sha512-7+I8RWURGfzvChyNQSyj5/tKrqRbzRl7H+BnTOf/4Vsw1nFOi5ROhlhD4X/Y0QCTacxnaoNcIrqnY7uGGvVRzw==} + engines: {node: '>=16.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sts': 3.600.0 + '@aws-sdk/core': 3.598.0 + '@aws-sdk/credential-provider-node': 3.600.0_f7n47caigsrjd2lr2szmwfuee4 + '@aws-sdk/middleware-host-header': 3.598.0 + '@aws-sdk/middleware-logger': 3.598.0 + '@aws-sdk/middleware-recursion-detection': 3.598.0 + '@aws-sdk/middleware-user-agent': 3.598.0 + '@aws-sdk/region-config-resolver': 3.598.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-endpoints': 3.598.0 + '@aws-sdk/util-user-agent-browser': 3.598.0 + '@aws-sdk/util-user-agent-node': 3.598.0 + '@smithy/config-resolver': 3.0.3 + '@smithy/core': 2.2.3 + '@smithy/fetch-http-handler': 3.2.1 + '@smithy/hash-node': 3.0.2 + '@smithy/invalid-dependency': 3.0.2 + '@smithy/middleware-content-length': 3.0.2 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-retry': 3.0.6 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/node-http-handler': 3.1.2 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.6 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.6 + '@smithy/util-defaults-mode-node': 3.0.6 + '@smithy/util-endpoints': 2.0.3 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.2 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sts' + - aws-crt + dev: false + /@aws-sdk/client-sso/3.423.0: resolution: {integrity: sha512-znIufHkwhCIePgaYciIs3x/+BpzR57CZzbCKHR9+oOvGyufEPPpUT5bFLvbwTgfiVkTjuk6sG/ES3U5Bc+xtrA==} engines: {node: '>=14.0.0'} @@ -12900,55 +12952,7 @@ packages: dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.600.0 - '@aws-sdk/core': 3.598.0 - '@aws-sdk/credential-provider-node': 3.600.0_f7n47caigsrjd2lr2szmwfuee4 - '@aws-sdk/middleware-host-header': 3.598.0 - '@aws-sdk/middleware-logger': 3.598.0 - '@aws-sdk/middleware-recursion-detection': 3.598.0 - '@aws-sdk/middleware-user-agent': 3.598.0 - '@aws-sdk/region-config-resolver': 3.598.0 - '@aws-sdk/types': 3.598.0 - '@aws-sdk/util-endpoints': 3.598.0 - '@aws-sdk/util-user-agent-browser': 3.598.0 - '@aws-sdk/util-user-agent-node': 3.598.0 - '@smithy/config-resolver': 3.0.3 - '@smithy/core': 2.2.3 - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/hash-node': 3.0.2 - '@smithy/invalid-dependency': 3.0.2 - '@smithy/middleware-content-length': 3.0.2 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.6 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.2 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.6 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.6 - '@smithy/util-defaults-mode-node': 3.0.6 - '@smithy/util-endpoints': 2.0.3 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.2 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.3 - transitivePeerDependencies: - - aws-crt - dev: false - - /@aws-sdk/client-sts/3.600.0_dseaa2p5u2yk67qiepewcq3hkq: - resolution: {integrity: sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.600.0 + '@aws-sdk/client-sso-oidc': 3.600.0_tdq3komn4zwyd65w7klbptsu34 '@aws-sdk/core': 3.598.0 '@aws-sdk/credential-provider-node': 3.600.0_f7n47caigsrjd2lr2szmwfuee4 '@aws-sdk/middleware-host-header': 3.598.0 @@ -12987,7 +12991,6 @@ packages: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - aws-crt dev: false @@ -17289,7 +17292,7 @@ packages: '@aws-sdk/client-sns': 3.423.0 '@aws-sdk/client-sqs': 3.423.0 '@aws-sdk/client-ssm': 3.423.0 - '@aws-sdk/client-sts': 3.600.0_dseaa2p5u2yk67qiepewcq3hkq + '@aws-sdk/client-sts': 3.600.0 '@aws-sdk/s3-request-presigner': 3.609.0 '@pipedream/helper_functions': 0.3.12 '@pipedream/platform': 1.6.6 @@ -33713,7 +33716,7 @@ packages: mime: 2.6.0 qs: 6.12.0 readable-stream: 3.6.2 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color dev: false