From 45ef1cb9b17fb01f1098b393471d0cc5f2d6959a Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 9 Jun 2025 14:38:53 -0300 Subject: [PATCH 01/13] picqer init --- .../check-return-receipt.mjs | 26 ++++ .../actions/create-order/create-order.mjs | 116 +++++++++++++++ .../get-return-receipt-data.mjs | 27 ++++ .../get-shipment-data/get-shipment-data.mjs | 26 ++++ .../get-shipment-status.mjs | 26 ++++ .../actions/update-stock/update-stock.mjs | 40 +++++ components/picqer/package.json | 2 +- components/picqer/picqer.app.mjs | 137 +++++++++++++++++- .../new-order-instant/new-order-instant.mjs | 102 +++++++++++++ .../new-picklist-instant.mjs | 110 ++++++++++++++ .../new-shipment-instant.mjs | 102 +++++++++++++ 11 files changed, 708 insertions(+), 6 deletions(-) create mode 100644 components/picqer/actions/check-return-receipt/check-return-receipt.mjs create mode 100644 components/picqer/actions/create-order/create-order.mjs create mode 100644 components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs create mode 100644 components/picqer/actions/get-shipment-data/get-shipment-data.mjs create mode 100644 components/picqer/actions/get-shipment-status/get-shipment-status.mjs create mode 100644 components/picqer/actions/update-stock/update-stock.mjs create mode 100644 components/picqer/sources/new-order-instant/new-order-instant.mjs create mode 100644 components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs create mode 100644 components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs diff --git a/components/picqer/actions/check-return-receipt/check-return-receipt.mjs b/components/picqer/actions/check-return-receipt/check-return-receipt.mjs new file mode 100644 index 0000000000000..25be67d740b24 --- /dev/null +++ b/components/picqer/actions/check-return-receipt/check-return-receipt.mjs @@ -0,0 +1,26 @@ +import picqer from "../../picqer.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-check-return-receipt", + name: "Check Return Receipt", + description: "Check the return receipt in Picqer. [See the documentation](https://picqer.com/en/api/returns)", + version: "0.0.1", + type: "action", + props: { + picqer, + returnId: { + propDefinition: [ + picqer, + "returnId", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.checkReturnReceipt({ + returnId: this.returnId, + }); + $.export("$summary", `Successfully retrieved return receipt for Return ID: ${this.returnId}`); + return response; + }, +}; diff --git a/components/picqer/actions/create-order/create-order.mjs b/components/picqer/actions/create-order/create-order.mjs new file mode 100644 index 0000000000000..df59268a168a0 --- /dev/null +++ b/components/picqer/actions/create-order/create-order.mjs @@ -0,0 +1,116 @@ +import picqer from "../../picqer.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-create-order", + name: "Create Picqer Order", + description: "Create a new order in Picqer with customer details, products, and optional warehouse assignment. [See the documentation](https://picqer.com/en/api/orders)", + version: "0.0.{{ts}}", + type: "action", + props: { + picqer, + customerDetails: { + propDefinition: [ + picqer, + "customerDetails", + ], + }, + products: { + propDefinition: [ + picqer, + "products", + ], + }, + warehouseId: { + propDefinition: [ + picqer, + "warehouseId", + ], + optional: true, + }, + idcustomer: { + type: "integer", + label: "Customer ID", + description: "Linked to resource Customers. When idcustomer is not given, a guest-order will be created.", + optional: true, + }, + idtemplate: { + type: "integer", + label: "Template ID", + description: "Linked to resource Templates, if null the default template will be selected.", + optional: true, + }, + idshippingprovider_profile: { + type: "integer", + label: "Shipping Provider Profile ID", + description: "The preferred shipping provider profile for this order.", + optional: true, + }, + reference: { + type: "string", + label: "Reference", + description: "Reference for customer, will be printed on invoice and picking list.", + optional: true, + }, + customer_remarks: { + type: "string", + label: "Customer Remarks", + description: "Remarks from the customer, will be printed on picking and packing list.", + optional: true, + }, + partialdelivery: { + type: "boolean", + label: "Partial Delivery", + description: "If Picqer AutoSplit is enabled, order can be split over multiple picklists over multiple warehouses. If disabled, it will wait for all products to be available.", + optional: true, + }, + discount: { + type: "float", + label: "Discount", + description: "Discount percentage of order.", + optional: true, + }, + invoiced: { + type: "boolean", + label: "Invoiced", + description: "If this order is already invoiced, set this to true. This will ensure Picqer will not invoice this order.", + optional: true, + }, + preferred_delivery_date: { + type: "string", + label: "Preferred Delivery Date", + description: "Customer supplied preferred delivery date, in format yyyy-mm-dd.", + optional: true, + }, + language: { + type: "string", + label: "Language", + description: "Language used for communication with customer, 'nl' or 'en'.", + optional: true, + }, + }, + async run({ $ }) { + const response = await this.picqer.createOrder({ + idcustomer: this.idcustomer, + idtemplate: this.idtemplate, + idshippingprovider_profile: this.idshippingprovider_profile, + reference: this.reference, + customer_remarks: this.customer_remarks, + partialdelivery: this.partialdelivery, + discount: this.discount, + invoiced: this.invoiced, + preferred_delivery_date: this.preferred_delivery_date, + language: this.language, + customerDetails: this.customerDetails, + products: this.products.map(JSON.parse), + warehouses: this.warehouseId + ? [ + this.warehouseId, + ] + : undefined, + }); + + $.export("$summary", `Order created successfully with ID ${response.idorder}`); + return response; + }, +}; diff --git a/components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs b/components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs new file mode 100644 index 0000000000000..e0d9f0adcbbb0 --- /dev/null +++ b/components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs @@ -0,0 +1,27 @@ +import picqer from "../../picqer.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-get-return-receipt-data", + name: "Get Return Receipt Data", + description: "Get the data of a return receipt in Picqer. [See the documentation](https://picqer.com/en/api/returns)", + version: "0.0.1", + type: "action", + props: { + picqer, + returnId: { + propDefinition: [ + picqer, + "returnId", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.getReturnReceiptData({ + returnId: this.returnId, + }); + + $.export("$summary", `Successfully retrieved return receipt data for ID: ${this.returnId}`); + return response; + }, +}; diff --git a/components/picqer/actions/get-shipment-data/get-shipment-data.mjs b/components/picqer/actions/get-shipment-data/get-shipment-data.mjs new file mode 100644 index 0000000000000..d1020b905d921 --- /dev/null +++ b/components/picqer/actions/get-shipment-data/get-shipment-data.mjs @@ -0,0 +1,26 @@ +import picqer from "../../picqer.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-get-shipment-data", + name: "Get Shipment Data", + description: "Retrieve the data of a shipment in Picqer. [See the documentation](https://picqer.com/en/api/picklist-shipments)", + version: "0.0.{{ts}}", + type: "action", + props: { + picqer, + shipmentId: { + propDefinition: [ + picqer, + "shipmentId", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.getShipmentData({ + shipmentId: this.shipmentId, + }); + $.export("$summary", `Successfully retrieved shipment data for shipment ID: ${this.shipmentId}`); + return response; + }, +}; diff --git a/components/picqer/actions/get-shipment-status/get-shipment-status.mjs b/components/picqer/actions/get-shipment-status/get-shipment-status.mjs new file mode 100644 index 0000000000000..4ee7327bb06e0 --- /dev/null +++ b/components/picqer/actions/get-shipment-status/get-shipment-status.mjs @@ -0,0 +1,26 @@ +import picqer from "../../picqer.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-get-shipment-status", + name: "Get Shipment Status", + description: "Get the status of a shipment in Picqer. [See the documentation](https://picqer.com/en/api/picklist-shipments#h-get-single-shipment)", + version: "0.0.{{ts}}", + type: "action", + props: { + picqer, + shipmentId: { + propDefinition: [ + picqer, + "shipmentId", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.getShipmentStatus({ + shipmentId: this.shipmentId, + }); + $.export("$summary", `Successfully retrieved status for shipment ID: ${this.shipmentId}`); + return response; + }, +}; diff --git a/components/picqer/actions/update-stock/update-stock.mjs b/components/picqer/actions/update-stock/update-stock.mjs new file mode 100644 index 0000000000000..a7b094add258e --- /dev/null +++ b/components/picqer/actions/update-stock/update-stock.mjs @@ -0,0 +1,40 @@ +import picqer from "../../picqer.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-update-stock", + name: "Update Product Stock", + description: "Update the stock level of a product in a specific warehouse. [See the documentation](https://picqer.com/en/api)", + version: "0.0.1", + type: "action", + props: { + picqer, + productCode: { + propDefinition: [ + picqer, + "productCode", + ], + }, + warehouseId: { + propDefinition: [ + picqer, + "warehouseId", + ], + }, + stock: { + type: "integer", + label: "Stock Level", + description: "The new stock level for the product in the specified warehouse.", + }, + }, + async run({ $ }) { + const response = await this.picqer.updateProductStock({ + productCode: this.productCode, + warehouseId: this.warehouseId, + stock: this.stock, + }); + + $.export("$summary", `Successfully updated the stock for product ${this.productCode} in warehouse ${this.warehouseId}`); + return response; + }, +}; diff --git a/components/picqer/package.json b/components/picqer/package.json index 68967efd5ca2c..1683c93bb4fe7 100644 --- a/components/picqer/package.json +++ b/components/picqer/package.json @@ -12,4 +12,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/components/picqer/picqer.app.mjs b/components/picqer/picqer.app.mjs index b06b45747d3d8..d79858d4a7621 100644 --- a/components/picqer/picqer.app.mjs +++ b/components/picqer/picqer.app.mjs @@ -1,11 +1,138 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "picqer", - propDefinitions: {}, + propDefinitions: { + warehouseId: { + type: "string", + label: "Warehouse ID", + description: "The ID of the warehouse to filter events or update stock levels.", + async options() { + const warehouses = await this.listWarehouses(); + return warehouses.map((warehouse) => ({ + label: warehouse.name, + value: warehouse.idwarehouse, + })); + }, + optional: true, + }, + status: { + type: "string", + label: "Status", + description: "The status to filter pick lists.", + async options() { + return [ + { + label: "Open", + value: "open", + }, + { + label: "Closed", + value: "closed", + }, + ]; + }, + optional: true, + }, + carrier: { + type: "string", + label: "Carrier", + description: "The name of the carrier to filter shipments.", + optional: true, + }, + shipmentId: { + type: "string", + label: "Shipment ID", + description: "The ID of the shipment to retrieve data or status.", + }, + returnId: { + type: "string", + label: "Return ID", + description: "The ID of the return receipt to check or retrieve data.", + }, + customerDetails: { + type: "object", + label: "Customer Details", + description: "The customer details for creating a new order.", + }, + products: { + type: "string[]", + label: "Products", + description: "A list of products for the order or stock update.", + }, + productCode: { + type: "string", + label: "Product Code", + description: "The code of the product.", + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://example.picqer.com/api/v1"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, method = "GET", path = "/", headers, ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + method, + url: this._baseUrl() + path, + headers: { + ...headers, + "X-Picqer-Api-Key": this.$auth.api_key, + "Content-Type": "application/json", + }, + }); + }, + async listWarehouses(opts = {}) { + return this._makeRequest({ + path: "/warehouses", + ...opts, + }); + }, + async createOrder(data = {}) { + return this._makeRequest({ + method: "POST", + path: "/orders", + data: { + ...data, + }, + }); + }, + async updateProductStock(data = {}) { + return this._makeRequest({ + method: "PUT", + path: `/products/${data.productCode}/warehouses/${data.warehouseId}`, + data: { + stock: data.stock, + }, + }); + }, + async getShipmentStatus(opts = {}) { + return this._makeRequest({ + path: `/shipments/${opts.shipmentId}`, + ...opts, + }); + }, + async getShipmentData(opts = {}) { + return this._makeRequest({ + path: `/shipments/${opts.shipmentId}`, + ...opts, + }); + }, + async checkReturnReceipt(opts = {}) { + return this._makeRequest({ + path: `/returns/${opts.returnId}`, + ...opts, + }); + }, + async getReturnReceiptData(opts = {}) { + return this._makeRequest({ + path: `/returns/${opts.returnId}`, + ...opts, + }); }, }, -}; \ No newline at end of file +}; diff --git a/components/picqer/sources/new-order-instant/new-order-instant.mjs b/components/picqer/sources/new-order-instant/new-order-instant.mjs new file mode 100644 index 0000000000000..d50e84bff6f5a --- /dev/null +++ b/components/picqer/sources/new-order-instant/new-order-instant.mjs @@ -0,0 +1,102 @@ +import picqer from "../../picqer.app.mjs"; +import crypto from "crypto"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-new-order-instant", + name: "New Order Instant", + description: "Emit new event when a new order is created in Picqer. [See the documentation](https://picqer.com/en/api/webhooks)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + picqer, + http: { + type: "$.interface.http", + customResponse: true, + }, + db: "$.service.db", + warehouseId: { + propDefinition: [ + picqer, + "warehouseId", + ], + }, + }, + hooks: { + async deploy() { + const orders = await this.picqer._makeRequest({ + path: "/orders", + method: "GET", + params: { + results: 50, + sort: "created_at:desc", + }, + }); + for (const order of orders) { + this.$emit(order, { + id: order.idorder, + summary: `New order: ${order.orderid}`, + ts: Date.parse(order.created_at), + }); + } + }, + async activate() { + const webhook = await this.picqer._makeRequest({ + method: "POST", + path: "/webhooks", + data: { + event: "orders.created", + url: this.http.endpoint, + secret: this.picqer.$auth.api_key, + warehouse_id: this.warehouseId, + }, + }); + this._setWebhookId(webhook.id); + }, + async deactivate() { + const webhookId = this._getWebhookId(); + if (webhookId) { + await this.picqer._makeRequest({ + method: "DELETE", + path: `/webhooks/${webhookId}`, + }); + } + }, + }, + methods: { + _getWebhookId() { + return this.db.get("webhookId"); + }, + _setWebhookId(id) { + this.db.set("webhookId", id); + }, + }, + async run(event) { + const webhookSignature = event.headers["x-picqer-signature"]; + const rawBody = event.bodyRaw; + const secretKey = this.picqer.$auth.api_key; + const computedSignature = crypto.createHmac("sha256", secretKey).update(rawBody) + .digest("base64"); + + if (computedSignature !== webhookSignature) { + this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } + + const data = event.body; + this.$emit(data, { + id: data.idorder, + summary: `New order created: ${data.orderid}`, + ts: Date.parse(data.created_at), + }); + + this.http.respond({ + status: 200, + body: "OK", + }); + }, +}; diff --git a/components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs b/components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs new file mode 100644 index 0000000000000..81620109f2062 --- /dev/null +++ b/components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs @@ -0,0 +1,110 @@ +import picqer from "../../picqer.app.mjs"; +import crypto from "crypto"; +import { axios } from "@pipedream/platform"; + +export default { + key: "picqer-new-picklist-instant", + name: "New Picklist Instant", + description: "Emit new event when a new pick list is created in Picqer. [See the documentation](https://picqer.com/en/api/webhooks)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + picqer, + http: { + type: "$.interface.http", + customResponse: true, + }, + db: "$.service.db", + warehouseId: { + propDefinition: [ + picqer, + "warehouseId", + ], + optional: true, + }, + status: { + propDefinition: [ + picqer, + "status", + ], + optional: true, + }, + }, + methods: { + _getWebhookId() { + return this.db.get("webhookId"); + }, + _setWebhookId(id) { + this.db.set("webhookId", id); + }, + }, + hooks: { + async deploy() { + const picklists = await this.picqer._makeRequest({ + path: "/picklists", + }); + + picklists.slice(-50).forEach((picklist) => { + this.$emit(picklist, { + id: picklist.idpicklist, + summary: `New picklist created: ${picklist.idpicklist}`, + ts: Date.parse(picklist.datecreated), + }); + }); + }, + async activate() { + const webhook = await this.picqer._makeRequest({ + method: "POST", + path: "/webhooks", + data: { + event: "picklists.created", + url: this.http.endpoint, + }, + }); + this._setWebhookId(webhook.id); + }, + async deactivate() { + const id = this._getWebhookId(); + if (id) { + await this.picqer._makeRequest({ + method: "DELETE", + path: `/webhooks/${id}`, + }); + } + }, + }, + async run(event) { + const signature = event.headers["x-picqer-signature"]; + const body = event.body_raw; + const secret = this.picqer.$auth.api_key; + + const computedSignature = crypto.createHmac("sha256", secret) + .update(body) + .digest("base64"); + + if (computedSignature !== signature) { + this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } + + const { body: picklist } = event; + if ( + (!this.warehouseId || this.warehouseId === picklist.idwarehouse) && + (!this.status || this.status === picklist.status) + ) { + this.$emit(picklist, { + id: picklist.idpicklist, + summary: `New picklist created: ${picklist.idpicklist}`, + ts: Date.parse(picklist.datecreated), + }); + } + + this.http.respond({ + status: 200, + }); + }, +}; diff --git a/components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs b/components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs new file mode 100644 index 0000000000000..fc19d639121ab --- /dev/null +++ b/components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs @@ -0,0 +1,102 @@ +import picqer from "../../picqer.app.mjs"; +import { axios } from "@pipedream/platform"; +import crypto from "crypto"; + +export default { + key: "picqer-new-shipment-instant", + name: "New Shipment Created", + description: "Emit a new event when a shipment is created for an order in Picqer. [See the documentation](https://picqer.com/en/api/webhooks)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + picqer, + http: { + type: "$.interface.http", + customResponse: true, + }, + db: "$.service.db", + carrier: { + propDefinition: [ + picqer, + "carrier", + ], + }, + }, + methods: { + _getWebhookId() { + return this.db.get("webhookId"); + }, + _setWebhookId(id) { + this.db.set("webhookId", id); + }, + }, + hooks: { + async deploy() { + const recentShipments = await this.picqer._makeRequest({ + path: "/shipments", + }); + for (const shipment of recentShipments.slice(0, 50)) { + const ts = Date.parse(shipment.created_at); + this.$emit(shipment, { + id: shipment.idshipment, + summary: `New shipment created: ${shipment.idshipment}`, + ts, + }); + } + }, + async activate() { + const webhookResponse = await this.picqer._makeRequest({ + method: "POST", + path: "/webhooks", + data: { + event: "picklists.shipments.created", + url: this.http.endpoint, + }, + }); + this._setWebhookId(webhookResponse.id); + }, + async deactivate() { + const webhookId = this._getWebhookId(); + if (webhookId) { + await this.picqer._makeRequest({ + method: "DELETE", + path: `/webhooks/${webhookId}`, + }); + } + }, + }, + async run(event) { + const rawBody = event.body_raw; + const webhookSignature = event.headers["x-picqer-signature"]; + const secretKey = this.picqer.$auth.api_key; + const computedSignature = crypto + .createHmac("sha256", secretKey) + .update(rawBody) + .digest("base64"); + + if (computedSignature !== webhookSignature) { + this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } + + this.http.respond({ + status: 200, + body: "OK", + }); + + const { body } = event; + if (this.carrier && body.carrier !== this.carrier) { + return; + } + + this.$emit(body, { + id: body.idshipment, + summary: `New shipment created: ${body.idshipment}`, + ts: Date.parse(body.created_at), + }); + }, +}; From 3ccc173b3edfff13e4b5cc5150ce5314d6248d0d Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 10 Jun 2025 18:08:27 -0300 Subject: [PATCH 02/13] [ACTION] Picqer.com MCP server #16939 Sources - New Event (Instant) Actions - Add Order Comment - Add Return Comment - Create Order - Get Customer - Get Order - Get Picklist - Get Status Per Order Line - Search Orders - Update Order --- .../add-order-comment/add-order-comment.mjs | 50 ++ .../add-return-comment/add-return-comment.mjs | 50 ++ .../check-return-receipt.mjs | 26 - .../actions/create-order/create-order.mjs | 374 +++++++++++--- .../actions/get-customer/get-customer.mjs | 27 + .../picqer/actions/get-order/get-order.mjs | 27 + .../actions/get-picklist/get-picklist.mjs | 27 + .../get-return-receipt-data.mjs | 27 - .../get-shipment-data/get-shipment-data.mjs | 26 - .../get-shipment-status.mjs | 26 - .../get-status-per-order-line.mjs | 28 ++ .../actions/search-orders/search-orders.mjs | 107 ++++ .../actions/update-order/update-order.mjs | 356 ++++++++++++++ .../actions/update-stock/update-stock.mjs | 40 -- components/picqer/common/constants.mjs | 230 +++++++++ components/picqer/common/utils.mjs | 24 + components/picqer/package.json | 6 +- components/picqer/picqer.app.mjs | 463 +++++++++++++++--- components/picqer/sources/common/base.mjs | 82 ++++ .../new-event-instant/new-event-instant.mjs | 20 + .../sources/new-event-instant/test-event.mjs | 43 ++ .../new-order-instant/new-order-instant.mjs | 102 ---- .../new-picklist-instant.mjs | 110 ----- .../new-shipment-instant.mjs | 102 ---- 24 files changed, 1777 insertions(+), 596 deletions(-) create mode 100644 components/picqer/actions/add-order-comment/add-order-comment.mjs create mode 100644 components/picqer/actions/add-return-comment/add-return-comment.mjs delete mode 100644 components/picqer/actions/check-return-receipt/check-return-receipt.mjs create mode 100644 components/picqer/actions/get-customer/get-customer.mjs create mode 100644 components/picqer/actions/get-order/get-order.mjs create mode 100644 components/picqer/actions/get-picklist/get-picklist.mjs delete mode 100644 components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs delete mode 100644 components/picqer/actions/get-shipment-data/get-shipment-data.mjs delete mode 100644 components/picqer/actions/get-shipment-status/get-shipment-status.mjs create mode 100644 components/picqer/actions/get-status-per-order-line/get-status-per-order-line.mjs create mode 100644 components/picqer/actions/search-orders/search-orders.mjs create mode 100644 components/picqer/actions/update-order/update-order.mjs delete mode 100644 components/picqer/actions/update-stock/update-stock.mjs create mode 100644 components/picqer/common/constants.mjs create mode 100644 components/picqer/common/utils.mjs create mode 100644 components/picqer/sources/common/base.mjs create mode 100644 components/picqer/sources/new-event-instant/new-event-instant.mjs create mode 100644 components/picqer/sources/new-event-instant/test-event.mjs delete mode 100644 components/picqer/sources/new-order-instant/new-order-instant.mjs delete mode 100644 components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs delete mode 100644 components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs diff --git a/components/picqer/actions/add-order-comment/add-order-comment.mjs b/components/picqer/actions/add-order-comment/add-order-comment.mjs new file mode 100644 index 0000000000000..574d7f759c81f --- /dev/null +++ b/components/picqer/actions/add-order-comment/add-order-comment.mjs @@ -0,0 +1,50 @@ +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-add-order-comment", + name: "Add Comment To Order", + description: "Add a comment to an order in Picqer. [See the documentation](https://picqer.com/en/api/comments#adding-comments-to-an-order)", + version: "0.0.1", + type: "action", + props: { + picqer, + orderId: { + propDefinition: [ + picqer, + "orderId", + ], + }, + body: { + propDefinition: [ + picqer, + "commentBody", + ], + }, + showAtRelated: { + propDefinition: [ + picqer, + "showAtRelated", + ], + }, + isVisibleFulfillment: { + propDefinition: [ + picqer, + "isVisibleFulfillment", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.addOrderComment({ + $, + orderId: this.orderId, + data: { + body: this.body, + show_at_related: this.showAtRelated, + is_visible_fulfilment: this.isVisibleFulfillment, + }, + }); + + $.export("$summary", `Successfully added comment to order ${this.orderId}`); + return response; + }, +}; diff --git a/components/picqer/actions/add-return-comment/add-return-comment.mjs b/components/picqer/actions/add-return-comment/add-return-comment.mjs new file mode 100644 index 0000000000000..b8df5e64f94bb --- /dev/null +++ b/components/picqer/actions/add-return-comment/add-return-comment.mjs @@ -0,0 +1,50 @@ +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-add-return-comment", + name: "Add Comment To Return", + description: "Add a comment to a return in Picqer. [See the documentation](https://picqer.com/en/api/comments#add-a-comment-to-an-return)", + version: "0.0.1", + type: "action", + props: { + picqer, + returnId: { + propDefinition: [ + picqer, + "returnId", + ], + }, + body: { + propDefinition: [ + picqer, + "commentBody", + ], + }, + showAtRelated: { + propDefinition: [ + picqer, + "showAtRelated", + ], + }, + isVisibleFulfillment: { + propDefinition: [ + picqer, + "isVisibleFulfillment", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.addReturnComment({ + $, + returnId: this.returnId, + data: { + body: this.body, + show_at_related: this.showAtRelated, + is_visible_fulfilment: this.isVisibleFulfillment, + }, + }); + + $.export("$summary", `Successfully added comment to return ${this.returnId}`); + return response; + }, +}; diff --git a/components/picqer/actions/check-return-receipt/check-return-receipt.mjs b/components/picqer/actions/check-return-receipt/check-return-receipt.mjs deleted file mode 100644 index 25be67d740b24..0000000000000 --- a/components/picqer/actions/check-return-receipt/check-return-receipt.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "picqer-check-return-receipt", - name: "Check Return Receipt", - description: "Check the return receipt in Picqer. [See the documentation](https://picqer.com/en/api/returns)", - version: "0.0.1", - type: "action", - props: { - picqer, - returnId: { - propDefinition: [ - picqer, - "returnId", - ], - }, - }, - async run({ $ }) { - const response = await this.picqer.checkReturnReceipt({ - returnId: this.returnId, - }); - $.export("$summary", `Successfully retrieved return receipt for Return ID: ${this.returnId}`); - return response; - }, -}; diff --git a/components/picqer/actions/create-order/create-order.mjs b/components/picqer/actions/create-order/create-order.mjs index df59268a168a0..470e25eeb8d98 100644 --- a/components/picqer/actions/create-order/create-order.mjs +++ b/components/picqer/actions/create-order/create-order.mjs @@ -1,113 +1,361 @@ +import { ConfigurationError } from "@pipedream/platform"; +import { LANGUAGE_OPTIONS } from "../../common/constants.mjs"; +import { parseObject } from "../../common/utils.mjs"; import picqer from "../../picqer.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "picqer-create-order", name: "Create Picqer Order", - description: "Create a new order in Picqer with customer details, products, and optional warehouse assignment. [See the documentation](https://picqer.com/en/api/orders)", - version: "0.0.{{ts}}", + description: "Create a new order in Picqer. [See the documentation](https://picqer.com/en/api/orders)", + version: "0.0.1", type: "action", props: { picqer, - customerDetails: { + customerId: { propDefinition: [ picqer, - "customerDetails", + "customerId", ], + reloadProps: true, + optional: true, }, - products: { + templateId: { propDefinition: [ picqer, - "products", + "templateId", + ], + optional: true, + }, + shippingProviderId: { + propDefinition: [ + picqer, + "shippingProviderId", + ], + optional: true, + }, + deliveryName: { + propDefinition: [ + picqer, + "deliveryName", + ], + hidden: true, + }, + deliveryContactName: { + propDefinition: [ + picqer, + "deliveryContactName", + ], + optional: true, + hidden: true, + }, + deliveryAddress: { + propDefinition: [ + picqer, + "deliveryAddress", + ], + optional: true, + hidden: true, + }, + deliveryAddress2: { + propDefinition: [ + picqer, + "deliveryAddress2", + ], + optional: true, + hidden: true, + }, + deliveryZipcode: { + propDefinition: [ + picqer, + "deliveryZipcode", + ], + optional: true, + hidden: true, + }, + deliveryCity: { + propDefinition: [ + picqer, + "deliveryCity", + ], + optional: true, + hidden: true, + }, + deliveryRegion: { + propDefinition: [ + picqer, + "deliveryRegion", + ], + optional: true, + hidden: true, + }, + deliveryCountry: { + propDefinition: [ + picqer, + "deliveryCountry", ], + hidden: true, }, - warehouseId: { + invoiceName: { propDefinition: [ picqer, - "warehouseId", + "invoiceName", ], optional: true, + hidden: true, }, - idcustomer: { - type: "integer", - label: "Customer ID", - description: "Linked to resource Customers. When idcustomer is not given, a guest-order will be created.", + invoiceContactName: { + propDefinition: [ + picqer, + "invoiceContactName", + ], optional: true, + hidden: true, }, - idtemplate: { - type: "integer", - label: "Template ID", - description: "Linked to resource Templates, if null the default template will be selected.", + invoiceAddress: { + propDefinition: [ + picqer, + "invoiceAddress", + ], optional: true, + hidden: true, }, - idshippingprovider_profile: { - type: "integer", - label: "Shipping Provider Profile ID", - description: "The preferred shipping provider profile for this order.", + invoiceAddress2: { + propDefinition: [ + picqer, + "invoiceAddress2", + ], + optional: true, + hidden: true, + }, + invoiceZipcode: { + propDefinition: [ + picqer, + "invoiceZipcode", + ], + optional: true, + hidden: true, + }, + invoiceCity: { + propDefinition: [ + picqer, + "invoiceCity", + ], + optional: true, + hidden: true, + }, + invoiceRegion: { + propDefinition: [ + picqer, + "invoiceRegion", + ], + optional: true, + hidden: true, + }, + invoiceCountry: { + propDefinition: [ + picqer, + "invoiceCountry", + ], + description: "Country of invoice address (needs to be ISO 3166 2-char code).", + hidden: true, + }, + telephone: { + propDefinition: [ + picqer, + "telephone", + ], + optional: true, + }, + emailAddress: { + propDefinition: [ + picqer, + "emailAddress", + ], optional: true, }, reference: { - type: "string", - label: "Reference", - description: "Reference for customer, will be printed on invoice and picking list.", + propDefinition: [ + picqer, + "reference", + ], optional: true, }, - customer_remarks: { - type: "string", - label: "Customer Remarks", - description: "Remarks from the customer, will be printed on picking and packing list.", + customerRemarks: { + propDefinition: [ + picqer, + "customerRemarks", + ], optional: true, }, - partialdelivery: { - type: "boolean", - label: "Partial Delivery", - description: "If Picqer AutoSplit is enabled, order can be split over multiple picklists over multiple warehouses. If disabled, it will wait for all products to be available.", + partialDelivery: { + propDefinition: [ + picqer, + "partialDelivery", + ], optional: true, }, discount: { - type: "float", - label: "Discount", - description: "Discount percentage of order.", + propDefinition: [ + picqer, + "discount", + ], optional: true, }, invoiced: { - type: "boolean", - label: "Invoiced", - description: "If this order is already invoiced, set this to true. This will ensure Picqer will not invoice this order.", + propDefinition: [ + picqer, + "invoiced", + ], optional: true, }, - preferred_delivery_date: { - type: "string", - label: "Preferred Delivery Date", - description: "Customer supplied preferred delivery date, in format yyyy-mm-dd.", + preferredDeliveryDate: { + propDefinition: [ + picqer, + "preferredDeliveryDate", + ], optional: true, }, language: { - type: "string", - label: "Language", - description: "Language used for communication with customer, 'nl' or 'en'.", + propDefinition: [ + picqer, + "language", + ], + options: LANGUAGE_OPTIONS, optional: true, }, + products: { + propDefinition: [ + picqer, + "products", + ], + }, + }, + async additionalProps(fixedProps) { + const props = {}; + const hasCustomerId = !!this.customerId; + fixedProps.deliveryName.hidden = hasCustomerId; + fixedProps.deliveryContactName.hidden = hasCustomerId; + fixedProps.deliveryAddress.hidden = hasCustomerId; + fixedProps.deliveryAddress2.hidden = hasCustomerId; + fixedProps.deliveryZipcode.hidden = hasCustomerId; + fixedProps.deliveryCity.hidden = hasCustomerId; + fixedProps.deliveryRegion.hidden = hasCustomerId; + fixedProps.deliveryCountry.hidden = hasCustomerId; + fixedProps.invoiceName.hidden = hasCustomerId; + fixedProps.invoiceContactName.hidden = hasCustomerId; + fixedProps.invoiceAddress.hidden = hasCustomerId; + fixedProps.invoiceAddress2.hidden = hasCustomerId; + fixedProps.invoiceZipcode.hidden = hasCustomerId; + fixedProps.invoiceCity.hidden = hasCustomerId; + fixedProps.invoiceRegion.hidden = hasCustomerId; + fixedProps.invoiceCountry.hidden = hasCustomerId; + + if (this.customerId) { + const orderFields = await this.picqer.listOrderFields(); + + for (const field of orderFields) { + const propData = { + type: `string${field.type === "multicheckbox" + ? "[]" + : ""}`, + label: field.title, + description: `Order field: ${field.title}`, + optional: !field.required, + }; + + if (field.values.length) { + propData.options = field.values; + } + + props[field.idorderfield] = propData; + } + } + return props; }, async run({ $ }) { - const response = await this.picqer.createOrder({ - idcustomer: this.idcustomer, - idtemplate: this.idtemplate, - idshippingprovider_profile: this.idshippingprovider_profile, - reference: this.reference, - customer_remarks: this.customer_remarks, - partialdelivery: this.partialdelivery, - discount: this.discount, - invoiced: this.invoiced, - preferred_delivery_date: this.preferred_delivery_date, - language: this.language, - customerDetails: this.customerDetails, - products: this.products.map(JSON.parse), - warehouses: this.warehouseId - ? [ - this.warehouseId, - ] - : undefined, + const { + picqer, + customerId, + templateId, + shippingProviderId, + deliveryName, + deliveryContactName, + deliveryAddress, + deliveryAddress2, + deliveryZipcode, + deliveryCity, + deliveryRegion, + deliveryCountry, + invoiceName, + invoiceContactName, + invoiceAddress, + invoiceAddress2, + invoiceZipcode, + invoiceCity, + invoiceRegion, + invoiceCountry, + telephone, + emailAddress, + reference, + customerRemarks, + partialDelivery, + discount, + invoiced, + products, + preferredDeliveryDate, + language, + ...otherFields + } = this; + + if (!customerId && !deliveryName) { + throw new ConfigurationError("Delivery Name is required if **Customer Id** is not provided"); + } + if (!customerId && !deliveryCountry) { + throw new ConfigurationError("Delivery Country is required if **Customer Id** is not provided"); + } + + const response = await picqer.createOrder({ + $, + data: { + idcustomer: customerId, + idtemplate: templateId, + idshippingprovider: shippingProviderId, + deliveryname: deliveryName, + deliverycontactname: deliveryContactName, + deliveryaddress: deliveryAddress, + deliveryaddress2: deliveryAddress2, + deliveryzipcode: deliveryZipcode, + deliverycity: deliveryCity, + deliveryregion: deliveryRegion, + deliverycountry: deliveryCountry, + invoicename: invoiceName, + invoicecontactname: invoiceContactName, + invoiceaddress: invoiceAddress, + invoiceaddress2: invoiceAddress2, + invoicezipcode: invoiceZipcode, + invoicecity: invoiceCity, + invoiceregion: invoiceRegion, + invoicecountry: invoiceCountry, + telephone, + emailaddress: emailAddress, + reference, + customerremarks: customerRemarks, + partialdelivery: partialDelivery, + discount: discount && parseFloat(discount), + invoiced, + preferreddeliverydate: preferredDeliveryDate, + language, + products: parseObject(products), + orderfields: Object.entries(otherFields)?.map(([ + key, + value, + ]) => ({ + idorderfield: parseInt(key), + value: Array.isArray(value) + ? value.join(";") + : value, + })), + }, }); $.export("$summary", `Order created successfully with ID ${response.idorder}`); diff --git a/components/picqer/actions/get-customer/get-customer.mjs b/components/picqer/actions/get-customer/get-customer.mjs new file mode 100644 index 0000000000000..60da7823c5248 --- /dev/null +++ b/components/picqer/actions/get-customer/get-customer.mjs @@ -0,0 +1,27 @@ +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-get-customer", + name: "Get Customer", + description: "Get a customer in Picqer. [See the documentation](https://picqer.com/en/api/customers#get-single-customer)", + version: "0.0.1", + type: "action", + props: { + picqer, + customerId: { + propDefinition: [ + picqer, + "customerId", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.getCustomer({ + $, + customerId: this.customerId, + }); + + $.export("$summary", `Successfully retrieved customer ${this.customerId}`); + return response; + }, +}; diff --git a/components/picqer/actions/get-order/get-order.mjs b/components/picqer/actions/get-order/get-order.mjs new file mode 100644 index 0000000000000..3f1d03d2c22b5 --- /dev/null +++ b/components/picqer/actions/get-order/get-order.mjs @@ -0,0 +1,27 @@ +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-get-order", + name: "Get Picqer Order", + description: "Get an order in Picqer. [See the documentation](https://picqer.com/en/api/orders#get-single-order)", + version: "0.0.1", + type: "action", + props: { + picqer, + orderId: { + propDefinition: [ + picqer, + "orderId", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.getOrder({ + $, + orderId: this.orderId, + }); + + $.export("$summary", `Successfully retrieved order ${this.orderId}`); + return response; + }, +}; diff --git a/components/picqer/actions/get-picklist/get-picklist.mjs b/components/picqer/actions/get-picklist/get-picklist.mjs new file mode 100644 index 0000000000000..5ddb4ce78028a --- /dev/null +++ b/components/picqer/actions/get-picklist/get-picklist.mjs @@ -0,0 +1,27 @@ +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-get-picklist", + name: "Get Picklist", + description: "Get a picklist in Picqer. [See the documentation](https://picqer.com/en/api/picklists#h-get-single-picklist)", + version: "0.0.1", + type: "action", + props: { + picqer, + picklistId: { + propDefinition: [ + picqer, + "picklistId", + ], + }, + }, + async run({ $ }) { + const response = await this.picqer.getPicklist({ + $, + picklistId: this.picklistId, + }); + + $.export("$summary", `Successfully retrieved picklist ${this.picklistId}`); + return response; + }, +}; diff --git a/components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs b/components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs deleted file mode 100644 index e0d9f0adcbbb0..0000000000000 --- a/components/picqer/actions/get-return-receipt-data/get-return-receipt-data.mjs +++ /dev/null @@ -1,27 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "picqer-get-return-receipt-data", - name: "Get Return Receipt Data", - description: "Get the data of a return receipt in Picqer. [See the documentation](https://picqer.com/en/api/returns)", - version: "0.0.1", - type: "action", - props: { - picqer, - returnId: { - propDefinition: [ - picqer, - "returnId", - ], - }, - }, - async run({ $ }) { - const response = await this.picqer.getReturnReceiptData({ - returnId: this.returnId, - }); - - $.export("$summary", `Successfully retrieved return receipt data for ID: ${this.returnId}`); - return response; - }, -}; diff --git a/components/picqer/actions/get-shipment-data/get-shipment-data.mjs b/components/picqer/actions/get-shipment-data/get-shipment-data.mjs deleted file mode 100644 index d1020b905d921..0000000000000 --- a/components/picqer/actions/get-shipment-data/get-shipment-data.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "picqer-get-shipment-data", - name: "Get Shipment Data", - description: "Retrieve the data of a shipment in Picqer. [See the documentation](https://picqer.com/en/api/picklist-shipments)", - version: "0.0.{{ts}}", - type: "action", - props: { - picqer, - shipmentId: { - propDefinition: [ - picqer, - "shipmentId", - ], - }, - }, - async run({ $ }) { - const response = await this.picqer.getShipmentData({ - shipmentId: this.shipmentId, - }); - $.export("$summary", `Successfully retrieved shipment data for shipment ID: ${this.shipmentId}`); - return response; - }, -}; diff --git a/components/picqer/actions/get-shipment-status/get-shipment-status.mjs b/components/picqer/actions/get-shipment-status/get-shipment-status.mjs deleted file mode 100644 index 4ee7327bb06e0..0000000000000 --- a/components/picqer/actions/get-shipment-status/get-shipment-status.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "picqer-get-shipment-status", - name: "Get Shipment Status", - description: "Get the status of a shipment in Picqer. [See the documentation](https://picqer.com/en/api/picklist-shipments#h-get-single-shipment)", - version: "0.0.{{ts}}", - type: "action", - props: { - picqer, - shipmentId: { - propDefinition: [ - picqer, - "shipmentId", - ], - }, - }, - async run({ $ }) { - const response = await this.picqer.getShipmentStatus({ - shipmentId: this.shipmentId, - }); - $.export("$summary", `Successfully retrieved status for shipment ID: ${this.shipmentId}`); - return response; - }, -}; diff --git a/components/picqer/actions/get-status-per-order-line/get-status-per-order-line.mjs b/components/picqer/actions/get-status-per-order-line/get-status-per-order-line.mjs new file mode 100644 index 0000000000000..bc27e8556cb3a --- /dev/null +++ b/components/picqer/actions/get-status-per-order-line/get-status-per-order-line.mjs @@ -0,0 +1,28 @@ +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-get-status-per-order-line", + name: "Get Status Per Order Line", + description: "Get the status per order line in Picqer. [See the documentation](https://picqer.com/en/api/orders#get-status-per-order-line)", + version: "0.0.1", + type: "action", + props: { + picqer, + orderId: { + propDefinition: [ + picqer, + "orderId", + ], + description: "Get the status per order line for this order.", + }, + }, + async run({ $ }) { + const response = await this.picqer.getStatusPerOrderLine({ + $, + orderId: this.orderId, + }); + + $.export("$summary", `Successfully retrieved status per order line for order ${this.orderId}`); + return response; + }, +}; diff --git a/components/picqer/actions/search-orders/search-orders.mjs b/components/picqer/actions/search-orders/search-orders.mjs new file mode 100644 index 0000000000000..244891c7498d0 --- /dev/null +++ b/components/picqer/actions/search-orders/search-orders.mjs @@ -0,0 +1,107 @@ +import { STATUS_OPTIONS } from "../../common/constants.mjs"; +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-search-orders", + name: "Search Picqer Orders", + description: "Search for orders in Picqer. [See the documentation](https://picqer.com/en/api/orders#get-all-orders)", + version: "0.0.1", + type: "action", + props: { + picqer, + search: { + type: "string", + label: "Search", + description: "Search through the fields orderid, reference, customer name and customer contact name.", + optional: true, + }, + sinceId: { + type: "string", + label: "Since ID", + description: "Get the orders with a later idorder than given.", + optional: true, + }, + beforeId: { + type: "string", + label: "Before ID", + description: "Get the orders with a smaller idorder than given.", + optional: true, + }, + sinceDate: { + type: "string", + label: "Since Date", + description: "Get the orders that are added after this date and time. **Format: YYYY-MM-DD HH:MM:SS**", + optional: true, + }, + untilDate: { + type: "string", + label: "Until Date", + description: "Get the orders that are added before this date and time. **Format: YYYY-MM-DD HH:MM:SS**", + optional: true, + }, + status: { + type: "string", + label: "Status", + description: "Get the orders that have this status.", + options: STATUS_OPTIONS, + optional: true, + }, + reference: { + type: "string", + label: "Reference", + description: "Get the orders that have this value as reference.", + optional: true, + }, + emailAddress: { + type: "string", + label: "Email Address", + description: "Get the orders that have this value as email address.", + optional: true, + }, + customerId: { + propDefinition: [ + picqer, + "customerId", + ], + description: "Get all orders for this customer.", + optional: true, + }, + warehouseId: { + propDefinition: [ + picqer, + "warehouseId", + ], + description: "Get the orders that can be delivered from this warehouse.", + optional: true, + }, + fulfillmentCustomerId: { + propDefinition: [ + picqer, + "fulfillmentCustomerId", + ], + description: "Get the orders for this fulfilment.", + optional: true, + }, + }, + async run({ $ }) { + const response = await this.picqer.searchOrders({ + $, + params: { + search: this.search, + sinceid: this.sinceId, + beforeid: this.beforeId, + sincedate: this.sinceDate, + untildate: this.untilDate, + status: this.status, + reference: this.reference, + emailaddress: this.emailAddress, + idcustomer: this.customerId, + idwarehouse: this.warehouseId, + idfulfilment_customer: this.fulfillmentCustomerId, + }, + }); + + $.export("$summary", `Orders found: ${response.length}`); + return response; + }, +}; diff --git a/components/picqer/actions/update-order/update-order.mjs b/components/picqer/actions/update-order/update-order.mjs new file mode 100644 index 0000000000000..4857c6f9f13d6 --- /dev/null +++ b/components/picqer/actions/update-order/update-order.mjs @@ -0,0 +1,356 @@ +import picqer from "../../picqer.app.mjs"; + +export default { + key: "picqer-update-order", + name: "Update Picqer Order", + description: "Update an order in Picqer. [See the documentation](https://picqer.com/en/api/orders#update)", + version: "0.0.1", + type: "action", + props: { + picqer, + orderId: { + propDefinition: [ + picqer, + "orderId", + ], + }, + customerId: { + propDefinition: [ + picqer, + "customerId", + ], + reloadProps: true, + optional: true, + }, + templateId: { + propDefinition: [ + picqer, + "templateId", + ], + optional: true, + }, + deliveryName: { + propDefinition: [ + picqer, + "deliveryName", + ], + description: "Name of delivery address.", + optional: true, + hidden: true, + }, + deliveryContactName: { + propDefinition: [ + picqer, + "deliveryContactName", + ], + optional: true, + hidden: true, + }, + deliveryAddress: { + propDefinition: [ + picqer, + "deliveryAddress", + ], + optional: true, + hidden: true, + }, + deliveryAddress2: { + propDefinition: [ + picqer, + "deliveryAddress2", + ], + optional: true, + hidden: true, + }, + deliveryZipcode: { + propDefinition: [ + picqer, + "deliveryZipcode", + ], + optional: true, + hidden: true, + }, + deliveryCity: { + propDefinition: [ + picqer, + "deliveryCity", + ], + optional: true, + hidden: true, + }, + deliveryRegion: { + propDefinition: [ + picqer, + "deliveryRegion", + ], + optional: true, + hidden: true, + }, + deliveryCountry: { + propDefinition: [ + picqer, + "deliveryCountry", + ], + description: "Country of delivery address (needs to be ISO 3166 2-char code).", + optional: true, + hidden: true, + }, + invoiceName: { + propDefinition: [ + picqer, + "invoiceName", + ], + description: "Name of invoice address.", + optional: true, + hidden: true, + }, + invoiceContactName: { + propDefinition: [ + picqer, + "invoiceContactName", + ], + optional: true, + hidden: true, + }, + invoiceAddress: { + propDefinition: [ + picqer, + "invoiceAddress", + ], + optional: true, + hidden: true, + }, + invoiceAddress2: { + propDefinition: [ + picqer, + "invoiceAddress2", + ], + optional: true, + hidden: true, + }, + invoiceZipcode: { + propDefinition: [ + picqer, + "invoiceZipcode", + ], + optional: true, + hidden: true, + }, + invoiceCity: { + propDefinition: [ + picqer, + "invoiceCity", + ], + optional: true, + hidden: true, + }, + invoiceRegion: { + propDefinition: [ + picqer, + "invoiceRegion", + ], + optional: true, + hidden: true, + }, + invoiceCountry: { + propDefinition: [ + picqer, + "invoiceCountry", + ], + optional: true, + hidden: true, + }, + telephone: { + propDefinition: [ + picqer, + "telephone", + ], + optional: true, + }, + emailAddress: { + propDefinition: [ + picqer, + "emailAddress", + ], + optional: true, + }, + discount: { + propDefinition: [ + picqer, + "discount", + ], + optional: true, + }, + preferredDeliveryDate: { + propDefinition: [ + picqer, + "preferredDeliveryDate", + ], + optional: true, + }, + customerRemarks: { + propDefinition: [ + picqer, + "customerRemarks", + ], + optional: true, + }, + reference: { + propDefinition: [ + picqer, + "reference", + ], + optional: true, + }, + invoiced: { + propDefinition: [ + picqer, + "invoiced", + ], + optional: true, + }, + shippingProviderId: { + propDefinition: [ + picqer, + "shippingProviderId", + ], + optional: true, + }, + partialDelivery: { + propDefinition: [ + picqer, + "partialDelivery", + ], + optional: true, + }, + language: { + propDefinition: [ + picqer, + "language", + ], + optional: true, + }, + }, + async additionalProps(fixedProps) { + const props = {}; + const hasCustomerId = !!this.customerId; + fixedProps.deliveryName.hidden = hasCustomerId; + fixedProps.deliveryContactName.hidden = hasCustomerId; + fixedProps.deliveryAddress.hidden = hasCustomerId; + fixedProps.deliveryAddress2.hidden = hasCustomerId; + fixedProps.deliveryZipcode.hidden = hasCustomerId; + fixedProps.deliveryCity.hidden = hasCustomerId; + fixedProps.deliveryRegion.hidden = hasCustomerId; + fixedProps.deliveryCountry.hidden = hasCustomerId; + fixedProps.invoiceName.hidden = hasCustomerId; + fixedProps.invoiceContactName.hidden = hasCustomerId; + fixedProps.invoiceAddress.hidden = hasCustomerId; + fixedProps.invoiceAddress2.hidden = hasCustomerId; + fixedProps.invoiceZipcode.hidden = hasCustomerId; + fixedProps.invoiceCity.hidden = hasCustomerId; + fixedProps.invoiceRegion.hidden = hasCustomerId; + fixedProps.invoiceCountry.hidden = hasCustomerId; + + if (this.customerId) { + const orderFields = await this.picqer.listOrderFields(); + for (const field of orderFields) { + const propData = { + type: `string${field.type === "multicheckbox" + ? "[]" + : ""}`, + label: field.title, + description: `Order field: ${field.title}`, + }; + + if (field.values.length) { + propData.options = field.values; + } + + props[field.idorderfield] = propData; + } + } + return props; + }, + async run({ $ }) { + const { + picqer, + orderId, + customerId, + templateId, + shippingProviderId, + deliveryName, + deliveryContactName, + deliveryAddress, + deliveryAddress2, + deliveryZipcode, + deliveryCity, + deliveryRegion, + deliveryCountry, + invoiceName, + invoiceContactName, + invoiceAddress, + invoiceAddress2, + invoiceZipcode, + invoiceCity, + invoiceRegion, + invoiceCountry, + telephone, + emailAddress, + reference, + customerRemarks, + partialDelivery, + discount, + invoiced, + preferredDeliveryDate, + language, + ...otherFields + } = this; + + const response = await picqer.updateOrder({ + $, + orderId, + data: { + idcustomer: customerId, + idtemplate: templateId, + idshippingprovider: shippingProviderId, + deliveryname: deliveryName, + deliverycontactname: deliveryContactName, + deliveryaddress: deliveryAddress, + deliveryaddress2: deliveryAddress2, + deliveryzipcode: deliveryZipcode, + deliverycity: deliveryCity, + deliveryregion: deliveryRegion, + deliverycountry: deliveryCountry, + invoicename: invoiceName, + invoicecontactname: invoiceContactName, + invoiceaddress: invoiceAddress, + invoiceaddress2: invoiceAddress2, + invoicezipcode: invoiceZipcode, + invoicecity: invoiceCity, + invoiceregion: invoiceRegion, + invoicecountry: invoiceCountry, + telephone, + emailaddress: emailAddress, + reference, + customerremarks: customerRemarks, + partialdelivery: partialDelivery, + discount: discount && parseFloat(discount), + invoiced, + preferreddeliverydate: preferredDeliveryDate, + language, + orderfields: Object.entries(otherFields)?.map(([ + key, + value, + ]) => ({ + idorderfield: parseInt(key), + value: Array.isArray(value) + ? value.join(";") + : value, + })), + }, + }); + + $.export("$summary", `Order updated successfully with ID ${orderId}`); + return response; + }, +}; diff --git a/components/picqer/actions/update-stock/update-stock.mjs b/components/picqer/actions/update-stock/update-stock.mjs deleted file mode 100644 index a7b094add258e..0000000000000 --- a/components/picqer/actions/update-stock/update-stock.mjs +++ /dev/null @@ -1,40 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "picqer-update-stock", - name: "Update Product Stock", - description: "Update the stock level of a product in a specific warehouse. [See the documentation](https://picqer.com/en/api)", - version: "0.0.1", - type: "action", - props: { - picqer, - productCode: { - propDefinition: [ - picqer, - "productCode", - ], - }, - warehouseId: { - propDefinition: [ - picqer, - "warehouseId", - ], - }, - stock: { - type: "integer", - label: "Stock Level", - description: "The new stock level for the product in the specified warehouse.", - }, - }, - async run({ $ }) { - const response = await this.picqer.updateProductStock({ - productCode: this.productCode, - warehouseId: this.warehouseId, - stock: this.stock, - }); - - $.export("$summary", `Successfully updated the stock for product ${this.productCode} in warehouse ${this.warehouseId}`); - return response; - }, -}; diff --git a/components/picqer/common/constants.mjs b/components/picqer/common/constants.mjs new file mode 100644 index 0000000000000..dad2dbb57f71d --- /dev/null +++ b/components/picqer/common/constants.mjs @@ -0,0 +1,230 @@ +export const LIMIT = 100; + +export const LANGUAGE_OPTIONS = [ + { + label: "English", + value: "en", + }, + { + label: "Dutch", + value: "nl", + }, +]; + +export const STATUS_OPTIONS = [ + { + label: "Concept", + value: "concept", + }, + { + label: "Expected", + value: "expected", + }, + { + label: "Processing", + value: "processing", + }, + { + label: "Paused", + value: "paused", + }, + { + label: "Completed", + value: "completed", + }, + { + label: "Cancelled", + value: "cancelled", + }, +]; + +export const EVENT_OPTIONS = [ + { + label: "New Comment Created", + value: "comments.created", + }, + { + label: "New Movement", + value: "movements.moved", + }, + { + label: "New Order Created", + value: "orders.created", + }, + { + label: "Order Allocated", + value: "orders.allocated", + }, + { + label: "Order Closed", + value: "orders.closed", + }, + { + label: "Order Paused", + value: "orders.paused", + }, + { + label: "Order Resumed", + value: "orders.resumed", + }, + { + label: "Order Status Changed", + value: "orders.status_changed", + }, + { + label: "Order Completed", + value: "orders.completed", + }, + { + label: "New Order Note Created", + value: "orders.notes.created", + }, + { + label: "New Picklist Created", + value: "picklists.created", + }, + { + label: "Picklist Changed", + value: "picklists.changed", + }, + { + label: "Picklist Paused", + value: "picklists.paused", + }, + { + label: "Picklist Resumed", + value: "picklists.resumed", + }, + { + label: "Picklist Closed", + value: "picklists.closed", + }, + { + label: "Picklist Cancelled", + value: "picklists.cancelled", + }, + { + label: "Picklist Snoozed", + value: "picklists.snoozed", + }, + { + label: "Picklist Unsnoozed", + value: "picklists.unsnoozed", + }, + { + label: "New Picklist Shipment Created", + value: "picklists.shipments.created", + }, + { + label: "Picklist Shipment Cancelled", + value: "picklists.shipments.cancelled", + }, + { + label: "New Picklist Batch Created", + value: "picklist_batches.created", + }, + { + label: "Picklist Batch Changed", + value: "picklist_batches.changed", + }, + { + label: "Picklist Batch Completed", + value: "picklist_batches.completed", + }, + { + label: "New Product Created", + value: "products.created", + }, + { + label: "Product Changed", + value: "products.changed", + }, + { + label: "Product Free Stock Changed", + value: "products.free_stock_changed", + }, + { + label: "Product Stock Changed", + value: "products.stock_changed", + }, + { + label: "Product Assembled Stock Changed", + value: "products.assembled_stock_changed", + }, + { + label: "Product Stock On Location Changed", + value: "products.stock_on_location_changed", + }, + { + label: "Product Parts Changed", + value: "products.parts.changed", + }, + { + label: "New Purchase Order Created", + value: "purchase_orders.created", + }, + { + label: "Purchase Order Changed", + value: "purchase_orders.changed", + }, + { + label: "Purchase Order Purchased", + value: "purchase_orders.purchased", + }, + { + label: "New Receipt Created", + value: "receipts.created", + }, + { + label: "Receipt Completed", + value: "receipts.completed", + }, + { + label: "Receipt Product Received", + value: "receipts.product_received", + }, + { + label: "Receipt Product Reverted", + value: "receipts.product_reverted", + }, + { + label: "New Return Created", + value: "returns.created", + }, + { + label: "Return Changed", + value: "returns.changed", + }, + { + label: "Return Status Changed", + value: "returns.status_changed", + }, + { + label: "Return Products Received", + value: "returns.products_received", + }, + { + label: "Location Stock Counts Completed", + value: "location_stock_counts.completed", + }, + { + label: "New Task Created", + value: "tasks.created", + }, + { + label: "Task Changed", + value: "tasks.changed", + }, + { + label: "Task Deleted", + value: "tasks.deleted", + }, + { + label: "Task Completed", + value: "tasks.completed", + }, + { + label: "Task Uncompleted", + value: "tasks.uncompleted", + }, +]; diff --git a/components/picqer/common/utils.mjs b/components/picqer/common/utils.mjs new file mode 100644 index 0000000000000..dcc9cc61f6f41 --- /dev/null +++ b/components/picqer/common/utils.mjs @@ -0,0 +1,24 @@ +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/picqer/package.json b/components/picqer/package.json index 1683c93bb4fe7..afec885e938a8 100644 --- a/components/picqer/package.json +++ b/components/picqer/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/picqer", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Picqer Components", "main": "picqer.app.mjs", "keywords": [ @@ -11,5 +11,9 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.1.0", + "crypto-js": "^4.2.0" } } diff --git a/components/picqer/picqer.app.mjs b/components/picqer/picqer.app.mjs index d79858d4a7621..a6a20696c658f 100644 --- a/components/picqer/picqer.app.mjs +++ b/components/picqer/picqer.app.mjs @@ -1,138 +1,455 @@ import { axios } from "@pipedream/platform"; +import { + LANGUAGE_OPTIONS, + LIMIT, +} from "./common/constants.mjs"; export default { type: "app", app: "picqer", propDefinitions: { - warehouseId: { + orderId: { type: "string", - label: "Warehouse ID", - description: "The ID of the warehouse to filter events or update stock levels.", - async options() { - const warehouses = await this.listWarehouses(); - return warehouses.map((warehouse) => ({ - label: warehouse.name, - value: warehouse.idwarehouse, + label: "Order ID", + description: "The order id for searching orders.", + async options({ page }) { + const data = await this.searchOrders({ + params: { + offset: page * LIMIT, + }, + }); + + return data.map(({ + idorder: value, invoicename: label, + }) => ({ + label, + value, + })); + }, + }, + customerId: { + type: "string", + label: "Customer ID", + description: "The customer id for creating a new order.", + async options({ page }) { + const data = await this.listCustomers({ + params: { + offset: page * LIMIT, + }, + }); + + return data.map(({ + idcustomer: value, name: label, + }) => ({ + label, + value, })); }, - optional: true, }, - status: { + templateId: { type: "string", - label: "Status", - description: "The status to filter pick lists.", - async options() { - return [ - { - label: "Open", - value: "open", + label: "Template Id", + description: "The template id for creating a new order.", + async options({ page }) { + const data = await this.listTemplates({ + params: { + offset: page * LIMIT, }, - { - label: "Closed", - value: "closed", + }); + + return data.map(({ + idtemplate: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + shippingProviderId: { + type: "string", + label: "Shipping Provider Id", + description: "The shipping provider id for creating a new order.", + async options({ page }) { + const data = await this.listShippingProviders({ + params: { + offset: page * LIMIT, }, - ]; + }); + return data.map(({ + idshippingprovider: value, name: label, + }) => ({ + label, + value, + })); }, - optional: true, }, - carrier: { + warehouseId: { type: "string", - label: "Carrier", - description: "The name of the carrier to filter shipments.", - optional: true, + label: "Warehouse ID", + description: "Warehouses that can be used to fulfil this order.", + async options({ page }) { + const warehouses = await this.listWarehouses({ + params: { + offset: page * LIMIT, + }, + }); + return warehouses.map(({ + idwarehouse: value, name: label, + }) => ({ + label, + value, + })); + }, }, - shipmentId: { + fulfillmentCustomerId: { type: "string", - label: "Shipment ID", - description: "The ID of the shipment to retrieve data or status.", + label: "Fulfillment Customer ID", + description: "Fulfillment customer for this order.", + async options({ page }) { + const fulfillmentCustomers = await this.listFulfillmentCustomers({ + params: { + offset: page * LIMIT, + }, + }); + return fulfillmentCustomers.map(({ + idcustomer: value, name: label, + }) => ({ + label, + value, + })); + }, }, returnId: { type: "string", label: "Return ID", - description: "The ID of the return receipt to check or retrieve data.", + description: "The return id for searching returns.", + async options({ page }) { + const data = await this.searchReturns({ + params: { + offset: page * LIMIT, + }, + }); + + return data.map(({ + idreturn: value, returnid, name, + }) => ({ + label: `${returnid} - ${name}`, + value, + })); + }, }, - customerDetails: { - type: "object", - label: "Customer Details", - description: "The customer details for creating a new order.", + picklistId: { + type: "string", + label: "Picklist ID", + description: "The picklist id for searching picklists.", + async options({ page }) { + const data = await this.listPicklists({ + params: { + offset: page * LIMIT, + }, + }); + return data.map(({ + idpicklist: value, picklistid, deliveryname, + }) => ({ + label: `${picklistid} - ${deliveryname}`, + value, + })); + }, + }, + deliveryName: { + type: "string", + label: "Delivery Name", + description: "Name of delivery address. Required if **Customer Id** is not provided.", + }, + deliveryContactName: { + type: "string", + label: "Delivery Contact Name", + description: "Contact name of delivery address.", }, - products: { - type: "string[]", - label: "Products", - description: "A list of products for the order or stock update.", + deliveryAddress: { + type: "string", + label: "Delivery Address", + description: "Address line of delivery address.", + }, + deliveryAddress2: { + type: "string", + label: "Delivery Address 2", + description: "Second address line. Not accepted by all shipping providers.", + }, + deliveryZipcode: { + type: "string", + label: "Delivery Zipcode", + description: "ZIP code of delivery address.", + }, + deliveryCity: { + type: "string", + label: "Delivery City", + description: "City of delivery address.", + }, + deliveryRegion: { + type: "string", + label: "Delivery Region", + description: "Region, province or state of delivery address.", + }, + deliveryCountry: { + type: "string", + label: "Delivery Country", + description: "Country of delivery address (needs to be ISO 3166 2-char code). Required if **Customer Id** is not provided.", + }, + invoiceName: { + type: "string", + label: "Invoice Name", + description: "Name of invoice address. Required if **Customer Id** is not provided.", + }, + invoiceContactName: { + type: "string", + label: "Invoice Contact Name", + description: "Contact name of invoice address", + }, + invoiceAddress: { + type: "string", + label: "Invoice Address", + description: "Address line of invoice address", + }, + invoiceAddress2: { + type: "string", + label: "Invoice Address 2", + description: "Second address line. Not accepted by all shipping providers.", + }, + invoiceZipcode: { + type: "string", + label: "Invoice Zipcode", + description: "ZIP code of invoice address", + }, + invoiceCity: { + type: "string", + label: "Invoice City", + description: "City of invoice address", + }, + invoiceRegion: { + type: "string", + label: "Invoice Region", + description: "Region, province or state of invoice address", + }, + invoiceCountry: { + type: "string", + label: "Invoice Country", + description: "Country of invoice address (needs to be ISO 3166 2-char code). Required if **Customer Id** is not provided.", + }, + telephone: { + type: "string", + label: "Telephone", + description: "Telephone number of the customer.", + }, + emailAddress: { + type: "string", + label: "Email Address", + description: "Email address of the customer", + }, + discount: { + type: "string", + label: "Discount", + description: "Discount percentage of order", + }, + preferredDeliveryDate: { + type: "string", + label: "Preferred Delivery Date", + description: "Customer supplied preferred delivery date, in format **yyyy-mm-dd**.", }, - productCode: { + customerRemarks: { type: "string", - label: "Product Code", - description: "The code of the product.", + label: "Customer Remarks", + description: "Remarks from the customer, will be printed on picking and packing list", + }, + reference: { + type: "string", + label: "Reference", + description: "Reference for customer, will be printed on invoice and picking list", + }, + invoiced: { + type: "boolean", + label: "Invoiced", + description: "If this order is already invoiced, set this to true. This will make sure Picqer will not invoice this order", + }, + partialDelivery: { + type: "boolean", + label: "Partial Delivery", + description: "If Picqer AutoSplit is enabled, order can be split over multiple picklists over multiple warehouses. If disabled, it will wait for all products to be available", + }, + language: { + type: "string", + label: "Language", + description: "Language of the order", + options: LANGUAGE_OPTIONS, + }, + commentBody: { + type: "string", + label: "Comment Body", + description: "The body of the comment.", + }, + showAtRelated: { + type: "boolean", + label: "Show At Related", + description: "Whether the comment is visible on related resources. For example: comments added to orders can be shown when retrieving comments for a picklist of that order.", + }, + isVisibleFulfillment: { + type: "boolean", + label: "Visible In Fulfillment", + description: "Only for Picqer Fulfilment: Whether the comment is visible for the fulfilment customer the resource belongs to.", }, }, methods: { _baseUrl() { - return "https://example.picqer.com/api/v1"; + return `https://${this.$auth.subdomain}.picqer.com/api/v1`; + }, + _auth() { + return { + username: `${this.$auth.api_key}`, + password: "", + }; }, - async _makeRequest(opts = {}) { - const { - $ = this, method = "GET", path = "/", headers, ...otherOpts - } = opts; + _makeRequest({ + $ = this, path, ...opts + }) { return axios($, { - ...otherOpts, - method, url: this._baseUrl() + path, - headers: { - ...headers, - "X-Picqer-Api-Key": this.$auth.api_key, - "Content-Type": "application/json", - }, + auth: this._auth(), + ...opts, + }); + }, + createOrder(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/orders", + ...opts, + }); + }, + updateOrder({ + orderId, ...opts + }) { + return this._makeRequest({ + method: "PUT", + path: `/orders/${orderId}`, + ...opts, + }); + }, + getOrder({ + orderId, ...opts + }) { + return this._makeRequest({ + path: `/orders/${orderId}`, + ...opts, + }); + }, + getCustomer({ + customerId, ...opts + }) { + return this._makeRequest({ + path: `/customers/${customerId}`, + ...opts, + }); + }, + listCustomers(opts = {}) { + return this._makeRequest({ + path: "/customers", + ...opts, }); }, - async listWarehouses(opts = {}) { + listOrderFields(opts = {}) { + return this._makeRequest({ + path: "/orderfields", + ...opts, + }); + }, + listTemplates(opts = {}) { + return this._makeRequest({ + path: "/templates", + ...opts, + }); + }, + listShippingProviders(opts = {}) { + return this._makeRequest({ + path: "/shippingproviders", + ...opts, + }); + }, + searchOrders(opts = {}) { + return this._makeRequest({ + path: "/orders", + ...opts, + }); + }, + listWarehouses(opts = {}) { return this._makeRequest({ path: "/warehouses", ...opts, }); }, - async createOrder(data = {}) { + listFulfillmentCustomers(opts = {}) { + return this._makeRequest({ + path: "/fulfilment/customers", + ...opts, + }); + }, + getStatusPerOrderLine({ + orderId, ...opts + }) { + return this._makeRequest({ + path: `/orders/${orderId}/productstatus`, + ...opts, + }); + }, + addOrderComment({ + orderId, ...opts + }) { return this._makeRequest({ method: "POST", - path: "/orders", - data: { - ...data, - }, + path: `/orders/${orderId}/comments`, + ...opts, }); }, - async updateProductStock(data = {}) { + addReturnComment({ + returnId, ...opts + }) { return this._makeRequest({ - method: "PUT", - path: `/products/${data.productCode}/warehouses/${data.warehouseId}`, - data: { - stock: data.stock, - }, + method: "POST", + path: `/returns/${returnId}/comments`, + ...opts, }); }, - async getShipmentStatus(opts = {}) { + searchReturns(opts = {}) { return this._makeRequest({ - path: `/shipments/${opts.shipmentId}`, + path: "/returns", ...opts, }); }, - async getShipmentData(opts = {}) { + listPicklists(opts = {}) { return this._makeRequest({ - path: `/shipments/${opts.shipmentId}`, + path: "/picklists", ...opts, }); }, - async checkReturnReceipt(opts = {}) { + getPicklist({ + picklistId, ...opts + }) { return this._makeRequest({ - path: `/returns/${opts.returnId}`, + path: `/picklists/${picklistId}`, ...opts, }); }, - async getReturnReceiptData(opts = {}) { + createHook(opts = {}) { return this._makeRequest({ - path: `/returns/${opts.returnId}`, + method: "POST", + path: "/hooks", ...opts, }); }, + deleteHook(hookId) { + return this._makeRequest({ + method: "DELETE", + path: `/hooks/${hookId}`, + }); + }, }, }; + diff --git a/components/picqer/sources/common/base.mjs b/components/picqer/sources/common/base.mjs new file mode 100644 index 0000000000000..d20b4ad897ba7 --- /dev/null +++ b/components/picqer/sources/common/base.mjs @@ -0,0 +1,82 @@ +import CryptoJS from "crypto-js"; +import { EVENT_OPTIONS } from "../../common/constants.mjs"; +import picqer from "../../picqer.app.mjs"; + +export default { + props: { + picqer, + db: "$.service.db", + http: { + type: "$.interface.http", + customResponse: true, + }, + warehouseId: { + propDefinition: [ + picqer, + "warehouseId", + ], + }, + event: { + type: "string", + label: "Event", + description: "The event to emit.", + options: EVENT_OPTIONS, + }, + name: { + type: "string", + label: "Name", + description: "Your own reference for this hook.", + }, + secret: { + type: "string", + label: "Secret", + description: "If you provide a secret key with your webhook, we will use it to sign every request so you can check the sender.", + optional: true, + secret: true, + }, + }, + hooks: { + async activate() { + const response = await this.picqer.createHook({ + data: { + event: this.event, + address: this.http.endpoint, + secret: this.secret, + name: this.name, + }, + }); + this.db.set("webhookId", response.idhook); + }, + async deactivate() { + const webhookId = this.db.get("webhookId"); + await this.picqer.deleteHook(webhookId); + }, + }, + async run(event) { + const { body } = event; + const signature = event?.headers["x-picqer-signature"]; + const hash = CryptoJS.HmacSHA256(event.bodyRaw, this.secret); + const hashBase64 = CryptoJS.enc.Base64.stringify(hash); + + if (hashBase64 != signature) { + this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } + + this.http.respond({ + status: 200, + body: "Success", + }); + + const ts = Date.parse(body.event_triggered_at); + + this.$emit(body, { + id: `${body.idhook}-${ts}`, + summary: this.getSummary(body), + ts, + }); + }, +}; diff --git a/components/picqer/sources/new-event-instant/new-event-instant.mjs b/components/picqer/sources/new-event-instant/new-event-instant.mjs new file mode 100644 index 0000000000000..5a9c2e5b54b39 --- /dev/null +++ b/components/picqer/sources/new-event-instant/new-event-instant.mjs @@ -0,0 +1,20 @@ +import { EVENT_OPTIONS } from "../../common/constants.mjs"; +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "picqer-new-event-instant", + name: "New Event Instant", + description: "Emit new event when Picqer sends a webhook matched with selected event. [See the documentation](https://picqer.com/en/api/webhooks)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + getSummary(body) { + const event = EVENT_OPTIONS.find((e) => e.value === body.event); + return event.label; + }, + }, + sampleEmit, +}; diff --git a/components/picqer/sources/new-event-instant/test-event.mjs b/components/picqer/sources/new-event-instant/test-event.mjs new file mode 100644 index 0000000000000..ccc328ef55a4c --- /dev/null +++ b/components/picqer/sources/new-event-instant/test-event.mjs @@ -0,0 +1,43 @@ +export default { + "idhook":228, + "name":"Stock change notifications", + "event":"products.free_stock_changed", + "event_triggered_at":"2018-12-01 02:09:12", + "data": { + "idproduct":138, + "idvatgroup":18, + "idsupplier":null, + "productcode": "6531-RB-7-9", + "name": "Hyperkewl Evaporative Cooling Vest Ultra Blue 7-9yr", + "price": 54.46, + "fixedstockprice": 0, + "productcode_supplier": "", + "deliverytime": null, + "description": "", + "barcode": "857825001442", + "type": "normal", + "unlimitedstock": false, + "weight": 200, + "minimum_purchase_quantity": 0, + "purchase_in_quantities_of": 0, + "hs_code": null, + "country_of_origin": null, + "active": true, + "tags": {}, + "productfields": [], + "images": [ + "/files/2/cb594f30-25d0-43a6-88f2-d93e193ea316/original.jpg" + ], + "stock": [ + { + "idwarehouse":18, + "stock":35, + "reserved":0, + "reservedbackorders":0, + "reservedpicklists":0, + "freestock":35, + "freepickablestock":35 + } + ] + } +} \ No newline at end of file diff --git a/components/picqer/sources/new-order-instant/new-order-instant.mjs b/components/picqer/sources/new-order-instant/new-order-instant.mjs deleted file mode 100644 index d50e84bff6f5a..0000000000000 --- a/components/picqer/sources/new-order-instant/new-order-instant.mjs +++ /dev/null @@ -1,102 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import crypto from "crypto"; -import { axios } from "@pipedream/platform"; - -export default { - key: "picqer-new-order-instant", - name: "New Order Instant", - description: "Emit new event when a new order is created in Picqer. [See the documentation](https://picqer.com/en/api/webhooks)", - version: "0.0.{{ts}}", - type: "source", - dedupe: "unique", - props: { - picqer, - http: { - type: "$.interface.http", - customResponse: true, - }, - db: "$.service.db", - warehouseId: { - propDefinition: [ - picqer, - "warehouseId", - ], - }, - }, - hooks: { - async deploy() { - const orders = await this.picqer._makeRequest({ - path: "/orders", - method: "GET", - params: { - results: 50, - sort: "created_at:desc", - }, - }); - for (const order of orders) { - this.$emit(order, { - id: order.idorder, - summary: `New order: ${order.orderid}`, - ts: Date.parse(order.created_at), - }); - } - }, - async activate() { - const webhook = await this.picqer._makeRequest({ - method: "POST", - path: "/webhooks", - data: { - event: "orders.created", - url: this.http.endpoint, - secret: this.picqer.$auth.api_key, - warehouse_id: this.warehouseId, - }, - }); - this._setWebhookId(webhook.id); - }, - async deactivate() { - const webhookId = this._getWebhookId(); - if (webhookId) { - await this.picqer._makeRequest({ - method: "DELETE", - path: `/webhooks/${webhookId}`, - }); - } - }, - }, - methods: { - _getWebhookId() { - return this.db.get("webhookId"); - }, - _setWebhookId(id) { - this.db.set("webhookId", id); - }, - }, - async run(event) { - const webhookSignature = event.headers["x-picqer-signature"]; - const rawBody = event.bodyRaw; - const secretKey = this.picqer.$auth.api_key; - const computedSignature = crypto.createHmac("sha256", secretKey).update(rawBody) - .digest("base64"); - - if (computedSignature !== webhookSignature) { - this.http.respond({ - status: 401, - body: "Unauthorized", - }); - return; - } - - const data = event.body; - this.$emit(data, { - id: data.idorder, - summary: `New order created: ${data.orderid}`, - ts: Date.parse(data.created_at), - }); - - this.http.respond({ - status: 200, - body: "OK", - }); - }, -}; diff --git a/components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs b/components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs deleted file mode 100644 index 81620109f2062..0000000000000 --- a/components/picqer/sources/new-picklist-instant/new-picklist-instant.mjs +++ /dev/null @@ -1,110 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import crypto from "crypto"; -import { axios } from "@pipedream/platform"; - -export default { - key: "picqer-new-picklist-instant", - name: "New Picklist Instant", - description: "Emit new event when a new pick list is created in Picqer. [See the documentation](https://picqer.com/en/api/webhooks)", - version: "0.0.{{ts}}", - type: "source", - dedupe: "unique", - props: { - picqer, - http: { - type: "$.interface.http", - customResponse: true, - }, - db: "$.service.db", - warehouseId: { - propDefinition: [ - picqer, - "warehouseId", - ], - optional: true, - }, - status: { - propDefinition: [ - picqer, - "status", - ], - optional: true, - }, - }, - methods: { - _getWebhookId() { - return this.db.get("webhookId"); - }, - _setWebhookId(id) { - this.db.set("webhookId", id); - }, - }, - hooks: { - async deploy() { - const picklists = await this.picqer._makeRequest({ - path: "/picklists", - }); - - picklists.slice(-50).forEach((picklist) => { - this.$emit(picklist, { - id: picklist.idpicklist, - summary: `New picklist created: ${picklist.idpicklist}`, - ts: Date.parse(picklist.datecreated), - }); - }); - }, - async activate() { - const webhook = await this.picqer._makeRequest({ - method: "POST", - path: "/webhooks", - data: { - event: "picklists.created", - url: this.http.endpoint, - }, - }); - this._setWebhookId(webhook.id); - }, - async deactivate() { - const id = this._getWebhookId(); - if (id) { - await this.picqer._makeRequest({ - method: "DELETE", - path: `/webhooks/${id}`, - }); - } - }, - }, - async run(event) { - const signature = event.headers["x-picqer-signature"]; - const body = event.body_raw; - const secret = this.picqer.$auth.api_key; - - const computedSignature = crypto.createHmac("sha256", secret) - .update(body) - .digest("base64"); - - if (computedSignature !== signature) { - this.http.respond({ - status: 401, - body: "Unauthorized", - }); - return; - } - - const { body: picklist } = event; - if ( - (!this.warehouseId || this.warehouseId === picklist.idwarehouse) && - (!this.status || this.status === picklist.status) - ) { - this.$emit(picklist, { - id: picklist.idpicklist, - summary: `New picklist created: ${picklist.idpicklist}`, - ts: Date.parse(picklist.datecreated), - }); - } - - this.http.respond({ - status: 200, - }); - }, -}; diff --git a/components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs b/components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs deleted file mode 100644 index fc19d639121ab..0000000000000 --- a/components/picqer/sources/new-shipment-instant/new-shipment-instant.mjs +++ /dev/null @@ -1,102 +0,0 @@ -import picqer from "../../picqer.app.mjs"; -import { axios } from "@pipedream/platform"; -import crypto from "crypto"; - -export default { - key: "picqer-new-shipment-instant", - name: "New Shipment Created", - description: "Emit a new event when a shipment is created for an order in Picqer. [See the documentation](https://picqer.com/en/api/webhooks)", - version: "0.0.{{ts}}", - type: "source", - dedupe: "unique", - props: { - picqer, - http: { - type: "$.interface.http", - customResponse: true, - }, - db: "$.service.db", - carrier: { - propDefinition: [ - picqer, - "carrier", - ], - }, - }, - methods: { - _getWebhookId() { - return this.db.get("webhookId"); - }, - _setWebhookId(id) { - this.db.set("webhookId", id); - }, - }, - hooks: { - async deploy() { - const recentShipments = await this.picqer._makeRequest({ - path: "/shipments", - }); - for (const shipment of recentShipments.slice(0, 50)) { - const ts = Date.parse(shipment.created_at); - this.$emit(shipment, { - id: shipment.idshipment, - summary: `New shipment created: ${shipment.idshipment}`, - ts, - }); - } - }, - async activate() { - const webhookResponse = await this.picqer._makeRequest({ - method: "POST", - path: "/webhooks", - data: { - event: "picklists.shipments.created", - url: this.http.endpoint, - }, - }); - this._setWebhookId(webhookResponse.id); - }, - async deactivate() { - const webhookId = this._getWebhookId(); - if (webhookId) { - await this.picqer._makeRequest({ - method: "DELETE", - path: `/webhooks/${webhookId}`, - }); - } - }, - }, - async run(event) { - const rawBody = event.body_raw; - const webhookSignature = event.headers["x-picqer-signature"]; - const secretKey = this.picqer.$auth.api_key; - const computedSignature = crypto - .createHmac("sha256", secretKey) - .update(rawBody) - .digest("base64"); - - if (computedSignature !== webhookSignature) { - this.http.respond({ - status: 401, - body: "Unauthorized", - }); - return; - } - - this.http.respond({ - status: 200, - body: "OK", - }); - - const { body } = event; - if (this.carrier && body.carrier !== this.carrier) { - return; - } - - this.$emit(body, { - id: body.idshipment, - summary: `New shipment created: ${body.idshipment}`, - ts: Date.parse(body.created_at), - }); - }, -}; From c90e38ff6fd50bb1030c95fecea5ed6cb9a322cb Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 10 Jun 2025 18:15:47 -0300 Subject: [PATCH 03/13] pnpm update --- pnpm-lock.yaml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 57e31305818d9..109a61db30dea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9879,7 +9879,14 @@ importers: specifier: ^1.2.1 version: 1.6.6 - components/picqer: {} + components/picqer: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 + crypto-js: + specifier: ^4.2.0 + version: 4.2.0 components/pidj: dependencies: @@ -15639,14 +15646,6 @@ importers: specifier: ^6.0.0 version: 6.2.0 - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/cjs: {} - - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/esm: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/cjs: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/esm: {} - packages/ai: dependencies: '@pipedream/sdk': From 465c1a1bb31d6fba54fada3a37614aa0dcb87f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Falc=C3=A3o?= <48412907+GTFalcao@users.noreply.github.com> Date: Tue, 17 Jun 2025 18:47:06 -0300 Subject: [PATCH 04/13] Update components/picqer/sources/common/base.mjs --- components/picqer/sources/common/base.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/picqer/sources/common/base.mjs b/components/picqer/sources/common/base.mjs index d20b4ad897ba7..ba8b1d9d197f5 100644 --- a/components/picqer/sources/common/base.mjs +++ b/components/picqer/sources/common/base.mjs @@ -58,7 +58,7 @@ export default { const hash = CryptoJS.HmacSHA256(event.bodyRaw, this.secret); const hashBase64 = CryptoJS.enc.Base64.stringify(hash); - if (hashBase64 != signature) { + if (hashBase64 !== signature) { this.http.respond({ status: 401, body: "Unauthorized", From 64c8246d9277b5d995e9352ad7b9978e0d534717 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 18 Jun 2025 08:53:08 -0300 Subject: [PATCH 05/13] fix products prop --- components/picqer/actions/create-order/create-order.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/picqer/actions/create-order/create-order.mjs b/components/picqer/actions/create-order/create-order.mjs index 470e25eeb8d98..6132cbd0be127 100644 --- a/components/picqer/actions/create-order/create-order.mjs +++ b/components/picqer/actions/create-order/create-order.mjs @@ -224,10 +224,10 @@ export default { optional: true, }, products: { - propDefinition: [ - picqer, - "products", - ], + type: "string[]", + label: "Products", + description: "List of objects of products to add to the order. **Format: [{\"idproduct\": 123, \"productcode\": 'ABC123', \"name\": 'Product Name', \"remarks\": 'Product remarks', \"price\": 100, \"idvatgroup\": 123}]}**", + optional: true, }, }, async additionalProps(fixedProps) { From d9fa20eb57b338f16673c9afd198ae0b8257df54 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 18 Jun 2025 11:04:32 -0300 Subject: [PATCH 06/13] Update create-order.mjs to correct product description format and adjust idorderfield handling --- components/picqer/actions/create-order/create-order.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/picqer/actions/create-order/create-order.mjs b/components/picqer/actions/create-order/create-order.mjs index 6132cbd0be127..1515a21b2ae1f 100644 --- a/components/picqer/actions/create-order/create-order.mjs +++ b/components/picqer/actions/create-order/create-order.mjs @@ -226,7 +226,7 @@ export default { products: { type: "string[]", label: "Products", - description: "List of objects of products to add to the order. **Format: [{\"idproduct\": 123, \"productcode\": 'ABC123', \"name\": 'Product Name', \"remarks\": 'Product remarks', \"price\": 100, \"idvatgroup\": 123}]}**", + description: "List of objects of products to add to the order. **Format: [{\"idproduct\": 123, \"productcode\": \"ABC123\", \"name\": \"Product Name\", \"remarks\": \"Product remarks\", \"amount\": 100, \"idvatgroup\": 123}]**", optional: true, }, }, @@ -267,7 +267,7 @@ export default { propData.options = field.values; } - props[field.idorderfield] = propData; + props[`id${field.idorderfield}`] = propData; } } return props; @@ -350,7 +350,7 @@ export default { key, value, ]) => ({ - idorderfield: parseInt(key), + idorderfield: parseInt(key.replace("id", "")), value: Array.isArray(value) ? value.join(";") : value, From 55db77137e3f2fbf63fab87fb701085dffcd7b4d Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 18 Jun 2025 11:13:41 -0300 Subject: [PATCH 07/13] pnpm update --- pnpm-lock.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6f32bfd537c43..2038ef6626eee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15846,7 +15846,7 @@ importers: version: 3.1.7 ts-jest: specifier: ^29.2.5 - version: 29.2.5(@babel/core@8.0.0-alpha.13)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-alpha.13))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0))(typescript@5.7.2) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0))(typescript@5.7.2) tsup: specifier: ^8.3.6 version: 8.3.6(@microsoft/api-extractor@7.47.12(@types/node@20.17.30))(jiti@1.21.6)(postcss@8.4.49)(tsx@4.19.4)(typescript@5.7.2)(yaml@2.6.1) @@ -15889,7 +15889,7 @@ importers: version: 3.1.0 jest: specifier: ^29.1.2 - version: 29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0) + version: 29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0) type-fest: specifier: ^4.15.0 version: 4.27.0 @@ -49810,7 +49810,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@8.0.0-alpha.13)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-alpha.13))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0))(typescript@5.7.2): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.30)(babel-plugin-macros@3.1.0))(typescript@5.7.2): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -49824,10 +49824,10 @@ snapshots: typescript: 5.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 8.0.0-alpha.13 + '@babel/core': 7.26.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@8.0.0-alpha.13) + babel-jest: 29.7.0(@babel/core@7.26.0) ts-jest@29.2.5(@babel/core@8.0.0-alpha.13)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-alpha.13))(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0))(typescript@5.6.3): dependencies: From 190ae32414fc6b5bc6bf0debdeaa2afdc663ca94 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Jun 2025 12:25:23 -0300 Subject: [PATCH 08/13] update pnpm-lock.yaml --- pnpm-lock.yaml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bd5ca9ffc818..1f3f85f02b8ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2850,8 +2850,7 @@ importers: components/common_paper: {} - components/commonninja: - specifiers: {} + components/commonninja: {} components/commpeak: dependencies: @@ -9307,8 +9306,7 @@ importers: specifier: ^17.0.45 version: 17.0.45 - components/openai_passthrough: - specifiers: {} + components/openai_passthrough: {} components/opencage: dependencies: @@ -9907,8 +9905,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/phonely: - specifiers: {} + components/phonely: {} components/php_point_of_sale: dependencies: @@ -13428,8 +13425,7 @@ importers: components/test_apps_for_switching_appslug_009: {} - components/test_apps_for_switching_appslug_025: - specifiers: {} + components/test_apps_for_switching_appslug_025: {} components/testlocally: dependencies: From e863febe3ddca0ebc10568ce782de4700b4c2eaa Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Jun 2025 12:56:02 -0300 Subject: [PATCH 09/13] Refactor HMAC signature verification in base.mjs to ensure proper handling of unauthorized requests --- components/picqer/sources/common/base.mjs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/components/picqer/sources/common/base.mjs b/components/picqer/sources/common/base.mjs index ba8b1d9d197f5..1c8c58bcce806 100644 --- a/components/picqer/sources/common/base.mjs +++ b/components/picqer/sources/common/base.mjs @@ -55,15 +55,17 @@ export default { async run(event) { const { body } = event; const signature = event?.headers["x-picqer-signature"]; - const hash = CryptoJS.HmacSHA256(event.bodyRaw, this.secret); - const hashBase64 = CryptoJS.enc.Base64.stringify(hash); + if (signature) { + const hash = CryptoJS.HmacSHA256(event.bodyRaw, this.secret); + const hashBase64 = CryptoJS.enc.Base64.stringify(hash); - if (hashBase64 !== signature) { - this.http.respond({ - status: 401, - body: "Unauthorized", - }); - return; + if (hashBase64 !== signature) { + this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } } this.http.respond({ From 530eee896bff0cd0265c863604a2a466e22a869f Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Jun 2025 13:12:06 -0300 Subject: [PATCH 10/13] [ACTION] New Trigger action "New Lead Update (Instant)" in Pipedrive #17171 Sources - Updated Lead (Instant) --- .../actions/add-activity/add-activity.mjs | 2 +- .../pipedrive/actions/add-deal/add-deal.mjs | 2 +- .../pipedrive/actions/add-lead/add-lead.mjs | 4 +- .../pipedrive/actions/add-note/add-note.mjs | 2 +- .../add-organization/add-organization.mjs | 2 +- .../actions/add-person/add-person.mjs | 2 +- .../remove-duplicate-notes.mjs | 4 +- .../actions/search-notes/search-notes.mjs | 2 +- .../actions/search-persons/search-persons.mjs | 2 +- .../actions/update-deal/update-deal.mjs | 2 +- .../actions/update-person/update-person.mjs | 2 +- components/pipedrive/package.json | 4 +- .../new-deal-instant/new-deal-instant.mjs | 2 +- .../new-person-instant/new-person-instant.mjs | 2 +- .../updated-deal-instant.mjs | 2 +- .../updated-lead-instant/test-event.mjs | 56 +++++++++++++++++++ .../updated-lead-instant.mjs | 25 +++++++++ .../updated-person-instant.mjs | 2 +- 18 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 components/pipedrive/sources/updated-lead-instant/test-event.mjs create mode 100644 components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs diff --git a/components/pipedrive/actions/add-activity/add-activity.mjs b/components/pipedrive/actions/add-activity/add-activity.mjs index 2c96278c47155..1f94468a38837 100644 --- a/components/pipedrive/actions/add-activity/add-activity.mjs +++ b/components/pipedrive/actions/add-activity/add-activity.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-add-activity", name: "Add Activity", description: "Adds a new activity. Includes `more_activities_scheduled_in_context` property in response's `additional_data` which indicates whether there are more undone activities scheduled with the same deal, person or organization (depending on the supplied data). See the Pipedrive API docs for Activities [here](https://developers.pipedrive.com/docs/api/v1/#!/Activities). For info on [adding an activity in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Activities#addActivity)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-deal/add-deal.mjs b/components/pipedrive/actions/add-deal/add-deal.mjs index fe13f92baa689..4f6ee648da9d2 100644 --- a/components/pipedrive/actions/add-deal/add-deal.mjs +++ b/components/pipedrive/actions/add-deal/add-deal.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-deal", name: "Add Deal", description: "Adds a new deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#addDeal)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-lead/add-lead.mjs b/components/pipedrive/actions/add-lead/add-lead.mjs index 850ed90947eee..3e233f1e3631c 100644 --- a/components/pipedrive/actions/add-lead/add-lead.mjs +++ b/components/pipedrive/actions/add-lead/add-lead.mjs @@ -1,12 +1,12 @@ -import pipedrive from "../../pipedrive.app.mjs"; import { ConfigurationError } from "@pipedream/platform"; import { parseObject } from "../../common/utils.mjs"; +import pipedrive from "../../pipedrive.app.mjs"; export default { key: "pipedrive-add-lead", name: "Add Lead", description: "Create a new lead in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Leads#addLead)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { pipedrive, diff --git a/components/pipedrive/actions/add-note/add-note.mjs b/components/pipedrive/actions/add-note/add-note.mjs index 2f33e6e7384d3..9eaccd8f77956 100644 --- a/components/pipedrive/actions/add-note/add-note.mjs +++ b/components/pipedrive/actions/add-note/add-note.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-note", name: "Add Note", description: "Adds a new note. For info on [adding an note in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Notes#addNote)", - version: "0.0.8", + version: "0.0.9", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-organization/add-organization.mjs b/components/pipedrive/actions/add-organization/add-organization.mjs index 55d5f0ba5e9f1..c33aacf6f82fd 100644 --- a/components/pipedrive/actions/add-organization/add-organization.mjs +++ b/components/pipedrive/actions/add-organization/add-organization.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-organization", name: "Add Organization", description: "Adds a new organization. See the Pipedrive API docs for Organizations [here](https://developers.pipedrive.com/docs/api/v1/Organizations#addOrganization)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-person/add-person.mjs b/components/pipedrive/actions/add-person/add-person.mjs index 1d3bbc901ee71..9d214cca4b4bd 100644 --- a/components/pipedrive/actions/add-person/add-person.mjs +++ b/components/pipedrive/actions/add-person/add-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-add-person", name: "Add Person", description: "Adds a new person. See the Pipedrive API docs for People [here](https://developers.pipedrive.com/docs/api/v1/Persons#addPerson)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs index c8114ffe86ace..7d32a343cbabe 100644 --- a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -1,11 +1,11 @@ -import pipedriveApp from "../../pipedrive.app.mjs"; import { decode } from "html-entities"; +import pipedriveApp from "../../pipedrive.app.mjs"; export default { key: "pipedrive-remove-duplicate-notes", name: "Remove Duplicate Notes", description: "Remove duplicate notes from an object in Pipedrive. See the documentation for [getting notes](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes) and [deleting notes](https://developers.pipedrive.com/docs/api/v1/Notes#deleteNote)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/search-notes/search-notes.mjs b/components/pipedrive/actions/search-notes/search-notes.mjs index 9f76f363c3773..cf40c148b5c66 100644 --- a/components/pipedrive/actions/search-notes/search-notes.mjs +++ b/components/pipedrive/actions/search-notes/search-notes.mjs @@ -4,7 +4,7 @@ export default { key: "pipedrive-search-notes", name: "Search Notes", description: "Search for notes in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/search-persons/search-persons.mjs b/components/pipedrive/actions/search-persons/search-persons.mjs index c1b47f7700785..bade41b0423b5 100644 --- a/components/pipedrive/actions/search-persons/search-persons.mjs +++ b/components/pipedrive/actions/search-persons/search-persons.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-search-persons", name: "Search persons", description: "Searches all Persons by `name`, `email`, `phone`, `notes` and/or custom fields. This endpoint is a wrapper of `/v1/itemSearch` with a narrower OAuth scope. Found Persons can be filtered by Organization ID. See the Pipedrive API docs [here](https://developers.pipedrive.com/docs/api/v1/Persons#searchPersons)", - version: "0.1.10", + version: "0.1.11", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-deal/update-deal.mjs b/components/pipedrive/actions/update-deal/update-deal.mjs index e1ef1d03977af..cbc7fe25091ab 100644 --- a/components/pipedrive/actions/update-deal/update-deal.mjs +++ b/components/pipedrive/actions/update-deal/update-deal.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-update-deal", name: "Update Deal", description: "Updates the properties of a deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#updateDeal)", - version: "0.1.12", + version: "0.1.13", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-person/update-person.mjs b/components/pipedrive/actions/update-person/update-person.mjs index 13f447d3030ce..084f0393a7185 100644 --- a/components/pipedrive/actions/update-person/update-person.mjs +++ b/components/pipedrive/actions/update-person/update-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-update-person", name: "Update Person", description: "Updates an existing person in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Persons#updatePerson)", - version: "0.0.2", + version: "0.0.3", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/package.json b/components/pipedrive/package.json index 79cbd3091f598..4cdd7598550e1 100644 --- a/components/pipedrive/package.json +++ b/components/pipedrive/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/pipedrive", - "version": "0.6.0", + "version": "0.7.0", "description": "Pipedream Pipedrive Components", "main": "pipedrive.app.mjs", "keywords": [ @@ -14,7 +14,7 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^3.0.3", + "@pipedream/platform": "^3.1.0", "html-entities": "^2.6.0", "pipedrive": "^24.1.1" } diff --git a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs index 881bda6ffdd18..6d5a5507f706e 100644 --- a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs +++ b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-deal-instant", name: "New Deal (Instant)", description: "Emit new event when a new deal is created.", - version: "0.0.6", + version: "0.0.7", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs index 210aac876d859..ca89b4eb24ad9 100644 --- a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs +++ b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-person-instant", name: "New Person (Instant)", description: "Emit new event when a new person is created.", - version: "0.0.6", + version: "0.0.7", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs index 69b221e2e9168..faa9b73cd2ae0 100644 --- a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs +++ b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-updated-deal-instant", name: "New Deal Update (Instant)", description: "Emit new event when a deal is updated.", - version: "0.0.6", + version: "0.0.7", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-lead-instant/test-event.mjs b/components/pipedrive/sources/updated-lead-instant/test-event.mjs new file mode 100644 index 0000000000000..c64d0ebcb06b3 --- /dev/null +++ b/components/pipedrive/sources/updated-lead-instant/test-event.mjs @@ -0,0 +1,56 @@ +export default { + "data": { + "add_time": "2025-06-19T16:07:08.597Z", + "channel": null, + "channel_id": null, + "creator_id": 12345678, + "custom_fields": {}, + "expected_close_date": null, + "id": "123456789-1234-1234-1234-123456789012", + "is_archived": false, + "label_ids": [ + "123456789-1234-1234-1234-123456789012", + "123456789-1234-1234-1234-123456789012", + "123456789-1234-1234-1234-123456789012" + ], + "next_activity_id": null, + "organization_id": null, + "origin": "ManuallyCreated", + "origin_id": null, + "owner_id": 12345678, + "person_id": 12, + "source_name": "Manually created", + "title": "Lead Title", + "update_time": "2025-06-19T16:07:36.753Z", + "was_seen": true, + "value": { + "amount": 123, + "currency": "BRL" + } + }, + "previous": { + "update_time": "2025-06-19T16:07:30.029Z", + "value": null + }, + "meta": { + "action": "change", + "company_id": "12345678", + "correlation_id": "123456789-1234-1234-1234-123456789012", + "entity_id": "123456789-1234-1234-1234-123456789012", + "entity": "lead", + "id": "123456789-1234-1234-1234-123456789012", + "is_bulk_edit": false, + "timestamp": "2025-06-19T16:07:36.754Z", + "type": "application", + "user_id": "12345678", + "version": "2.0", + "webhook_id": "12345678", + "webhook_owner_id": "12345678", + "change_source": "app", + "permitted_user_ids": [ + "12345678" + ], + "attempt": 1, + "host": "pd.pipedrive.com" + } +} \ No newline at end of file diff --git a/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs b/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs new file mode 100644 index 0000000000000..6c861d0bcce35 --- /dev/null +++ b/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs @@ -0,0 +1,25 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "pipedrive-updated-lead-instant", + name: "Updated Lead (Instant)", + description: "Emit new event when a lead is updated.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getExtraData() { + return { + event_action: "change", + event_object: "lead", + }; + }, + getSummary(body) { + return `Lead successfully updated: ${body.data.id}`; + }, + }, + sampleEmit, +}; diff --git a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs index cb09964ece5a7..2e1effd9fbe5f 100644 --- a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs +++ b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-updated-person-instant", name: "Updated Person (Instant)", description: "Emit new event when a person is updated.", - version: "0.0.6", + version: "0.0.7", type: "source", dedupe: "unique", methods: { From 406c684fe8eb2e390e0f3e14f6edffebb128cb70 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Jun 2025 13:13:43 -0300 Subject: [PATCH 11/13] pnpm update --- pnpm-lock.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f3f85f02b8ef..4725725af93bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10087,8 +10087,8 @@ importers: components/pipedrive: dependencies: '@pipedream/platform': - specifier: ^3.0.3 - version: 3.0.3 + specifier: ^3.1.0 + version: 3.1.0 html-entities: specifier: ^2.6.0 version: 2.6.0 From a2dd8f18406bfb4c2cf550eca952361d14ec9002 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Jun 2025 14:49:37 -0300 Subject: [PATCH 12/13] Revert "pnpm update" This reverts commit 406c684fe8eb2e390e0f3e14f6edffebb128cb70. --- pnpm-lock.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4725725af93bf..1f3f85f02b8ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10087,8 +10087,8 @@ importers: components/pipedrive: dependencies: '@pipedream/platform': - specifier: ^3.1.0 - version: 3.1.0 + specifier: ^3.0.3 + version: 3.0.3 html-entities: specifier: ^2.6.0 version: 2.6.0 From 9bdd1c80cec08f7171e511258fea98ac6192d3b3 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Jun 2025 14:49:56 -0300 Subject: [PATCH 13/13] Revert "[ACTION] New Trigger action "New Lead Update (Instant)" in Pipedrive #17171" This reverts commit 530eee896bff0cd0265c863604a2a466e22a869f. --- .../actions/add-activity/add-activity.mjs | 2 +- .../pipedrive/actions/add-deal/add-deal.mjs | 2 +- .../pipedrive/actions/add-lead/add-lead.mjs | 4 +- .../pipedrive/actions/add-note/add-note.mjs | 2 +- .../add-organization/add-organization.mjs | 2 +- .../actions/add-person/add-person.mjs | 2 +- .../remove-duplicate-notes.mjs | 4 +- .../actions/search-notes/search-notes.mjs | 2 +- .../actions/search-persons/search-persons.mjs | 2 +- .../actions/update-deal/update-deal.mjs | 2 +- .../actions/update-person/update-person.mjs | 2 +- components/pipedrive/package.json | 4 +- .../new-deal-instant/new-deal-instant.mjs | 2 +- .../new-person-instant/new-person-instant.mjs | 2 +- .../updated-deal-instant.mjs | 2 +- .../updated-lead-instant/test-event.mjs | 56 ------------------- .../updated-lead-instant.mjs | 25 --------- .../updated-person-instant.mjs | 2 +- 18 files changed, 19 insertions(+), 100 deletions(-) delete mode 100644 components/pipedrive/sources/updated-lead-instant/test-event.mjs delete mode 100644 components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs diff --git a/components/pipedrive/actions/add-activity/add-activity.mjs b/components/pipedrive/actions/add-activity/add-activity.mjs index 1f94468a38837..2c96278c47155 100644 --- a/components/pipedrive/actions/add-activity/add-activity.mjs +++ b/components/pipedrive/actions/add-activity/add-activity.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-add-activity", name: "Add Activity", description: "Adds a new activity. Includes `more_activities_scheduled_in_context` property in response's `additional_data` which indicates whether there are more undone activities scheduled with the same deal, person or organization (depending on the supplied data). See the Pipedrive API docs for Activities [here](https://developers.pipedrive.com/docs/api/v1/#!/Activities). For info on [adding an activity in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Activities#addActivity)", - version: "0.1.11", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-deal/add-deal.mjs b/components/pipedrive/actions/add-deal/add-deal.mjs index 4f6ee648da9d2..fe13f92baa689 100644 --- a/components/pipedrive/actions/add-deal/add-deal.mjs +++ b/components/pipedrive/actions/add-deal/add-deal.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-deal", name: "Add Deal", description: "Adds a new deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#addDeal)", - version: "0.1.11", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-lead/add-lead.mjs b/components/pipedrive/actions/add-lead/add-lead.mjs index 3e233f1e3631c..850ed90947eee 100644 --- a/components/pipedrive/actions/add-lead/add-lead.mjs +++ b/components/pipedrive/actions/add-lead/add-lead.mjs @@ -1,12 +1,12 @@ +import pipedrive from "../../pipedrive.app.mjs"; import { ConfigurationError } from "@pipedream/platform"; import { parseObject } from "../../common/utils.mjs"; -import pipedrive from "../../pipedrive.app.mjs"; export default { key: "pipedrive-add-lead", name: "Add Lead", description: "Create a new lead in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Leads#addLead)", - version: "0.0.5", + version: "0.0.4", type: "action", props: { pipedrive, diff --git a/components/pipedrive/actions/add-note/add-note.mjs b/components/pipedrive/actions/add-note/add-note.mjs index 9eaccd8f77956..2f33e6e7384d3 100644 --- a/components/pipedrive/actions/add-note/add-note.mjs +++ b/components/pipedrive/actions/add-note/add-note.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-note", name: "Add Note", description: "Adds a new note. For info on [adding an note in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Notes#addNote)", - version: "0.0.9", + version: "0.0.8", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-organization/add-organization.mjs b/components/pipedrive/actions/add-organization/add-organization.mjs index c33aacf6f82fd..55d5f0ba5e9f1 100644 --- a/components/pipedrive/actions/add-organization/add-organization.mjs +++ b/components/pipedrive/actions/add-organization/add-organization.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-organization", name: "Add Organization", description: "Adds a new organization. See the Pipedrive API docs for Organizations [here](https://developers.pipedrive.com/docs/api/v1/Organizations#addOrganization)", - version: "0.1.11", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-person/add-person.mjs b/components/pipedrive/actions/add-person/add-person.mjs index 9d214cca4b4bd..1d3bbc901ee71 100644 --- a/components/pipedrive/actions/add-person/add-person.mjs +++ b/components/pipedrive/actions/add-person/add-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-add-person", name: "Add Person", description: "Adds a new person. See the Pipedrive API docs for People [here](https://developers.pipedrive.com/docs/api/v1/Persons#addPerson)", - version: "0.1.11", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs index 7d32a343cbabe..c8114ffe86ace 100644 --- a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -1,11 +1,11 @@ -import { decode } from "html-entities"; import pipedriveApp from "../../pipedrive.app.mjs"; +import { decode } from "html-entities"; export default { key: "pipedrive-remove-duplicate-notes", name: "Remove Duplicate Notes", description: "Remove duplicate notes from an object in Pipedrive. See the documentation for [getting notes](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes) and [deleting notes](https://developers.pipedrive.com/docs/api/v1/Notes#deleteNote)", - version: "0.0.2", + version: "0.0.1", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/search-notes/search-notes.mjs b/components/pipedrive/actions/search-notes/search-notes.mjs index cf40c148b5c66..9f76f363c3773 100644 --- a/components/pipedrive/actions/search-notes/search-notes.mjs +++ b/components/pipedrive/actions/search-notes/search-notes.mjs @@ -4,7 +4,7 @@ export default { key: "pipedrive-search-notes", name: "Search Notes", description: "Search for notes in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes)", - version: "0.0.2", + version: "0.0.1", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/search-persons/search-persons.mjs b/components/pipedrive/actions/search-persons/search-persons.mjs index bade41b0423b5..c1b47f7700785 100644 --- a/components/pipedrive/actions/search-persons/search-persons.mjs +++ b/components/pipedrive/actions/search-persons/search-persons.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-search-persons", name: "Search persons", description: "Searches all Persons by `name`, `email`, `phone`, `notes` and/or custom fields. This endpoint is a wrapper of `/v1/itemSearch` with a narrower OAuth scope. Found Persons can be filtered by Organization ID. See the Pipedrive API docs [here](https://developers.pipedrive.com/docs/api/v1/Persons#searchPersons)", - version: "0.1.11", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-deal/update-deal.mjs b/components/pipedrive/actions/update-deal/update-deal.mjs index cbc7fe25091ab..e1ef1d03977af 100644 --- a/components/pipedrive/actions/update-deal/update-deal.mjs +++ b/components/pipedrive/actions/update-deal/update-deal.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-update-deal", name: "Update Deal", description: "Updates the properties of a deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#updateDeal)", - version: "0.1.13", + version: "0.1.12", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-person/update-person.mjs b/components/pipedrive/actions/update-person/update-person.mjs index 084f0393a7185..13f447d3030ce 100644 --- a/components/pipedrive/actions/update-person/update-person.mjs +++ b/components/pipedrive/actions/update-person/update-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-update-person", name: "Update Person", description: "Updates an existing person in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Persons#updatePerson)", - version: "0.0.3", + version: "0.0.2", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/package.json b/components/pipedrive/package.json index 4cdd7598550e1..79cbd3091f598 100644 --- a/components/pipedrive/package.json +++ b/components/pipedrive/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/pipedrive", - "version": "0.7.0", + "version": "0.6.0", "description": "Pipedream Pipedrive Components", "main": "pipedrive.app.mjs", "keywords": [ @@ -14,7 +14,7 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^3.1.0", + "@pipedream/platform": "^3.0.3", "html-entities": "^2.6.0", "pipedrive": "^24.1.1" } diff --git a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs index 6d5a5507f706e..881bda6ffdd18 100644 --- a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs +++ b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-deal-instant", name: "New Deal (Instant)", description: "Emit new event when a new deal is created.", - version: "0.0.7", + version: "0.0.6", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs index ca89b4eb24ad9..210aac876d859 100644 --- a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs +++ b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-person-instant", name: "New Person (Instant)", description: "Emit new event when a new person is created.", - version: "0.0.7", + version: "0.0.6", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs index faa9b73cd2ae0..69b221e2e9168 100644 --- a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs +++ b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-updated-deal-instant", name: "New Deal Update (Instant)", description: "Emit new event when a deal is updated.", - version: "0.0.7", + version: "0.0.6", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-lead-instant/test-event.mjs b/components/pipedrive/sources/updated-lead-instant/test-event.mjs deleted file mode 100644 index c64d0ebcb06b3..0000000000000 --- a/components/pipedrive/sources/updated-lead-instant/test-event.mjs +++ /dev/null @@ -1,56 +0,0 @@ -export default { - "data": { - "add_time": "2025-06-19T16:07:08.597Z", - "channel": null, - "channel_id": null, - "creator_id": 12345678, - "custom_fields": {}, - "expected_close_date": null, - "id": "123456789-1234-1234-1234-123456789012", - "is_archived": false, - "label_ids": [ - "123456789-1234-1234-1234-123456789012", - "123456789-1234-1234-1234-123456789012", - "123456789-1234-1234-1234-123456789012" - ], - "next_activity_id": null, - "organization_id": null, - "origin": "ManuallyCreated", - "origin_id": null, - "owner_id": 12345678, - "person_id": 12, - "source_name": "Manually created", - "title": "Lead Title", - "update_time": "2025-06-19T16:07:36.753Z", - "was_seen": true, - "value": { - "amount": 123, - "currency": "BRL" - } - }, - "previous": { - "update_time": "2025-06-19T16:07:30.029Z", - "value": null - }, - "meta": { - "action": "change", - "company_id": "12345678", - "correlation_id": "123456789-1234-1234-1234-123456789012", - "entity_id": "123456789-1234-1234-1234-123456789012", - "entity": "lead", - "id": "123456789-1234-1234-1234-123456789012", - "is_bulk_edit": false, - "timestamp": "2025-06-19T16:07:36.754Z", - "type": "application", - "user_id": "12345678", - "version": "2.0", - "webhook_id": "12345678", - "webhook_owner_id": "12345678", - "change_source": "app", - "permitted_user_ids": [ - "12345678" - ], - "attempt": 1, - "host": "pd.pipedrive.com" - } -} \ No newline at end of file diff --git a/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs b/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs deleted file mode 100644 index 6c861d0bcce35..0000000000000 --- a/components/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjs +++ /dev/null @@ -1,25 +0,0 @@ -import common from "../common/base.mjs"; -import sampleEmit from "./test-event.mjs"; - -export default { - ...common, - key: "pipedrive-updated-lead-instant", - name: "Updated Lead (Instant)", - description: "Emit new event when a lead is updated.", - version: "0.0.1", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - getExtraData() { - return { - event_action: "change", - event_object: "lead", - }; - }, - getSummary(body) { - return `Lead successfully updated: ${body.data.id}`; - }, - }, - sampleEmit, -}; diff --git a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs index 2e1effd9fbe5f..cb09964ece5a7 100644 --- a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs +++ b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-updated-person-instant", name: "Updated Person (Instant)", description: "Emit new event when a person is updated.", - version: "0.0.7", + version: "0.0.6", type: "source", dedupe: "unique", methods: {