diff --git a/components/domain_group/actions/create-business-listing/create-business-listing.mjs b/components/domain_group/actions/create-business-listing/create-business-listing.mjs new file mode 100644 index 0000000000000..186206aae1dce --- /dev/null +++ b/components/domain_group/actions/create-business-listing/create-business-listing.mjs @@ -0,0 +1,157 @@ +import domainGroup from "../../domain_group.app.mjs"; +import { BUSINESS_TYPES } from "../../common/property-types.mjs"; + +export default { + key: "domain_group-create-business-listing", + name: "Create Business Listing", + description: "Creates a new business listing. [See the documentation](https://developer.domain.com.au/docs/latest/apis/pkg_listing_management/references/listings_upsertbusinesslisting/).", + version: "0.0.1", + type: "action", + props: { + domainGroup, + agencyId: { + propDefinition: [ + domainGroup, + "agencyId", + ], + }, + providerAdId: { + propDefinition: [ + domainGroup, + "providerAdId", + ], + }, + propertyType: { + propDefinition: [ + domainGroup, + "propertyType", + ], + options: BUSINESS_TYPES, + }, + listingAction: { + propDefinition: [ + domainGroup, + "listingAction", + ], + }, + underOfferOrContract: { + propDefinition: [ + domainGroup, + "underOfferOrContract", + ], + }, + nabers: { + propDefinition: [ + domainGroup, + "nabers", + ], + }, + fromPrice: { + propDefinition: [ + domainGroup, + "fromPrice", + ], + }, + toPrice: { + propDefinition: [ + domainGroup, + "toPrice", + ], + }, + description: { + propDefinition: [ + domainGroup, + "description", + ], + }, + features: { + propDefinition: [ + domainGroup, + "features", + ], + }, + streetNumber: { + propDefinition: [ + domainGroup, + "streetNumber", + ], + }, + unitNumber: { + propDefinition: [ + domainGroup, + "unitNumber", + ], + }, + street: { + propDefinition: [ + domainGroup, + "street", + ], + }, + state: { + propDefinition: [ + domainGroup, + "state", + ], + }, + suburb: { + propDefinition: [ + domainGroup, + "suburb", + ], + }, + postcode: { + propDefinition: [ + domainGroup, + "postcode", + ], + }, + receiveEmailsToDefaultAddress: { + propDefinition: [ + domainGroup, + "receiveEmailsToDefaultAddress", + ], + }, + isRural: { + propDefinition: [ + domainGroup, + "isRural", + ], + }, + }, + async run({ $ }) { + const response = await this.domainGroup.createBusinessListing({ + $, + data: { + domainAgencyID: this.agencyId, + providerAdId: this.providerAdId, + listingAction: this.listingAction, + underOfferOrContract: this.underOfferOrContract, + nabers: this.nabers && +this.nabers, + price: { + from: this.fromPrice, + to: this.toPrice, + }, + description: this.description, + features: this.features, + propertyDetails: { + propertyType: [ + this.propertyType, + ], + address: { + streetNumber: this.streetNumber, + unitNumber: this.unitNumber, + street: this.street, + state: this.state, + suburb: this.suburb, + postcode: this.postcode, + }, + }, + receiveEmailsToDefaultAddress: this.receiveEmailsToDefaultAddress, + isRural: this.isRural, + }, + }); + $.export("$summary", `Created business listing with ID: ${response.id}`); + return response; + }, +}; diff --git a/components/domain_group/actions/create-commercial-listing/create-commercial-listing.mjs b/components/domain_group/actions/create-commercial-listing/create-commercial-listing.mjs new file mode 100644 index 0000000000000..c2cfd6071a4da --- /dev/null +++ b/components/domain_group/actions/create-commercial-listing/create-commercial-listing.mjs @@ -0,0 +1,231 @@ +import domainGroup from "../../domain_group.app.mjs"; +import { COMMERCIAL_TYPES } from "../../common/property-types.mjs"; + +export default { + key: "domain_group-create-commercial-listing", + name: "Create Commercial Listing", + description: "Creates a new commercial listing. [See the documentation](https://developer.domain.com.au/docs/latest/apis/pkg_listing_management/references/listings_upsertcommerciallisting/).", + version: "0.0.1", + type: "action", + props: { + domainGroup, + agencyId: { + propDefinition: [ + domainGroup, + "agencyId", + ], + }, + providerAdId: { + propDefinition: [ + domainGroup, + "providerAdId", + ], + }, + propertyType: { + propDefinition: [ + domainGroup, + "propertyType", + ], + options: COMMERCIAL_TYPES, + }, + listingAction: { + propDefinition: [ + domainGroup, + "listingAction", + ], + reloadProps: true, + }, + underOfferOrContract: { + propDefinition: [ + domainGroup, + "underOfferOrContract", + ], + }, + nabers: { + propDefinition: [ + domainGroup, + "nabers", + ], + }, + description: { + propDefinition: [ + domainGroup, + "description", + ], + }, + features: { + propDefinition: [ + domainGroup, + "features", + ], + }, + streetNumber: { + propDefinition: [ + domainGroup, + "streetNumber", + ], + }, + unitNumber: { + propDefinition: [ + domainGroup, + "unitNumber", + ], + }, + street: { + propDefinition: [ + domainGroup, + "street", + ], + }, + state: { + propDefinition: [ + domainGroup, + "state", + ], + }, + suburb: { + propDefinition: [ + domainGroup, + "suburb", + ], + }, + postcode: { + propDefinition: [ + domainGroup, + "postcode", + ], + }, + areaValue: { + type: "string", + label: "Area Value", + description: "The size of the area in the commercial listing", + }, + areaUnit: { + type: "string", + label: "Area Unit", + description: "The unit of measure of the area value", + options: [ + "squareMetres", + "acres", + "hectares", + "squareFeet", + "squareYards", + "squares", + ], + }, + receiveEmailsToDefaultAddress: { + propDefinition: [ + domainGroup, + "receiveEmailsToDefaultAddress", + ], + }, + isRural: { + propDefinition: [ + domainGroup, + "isRural", + ], + }, + occupancyType: { + type: "string", + label: "Occupancy Type", + description: "The occupancy type of the listing", + options: [ + "tenanted", + "vacant", + ], + optional: true, + }, + }, + additionalProps() { + const props = {}; + if (!this.listingAction) { + return props; + } + + const saleFromPrice = { + type: "integer", + label: "Sale - From Price", + description: "Lowest price the property is expected to sell for to set search price. For a fixed price, set this value the same as To Price", + }; + const saleToPrice = { + type: "integer", + label: "Sale - To Price", + description: "Highest price the property is expected to sell for to set search price. For a fixed price, set this value the same as From Price", + }; + const leaseFromPrice = { + type: "integer", + label: "Lease - From Price", + description: "Lowest price the property is expected to rent for to set search price. For a fixed price, set this value the same as To Price", + }; + const leaseToPrice = { + type: "integer", + label: "Lease - To Price", + description: "Highest price the property is expected to rent for to set search price. For a fixed price, set this value the same as From Price", + }; + + if (this.listingAction === "sale") { + props.saleFromPrice = saleFromPrice; + props.saleToPrice = saleToPrice; + } + if (this.listingAction === "rent") { + props.leaseFromPrice = leaseFromPrice; + props.leaseToPrice = leaseToPrice; + } + if (this.listingAction === "saleAndLease") { + props.saleFromPrice = saleFromPrice; + props.saleToPrice = saleToPrice; + props.leaseFromPrice = leaseFromPrice; + props.leaseToPrice = leaseToPrice; + } + + return props; + }, + async run({ $ }) { + const response = await this.domainGroup.createCommercialListing({ + $, + data: { + domainAgencyID: this.agencyId, + providerAdId: this.providerAdId, + nabers: this.nabers, + listingAction: this.listingAction, + underOfferOrContract: this.underOfferOrContract, + salePrice: this.saleFromPrice + ? { + from: this.saleFromPrice, + to: this.saleToPrice, + } + : undefined, + leasePrice: this.leaseFromPrice + ? { + from: this.leaseFromPrice, + to: this.leaseToPrice, + } + : undefined, + description: this.description, + features: this.features, + propertyDetails: { + propertyType: [ + this.propertyType, + ], + address: { + streetNumber: this.streetNumber, + unitNumber: this.unitNumber, + street: this.street, + state: this.state, + suburb: this.suburb, + postcode: this.postcode, + }, + area: { + value: +this.areaValue, + unit: this.areaUnit, + }, + }, + receiveEmailsToDefaultAddress: this.receiveEmailsToDefaultAddress, + isRural: this.isRural, + occupancyType: this.occupancyType, + }, + }); + $.export("$summary", `Created commercial listing with ID: ${response.id}`); + return response; + }, +}; diff --git a/components/domain_group/actions/create-residential-listing/create-residential-listing.mjs b/components/domain_group/actions/create-residential-listing/create-residential-listing.mjs new file mode 100644 index 0000000000000..2c4973645986a --- /dev/null +++ b/components/domain_group/actions/create-residential-listing/create-residential-listing.mjs @@ -0,0 +1,150 @@ +import domainGroup from "../../domain_group.app.mjs"; +import { RESIDENTIAL_TYPES } from "../../common/property-types.mjs"; + +export default { + key: "domain_group-create-residential-listing", + name: "Create Residential Listing", + description: "Creates a new residential listing. [See the documentation](https://developer.domain.com.au/docs/latest/apis/pkg_listing_management/references/listings_upsertresidentiallisting/)", + version: "0.0.1", + type: "action", + props: { + domainGroup, + agencyId: { + propDefinition: [ + domainGroup, + "agencyId", + ], + }, + providerAdId: { + propDefinition: [ + domainGroup, + "providerAdId", + ], + }, + propertyType: { + propDefinition: [ + domainGroup, + "propertyType", + ], + options: RESIDENTIAL_TYPES, + }, + listingAction: { + propDefinition: [ + domainGroup, + "listingAction", + ], + }, + underOfferOrContract: { + propDefinition: [ + domainGroup, + "underOfferOrContract", + ], + }, + fromPrice: { + propDefinition: [ + domainGroup, + "fromPrice", + ], + }, + toPrice: { + propDefinition: [ + domainGroup, + "toPrice", + ], + }, + description: { + propDefinition: [ + domainGroup, + "description", + ], + }, + features: { + propDefinition: [ + domainGroup, + "features", + ], + }, + streetNumber: { + propDefinition: [ + domainGroup, + "streetNumber", + ], + }, + unitNumber: { + propDefinition: [ + domainGroup, + "unitNumber", + ], + }, + street: { + propDefinition: [ + domainGroup, + "street", + ], + }, + state: { + propDefinition: [ + domainGroup, + "state", + ], + }, + suburb: { + propDefinition: [ + domainGroup, + "suburb", + ], + }, + postcode: { + propDefinition: [ + domainGroup, + "postcode", + ], + }, + receiveEmailsToDefaultAddress: { + propDefinition: [ + domainGroup, + "receiveEmailsToDefaultAddress", + ], + }, + isRural: { + propDefinition: [ + domainGroup, + "isRural", + ], + }, + }, + async run({ $ }) { + const response = await this.domainGroup.createResidentialListing({ + $, + data: { + domainAgencyID: this.agencyId, + providerAdId: this.providerAdId, + listingAction: this.listingAction, + underOfferOrContract: this.underOfferOrContract, + price: { + from: this.fromPrice, + to: this.toPrice, + }, + description: this.description, + features: this.features, + propertyDetails: { + propertyType: [ + this.propertyType, + ], + address: { + streetNumber: this.streetNumber, + unitNumber: this.unitNumber, + street: this.street, + state: this.state, + suburb: this.suburb, + postcode: this.postcode, + }, + }, + receiveEmailsToDefaultAddress: this.receiveEmailsToDefaultAddress, + isRural: this.isRural, + }, + }); + $.export("$summary", `Created residential listing with ID: ${response.id}`); + return response; + }, +}; diff --git a/components/domain_group/common/property-types.mjs b/components/domain_group/common/property-types.mjs new file mode 100644 index 0000000000000..1a11a533e7c0b --- /dev/null +++ b/components/domain_group/common/property-types.mjs @@ -0,0 +1,288 @@ +const BUSINESS_TYPES = [ + "accessoriesParts", + "accommodationTourism", + "accounting", + "adult", + "advertisingMarketing", + "aerial", + "aeronautical", + "agedCare", + "agricultural", + "air", + "aircraft", + "alarms", + "alcoholLiquor", + "amusements", + "animalRelated", + "aquaculture", + "aquaticMarineMarinaBerth", + "artsCrafts", + "autoElectrical", + "automotive", + "backpackerHostel", + "bakery", + "barsNightclubs", + "beautyHealth", + "beautyProducts", + "beautySalon", + "bikeAndMotorcycle", + "boardingKennels", + "boatsMarineMarinaBerth", + "bookkeeping", + "brokerage", + "builder", + "buildingAndConstruction", + "bus", + "butcher", + "cafeCoffeeShop", + "car", + "carBusTruck", + "carDealership", + "carRental", + "carWash", + "caravanPark", + "carpenter", + "catering", + "childCare", + "civil", + "cleaning", + "cleaningAndMaintenance", + "clinicalPractice", + "clothingAccessories", + "clothingFootwear", + "communication", + "communications", + "computerIT", + "computerAndInternet", + "construction", + "convenienceStore", + "copyLaminate", + "courier", + "cropHarvesting", + "customs", + "dairyFarming", + "deli", + "dental", + "detailing", + "distributors", + "drivingSchools", + "educationTraining", + "educational", + "electrical", + "employmentRecruitment", + "entertainment", + "entertainmentTechnology", + "export", + "farming", + "fertiliser", + "finance", + "financialServices", + "fishingForestry", + "floristNursery", + "foodBeverage", + "foodBeverageHospitality", + "franchiseBusinessOpportunities", + "freight", + "fruitVegFreshProduce", + "fruitPicking", + "functionCentre", + "furnitureTimber", + "gambling", + "gardenHousehold", + "gardenNurseries", + "gardening", + "glassCeramic", + "guestHouseBB", + "hairdresser", + "healthBeauty", + "healthSpa", + "hire", + "homeGarden", + "homeBased", + "homewareHardware", + "hospital", + "hotel", + "huntingTrap", + "import", + "importExportWholesale", + "industrialManufacturing", + "insemination", + "insurance", + "internet", + "irrigationServices", + "juiceBar", + "landClearing", + "landscaping", + "laundryDryCleaning", + "legal", + "leisureEntertainment", + "limousineTaxi", + "livestock", + "machinery", + "machineryMetal", + "managementRights", + "manufacturers", + "manufacturingEngineering", + "marine", + "massage", + "mechanicalRepair", + "media", + "medical", + "medicalPractice", + "miningEarthMoving", + "mobileServices", + "motel", + "motorcycle", + "musicRelated", + "mustering", + "nails", + "naturalTherapies", + "newsagency", + "nursery", + "nursingHome", + "officeSupplies", + "oilGas", + "panelBeating", + "paperPrinting", + "parkingCarSpace", + "pestRelated", + "pharmacies", + "plastic", + "plumbing", + "poolWater", + "postOffices", + "printPhoto", + "professional", + "propertyRealEstate", + "rail", + "recreationSport", + "recruitment", + "repair", + "resort", + "restaurant", + "retail", + "retailer", + "retirement", + "retirementVillage", + "road", + "rural", + "scientific", + "sea", + "security", + "serviceStation", + "services", + "shearing", + "sportsComplexGym", + "supermarket", + "takeawayFood", + "taxi", + "themePark", + "tours", + "training", + "transportDistribution", + "travel", + "truck", + "vending", + "water", + "welding", + "wholesale", + "wholesalers", + "woolClassing", + "wreckers", + "alcoholGrocery", + "cafeRestaurants", + "discountStore", + "ecoFriendly", + "green", + "grocery", + "specialityRetail", + "storage", + "travelAgency", + "varietyStore", + "chickenShop", + "seafoodShop", + "deliCafe", + "cropping", + "viticulture", + "grazing", + "horticulture", + "equine", + "farmlet", + "orchard", + "ruralLifestyle", + "onlineBusiness", +]; + +const RESIDENTIAL_TYPES = [ + "acreageSemiRural", + "apartmentUnitFlat", + "aquaculture", + "blockOfUnits", + "carSpace", + "dairyFarming", + "developmentSite", + "duplex", + "farm", + "fishingForestry", + "newHomeDesigns", + "house", + "newHouseLand", + "irrigationServices", + "newLand", + "livestock", + "newApartments", + "penthouse", + "retirement", + "rural", + "semiDetached", + "specialistFarm", + "studio", + "terrace", + "townhouse", + "vacantLand", + "villa", + "cropping", + "viticulture", + "mixedFarming", + "grazing", + "horticulture", + "equine", + "farmlet", + "orchard", + "ruralLifestyle", +]; + +const COMMERCIAL_TYPES = [ + "aquaculture", + "dairyFarming", + "developmentLand", + "fishingForestry", + "hotelLeisure", + "industrialWarehouse", + "irrigationServices", + "livestock", + "internationalCommercial", + "medicalConsulting", + "offices", + "parkingCarSpace", + "retail", + "ruralCommercialFarming", + "showroomsBulkyGoods", + "servicedOffices", + "other", + "cropping", + "viticulture", + "mixedFarming", + "grazing", + "horticulture", + "equine", + "farmlet", + "orchard", + "ruralLifestyle", +]; + +export { + BUSINESS_TYPES, + RESIDENTIAL_TYPES, + COMMERCIAL_TYPES, +}; diff --git a/components/domain_group/domain_group.app.mjs b/components/domain_group/domain_group.app.mjs index 99e791ea63823..79f4371b25d9a 100644 --- a/components/domain_group/domain_group.app.mjs +++ b/components/domain_group/domain_group.app.mjs @@ -1,11 +1,204 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "domain_group", - propDefinitions: {}, + propDefinitions: { + agencyId: { + type: "string", + label: "Agency ID", + description: "The identifier of an agency", + async options() { + const agencies = await this.listAgencies(); + return agencies.map((agency) => ({ + label: agency.name, + value: agency.id, + })); + }, + }, + providerAdId: { + type: "string", + label: "Provider Ad ID", + description: "Must be unique. If Provider Ad ID supplied already exists, the listing will be updated. External Advertisement Id of up to 50 characters will be stored.
This value is used to identify an Advertisement for updates and should be unique for listing provider.
This value is case-insensitive (meaning AAAA will update aaaa).", + }, + listingAction: { + type: "string", + label: "Listing Action", + description: "The type of listing action", + options: [ + "sale", + "rent", + "saleAndLease", + ], + }, + propertyType: { + type: "string", + label: "Property Type", + description: "The type of property", + }, + underOfferOrContract: { + type: "boolean", + label: "Under Offer or Contract", + description: "Set for Sale listings only", + optional: true, + }, + nabers: { + type: "string", + label: "NABERS", + description: "The NABERS Rating is the energy efficiency rating that the property has been measured to have. This rating is measured in increments of .5 and can range from 0 to 6. The NABERS rating is required for spaces within office buildings of 1000 square metres or more. For more information on the NABERS rating system please visit [http://www.nabers.gov.au](http://www.nabers.gov.au)", + optional: true, + }, + fromPrice: { + type: "integer", + label: "From Price", + description: "Lowest price the property is expected to sell/rent for to set search price. For a fixed price, set this value the same as To Price", + }, + toPrice: { + type: "integer", + label: "To Price", + description: "Highest price the property is expected to sell/rent for to set search price. For a fixed price, set this value the same as From Price", + }, + description: { + type: "string", + label: "Description", + description: "Description of the property", + optional: true, + }, + features: { + type: "string", + label: "Features", + description: "Comma-separated list of features", + optional: true, + }, + streetNumber: { + type: "string", + label: "Street Number", + description: "Street number of the listing address", + }, + unitNumber: { + type: "string", + label: "Unit Number", + description: "Unit number of the listing address", + optional: true, + }, + street: { + type: "string", + label: "Street", + description: "Street of the listing address", + }, + state: { + type: "string", + label: "State", + description: "State of the listing address", + options: [ + "nsw", + "vic", + "act", + "sa", + "wa", + "tas", + "qld", + "nt", + ], + }, + suburb: { + type: "string", + label: "Suburb", + description: "Suburb of the listing address", + }, + postcode: { + type: "string", + label: "Postcode", + description: "Post code of the listing address", + }, + receiveEmailsToDefaultAddress: { + type: "boolean", + label: "Receive Emails to Default Address", + description: "Send email enquiries to the default address for this listing type", + optional: true, + }, + isRural: { + type: "boolean", + label: "Is Rural?", + description: "True if the property is rural", + optional: true, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return `${this.$auth.api_url}`; + }, + _makeRequest({ + $ = this, + path, + ...otherOpts + }) { + return axios($, { + ...otherOpts, + url: `${this._baseUrl()}${path}`, + headers: { + Authorization: `Bearer ${this.$auth.oauth_access_token}`, + }, + }); + }, + listAgencies() { + return this._makeRequest({ + path: "/v1/me/agencies", + }); + }, + listAgencyListings({ + agencyId, ...opts + }) { + return this._makeRequest({ + path: `/v1/agencies/${agencyId}/listings`, + ...opts, + }); + }, + createBusinessListing(opts = {}) { + return this._makeRequest({ + method: "PUT", + path: "/v1/listings/business", + ...opts, + }); + }, + createResidentialListing(opts = {}) { + return this._makeRequest({ + method: "PUT", + path: "/v1/listings/residential", + ...opts, + }); + }, + createCommercialListing(opts = {}) { + return this._makeRequest({ + method: "PUT", + path: "/v2/listings/commercial", + ...opts, + }); + }, + async *paginate({ + resourceFn, + args, + max, + }) { + let total, count = 0; + args = { + ...args, + params: { + ...args.params, + pageNumber: 1, + }, + }; + do { + const items = await resourceFn(args); + for (const item of items) { + yield item; + if (max && ++count >= max) { + return; + } + } + total = items.length; + args.params.pageNumber++; + } while (total); }, }, -}; \ No newline at end of file +}; diff --git a/components/domain_group/package.json b/components/domain_group/package.json index 3660a1450678d..dc6e5ca3ce7c0 100644 --- a/components/domain_group/package.json +++ b/components/domain_group/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/domain_group", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Domain Group Components", "main": "domain_group.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } -} \ No newline at end of file +} diff --git a/components/domain_group/sources/agency-listing-updated/agency-listing-updated.mjs b/components/domain_group/sources/agency-listing-updated/agency-listing-updated.mjs new file mode 100644 index 0000000000000..6e86067e1e1b4 --- /dev/null +++ b/components/domain_group/sources/agency-listing-updated/agency-listing-updated.mjs @@ -0,0 +1,48 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "domain_group-agency-listing-updated", + name: "Agency Listing Updated", + description: "Emit new event when an agency listing is updated. [See the documentation](https://developer.domain.com.au/docs/latest/apis/pkg_listing_management/references/agencies_getlistings/)", + version: "0.0.1", + type: "source", + dedupe: "unique", + props: { + ...common.props, + agencyId: { + propDefinition: [ + common.props.domainGroup, + "agencyId", + ], + }, + }, + methods: { + ...common.methods, + getResourceFn() { + return this.domainGroup.listAgencyListings; + }, + getArgs(lastTs) { + const args = { + agencyId: this.agencyId, + }; + if (lastTs) { + args.params = { + dateUpdatedSince: lastTs, + }; + } + return args; + }, + getTsField() { + return "dateUpdated"; + }, + generateMeta(item) { + const ts = Date.parse(item[this.getTsField()]); + return { + id: `${item.id}${ts}`, + summary: `Updated Listing with ID: ${item.id}`, + ts, + }; + }, + }, +}; diff --git a/components/domain_group/sources/common/base.mjs b/components/domain_group/sources/common/base.mjs new file mode 100644 index 0000000000000..4555f6785224d --- /dev/null +++ b/components/domain_group/sources/common/base.mjs @@ -0,0 +1,79 @@ +import domainGroup from "../../domain_group.app.mjs"; +import { + DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, ConfigurationError, +} from "@pipedream/platform"; + +export default { + props: { + domainGroup, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + methods: { + _getLastTs() { + return this.db.get("lastTs"); + }, + _setLastTs(lastTs) { + this.db.set("lastTs", lastTs); + }, + getArgs() { + return {}; + }, + async getResults() { + const lastTs = this._getLastTs(); + let maxTs = lastTs; + + const resourceFn = this.getResourceFn(); + const args = this.getArgs(); + const tsField = this.getTsField(); + + const items = this.domainGroup.paginate({ + resourceFn, + args, + }); + + const results = []; + for await (const item of items) { + const ts = item[tsField]; + if (!lastTs || (Date.parse(ts) > Date.parse(lastTs))) { + results.push(item); + if (!maxTs || (Date.parse(ts) > Date.parse(maxTs))) { + maxTs = ts; + } + } + } + + if (maxTs) { + this._setLastTs(maxTs); + } + + return results; + }, + getResourceFn() { + throw new ConfigurationError("getResourceFn is not implemented"); + }, + getTsField() { + throw new ConfigurationError("getTsField is not implemented"); + }, + generateMeta() { + throw new ConfigurationError("generateMeta is not implemented"); + }, + }, + async run() { + const results = await this.getResults(); + + if (!results.length) { + return; + } + + results.forEach((item) => { + const meta = this.generateMeta(item); + this.$emit(item, meta); + }); + }, +}; diff --git a/components/domain_group/sources/new-agency-created/new-agency-created.mjs b/components/domain_group/sources/new-agency-created/new-agency-created.mjs new file mode 100644 index 0000000000000..f72834c7a3cba --- /dev/null +++ b/components/domain_group/sources/new-agency-created/new-agency-created.mjs @@ -0,0 +1,29 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "domain_group-new-agency-created", + name: "New Agency Created", + description: "Emit new event when a new agency is created. [See the documentation](https://developer.domain.com.au/docs/latest/apis/pkg_listing_management/references/me_getmyagencies/)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + async getResults() { + const agencies = await this.domainGroup.listAgencies(); + const results = []; + for (const agency of agencies) { + results.push(agency); + } + return results; + }, + generateMeta(item) { + return { + id: item.id, + summary: `New Agency with ID: ${item.id}`, + ts: Date.now(), + }; + }, + }, +}; diff --git a/components/domain_group/sources/new-agency-listing-created/new-agency-listing-created.mjs b/components/domain_group/sources/new-agency-listing-created/new-agency-listing-created.mjs new file mode 100644 index 0000000000000..a200e61591e0c --- /dev/null +++ b/components/domain_group/sources/new-agency-listing-created/new-agency-listing-created.mjs @@ -0,0 +1,47 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "domain_group-new-agency-listing-created", + name: "New Agency Listing Created", + description: "Emit new event when a new agency listing is created. [See the documentation](https://developer.domain.com.au/docs/latest/apis/pkg_listing_management/references/agencies_getlistings/)", + version: "0.0.1", + type: "source", + dedupe: "unique", + props: { + ...common.props, + agencyId: { + propDefinition: [ + common.props.domainGroup, + "agencyId", + ], + }, + }, + methods: { + ...common.methods, + getResourceFn() { + return this.domainGroup.listAgencyListings; + }, + getArgs(lastTs) { + const args = { + agencyId: this.agencyId, + }; + if (lastTs) { + args.params = { + dateUpdatedSince: lastTs, + }; + } + return args; + }, + getTsField() { + return "dateCreated"; + }, + generateMeta(item) { + return { + id: item.id, + summary: `New Listing with ID: ${item.id}`, + ts: Date.parse(item[this.getTsField()]), + }; + }, + }, +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 271a9e7281879..81ba71dca4fda 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3618,7 +3618,11 @@ importers: components/dokan: {} - components/domain_group: {} + components/domain_group: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/domo: {}