diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index b79a166e901..f049157d62c 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -1193,6 +1193,18 @@ export function DocuSignIcon(props: SVGProps) { ) } +export function DoordashIcon(props: SVGProps) { + return ( + + + + + ) +} + export function DiscordIcon(props: SVGProps) { return ( > @@ -210,6 +211,7 @@ export const blockTypeToIconMap: Record = { devin: DevinIcon, discord: DiscordIcon, docusign: DocuSignIcon, + doordash: DoordashIcon, dropbox: DropboxIcon, dspy: DsPyIcon, dub: DubIcon, diff --git a/apps/docs/content/docs/en/tools/doordash.mdx b/apps/docs/content/docs/en/tools/doordash.mdx new file mode 100644 index 00000000000..2de3b1bdb9e --- /dev/null +++ b/apps/docs/content/docs/en/tools/doordash.mdx @@ -0,0 +1,460 @@ +--- +title: DoorDash +description: Create and manage DoorDash Drive deliveries, businesses, and stores +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +## Overview + +The DoorDash block integrates with the [DoorDash Drive API](https://developer.doordash.com/en-US/docs/drive/overview/) to enable last-mile delivery orchestration directly from your workflows. + +### Authentication + +DoorDash Drive uses **JWT-based authentication** with three credentials: + +- **Developer ID** — Your DoorDash developer account identifier +- **Key ID** — The key identifier for signing requests +- **Signing Secret** — The secret used to sign JWT tokens (Base64-encoded) + +You can find these credentials in the [DoorDash Developer Portal](https://developer.doordash.com/portal/integration/drive/credentials). + +### Recommended Workflow + +The typical delivery flow is: + +1. **Create Quote** — Validate delivery coverage, get pricing and ETAs +2. **Accept Quote** — Confirm the quote to create the delivery (must be within 5 minutes) +3. **Get Delivery** — Track delivery status and Dasher assignment +4. **Update Delivery** — Modify tip or dropoff details if needed +5. **Cancel Delivery** — Cancel before a Dasher is assigned + +Alternatively, use **Create Delivery** to skip the quote step and create a delivery directly. + +### Business & Store Management + +DoorDash Drive also supports managing business entities and store locations: + +- **Create/List/Update Business** — Organize your delivery operations under business entities +- **Create/List/Get/Update Store** — Manage store locations under businesses for pickup + +### Important Notes + +- DoorDash Drive is a **delivery-only** API — it does not support placing food/product orders +- Order values and fees are in **cents** (e.g., `1999` = $19.99) +- `pickupTime` and `dropoffTime` are **mutually exclusive** — set one or the other, not both +- Delivery cancellation is only possible **before** a Dasher is assigned + +## Tools + +### `doordash_create_quote` + +Creates a delivery quote to validate coverage, pricing, and estimated delivery times. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | DoorDash Key ID | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalDeliveryId` | string | Yes | Unique delivery identifier | +| `pickupAddress` | string | Yes | Pickup address \(e.g., "901 Market Street 6th Floor San Francisco, CA 94103"\) | +| `pickupPhoneNumber` | string | Yes | Pickup phone number \(e.g., "+16505555555"\) | +| `pickupBusinessName` | string | Yes | Pickup business name | +| `dropoffAddress` | string | Yes | Dropoff address | +| `dropoffPhoneNumber` | string | Yes | Dropoff phone number | +| `dropoffBusinessName` | string | Yes | Dropoff contact or business name | +| `orderValue` | string | Yes | Order value in cents \(e.g., "1999" for $19.99\) | +| `pickupInstructions` | string | No | Instructions for pickup | +| `dropoffInstructions` | string | No | Instructions for dropoff | +| `tip` | string | No | Tip amount in cents | +| `dropoffContactSendNotifications` | string | No | Send SMS notifications to recipient \(true/false\) | +| `actionIfUndeliverable` | string | No | Action if undeliverable \(e.g., "return_to_pickup"\) | +| `contactlessDropoff` | string | No | Contactless doorstep delivery with photo verification \(true/false\) | +| `dropoffRequiresSignature` | string | No | Require signature at dropoff \(true/false\) | +| `dropoffContactGivenName` | string | No | Recipient first name | +| `dropoffContactFamilyName` | string | No | Recipient last name | +| `pickupTime` | string | No | Scheduled pickup time \(ISO 8601, mutually exclusive with dropoffTime\) | +| `dropoffTime` | string | No | Scheduled dropoff time \(ISO 8601, mutually exclusive with pickupTime\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalDeliveryId` | string | External delivery ID | +| `deliveryStatus` | string | Delivery status | +| `fee` | number | Delivery fee in cents | +| `currency` | string | Fee currency code | +| `pickupTimeEstimated` | string | Estimated pickup time | +| `dropoffTimeEstimated` | string | Estimated dropoff time | + +### `doordash_accept_quote` + +Accepts a delivery quote to formally create the delivery. Must be called within 5 minutes of creating the quote. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | DoorDash Key ID | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalDeliveryId` | string | Yes | External delivery ID from the quote | +| `tip` | string | No | Tip amount in cents | +| `dropoffPhoneNumber` | string | No | Updated dropoff phone number | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalDeliveryId` | string | External delivery ID | +| `deliveryStatus` | string | Delivery status | +| `fee` | number | Delivery fee in cents | +| `tip` | number | Tip amount in cents | +| `orderValue` | number | Order value in cents | +| `currency` | string | Fee currency code | +| `trackingUrl` | string | Delivery tracking URL | +| `supportReference` | string | Support reference ID | +| `dasherName` | string | Assigned Dasher name | +| `dasherId` | number | Assigned Dasher ID | +| `contactlessDropoff` | boolean | Whether contactless dropoff was used | +| `dropoffVerificationImageUrl` | string | Photo verification URL at dropoff | +| `cancellationReason` | string | Reason for cancellation | +| `pickupTimeEstimated` | string | Estimated pickup time | +| `pickupTimeActual` | string | Actual pickup time | +| `dropoffTimeEstimated` | string | Estimated dropoff time | +| `dropoffTimeActual` | string | Actual dropoff time | +| `pickupAddress` | string | Pickup address | +| `dropoffAddress` | string | Dropoff address | +| `updatedAt` | string | Last updated timestamp | + +### `doordash_create_delivery` + +Creates a delivery directly without a prior quote. Skips price confirmation. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | DoorDash Key ID | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalDeliveryId` | string | Yes | Unique delivery identifier | +| `pickupAddress` | string | Yes | Pickup address \(e.g., "901 Market Street 6th Floor San Francisco, CA 94103"\) | +| `pickupPhoneNumber` | string | Yes | Pickup phone number \(e.g., "+16505555555"\) | +| `pickupBusinessName` | string | Yes | Pickup business name | +| `dropoffAddress` | string | Yes | Dropoff address | +| `dropoffPhoneNumber` | string | Yes | Dropoff phone number | +| `dropoffBusinessName` | string | Yes | Dropoff contact or business name | +| `orderValue` | string | Yes | Order value in cents \(e.g., "1999" for $19.99\) | +| `pickupInstructions` | string | No | Instructions for pickup | +| `dropoffInstructions` | string | No | Instructions for dropoff | +| `tip` | string | No | Tip amount in cents | +| `dropoffContactSendNotifications` | string | No | Send SMS notifications to recipient \(true/false\) | +| `actionIfUndeliverable` | string | No | Action if undeliverable \(e.g., "return_to_pickup"\) | +| `contactlessDropoff` | string | No | Contactless doorstep delivery with photo verification \(true/false\) | +| `dropoffRequiresSignature` | string | No | Require signature at dropoff \(true/false\) | +| `dropoffContactGivenName` | string | No | Recipient first name | +| `dropoffContactFamilyName` | string | No | Recipient last name | +| `pickupTime` | string | No | Scheduled pickup time \(ISO 8601, mutually exclusive with dropoffTime\) | +| `dropoffTime` | string | No | Scheduled dropoff time \(ISO 8601, mutually exclusive with pickupTime\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalDeliveryId` | string | External delivery ID | +| `deliveryStatus` | string | Delivery status | +| `fee` | number | Delivery fee in cents | +| `tip` | number | Tip amount in cents | +| `orderValue` | number | Order value in cents | +| `currency` | string | Fee currency code | +| `trackingUrl` | string | Delivery tracking URL | +| `supportReference` | string | Support reference ID | +| `dasherName` | string | Assigned Dasher name | +| `dasherId` | number | Assigned Dasher ID | +| `contactlessDropoff` | boolean | Whether contactless dropoff was used | +| `dropoffVerificationImageUrl` | string | Photo verification URL at dropoff | +| `cancellationReason` | string | Reason for cancellation | +| `pickupTimeEstimated` | string | Estimated pickup time | +| `pickupTimeActual` | string | Actual pickup time | +| `dropoffTimeEstimated` | string | Estimated dropoff time | +| `dropoffTimeActual` | string | Actual dropoff time | +| `pickupAddress` | string | Pickup address | +| `dropoffAddress` | string | Dropoff address | +| `updatedAt` | string | Last updated timestamp | + +### `doordash_get_delivery` + +Retrieves the current status and details of a delivery. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | DoorDash Key ID | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalDeliveryId` | string | Yes | External delivery ID to look up | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalDeliveryId` | string | External delivery ID | +| `deliveryStatus` | string | Delivery status | +| `fee` | number | Delivery fee in cents | +| `tip` | number | Tip amount in cents | +| `orderValue` | number | Order value in cents | +| `currency` | string | Fee currency code | +| `trackingUrl` | string | Delivery tracking URL | +| `supportReference` | string | Support reference ID | +| `dasherName` | string | Assigned Dasher name | +| `dasherId` | number | Assigned Dasher ID | +| `contactlessDropoff` | boolean | Whether contactless dropoff was used | +| `dropoffVerificationImageUrl` | string | Photo verification URL at dropoff | +| `cancellationReason` | string | Reason for cancellation | +| `pickupTimeEstimated` | string | Estimated pickup time | +| `pickupTimeActual` | string | Actual pickup time | +| `dropoffTimeEstimated` | string | Estimated dropoff time | +| `dropoffTimeActual` | string | Actual dropoff time | +| `pickupAddress` | string | Pickup address | +| `dropoffAddress` | string | Dropoff address | +| `updatedAt` | string | Last updated timestamp | + +### `doordash_update_delivery` + +Updates a delivery. Only tip and dropoff details can be modified after creation. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | DoorDash Key ID | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalDeliveryId` | string | Yes | External delivery ID to update | +| `tip` | string | No | Updated tip amount in cents | +| `dropoffPhoneNumber` | string | No | Updated dropoff phone number | +| `dropoffInstructions` | string | No | Updated dropoff instructions | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalDeliveryId` | string | External delivery ID | +| `deliveryStatus` | string | Delivery status | +| `fee` | number | Delivery fee in cents | +| `tip` | number | Tip amount in cents | +| `orderValue` | number | Order value in cents | +| `currency` | string | Fee currency code | +| `trackingUrl` | string | Delivery tracking URL | +| `supportReference` | string | Support reference ID | +| `dasherName` | string | Assigned Dasher name | +| `dasherId` | number | Assigned Dasher ID | +| `contactlessDropoff` | boolean | Whether contactless dropoff was used | +| `dropoffVerificationImageUrl` | string | Photo verification URL at dropoff | +| `cancellationReason` | string | Reason for cancellation | +| `pickupTimeEstimated` | string | Estimated pickup time | +| `pickupTimeActual` | string | Actual pickup time | +| `dropoffTimeEstimated` | string | Estimated dropoff time | +| `dropoffTimeActual` | string | Actual dropoff time | +| `pickupAddress` | string | Pickup address | +| `dropoffAddress` | string | Dropoff address | +| `updatedAt` | string | Last updated timestamp | + +### `doordash_cancel_delivery` + +Cancels a delivery. Cannot be used after a Dasher has been assigned to the delivery. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | DoorDash Key ID | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalDeliveryId` | string | Yes | External delivery ID to cancel | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalDeliveryId` | string | External delivery ID | +| `deliveryStatus` | string | Delivery status \(cancelled\) | + +### `doordash_create_business` + +Creates a new business entity for organizing delivery locations. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | No description | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalBusinessId` | string | Yes | Unique business identifier | +| `name` | string | Yes | No description | +| `description` | string | No | Business description | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalBusinessId` | string | Business ID | +| `name` | string | Business name | +| `description` | string | Business description | +| `activationStatus` | string | Activation status | + +### `doordash_list_businesses` + +Lists all businesses owned by the developer. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | No description | +| `signingSecret` | string | Yes | DoorDash Signing Secret | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `businesses` | array | List of businesses | +| ↳ `externalBusinessId` | string | Business ID | +| ↳ `name` | string | Business name | +| ↳ `description` | string | Business description | +| ↳ `activationStatus` | string | Activation status | + +### `doordash_update_business` + +Updates a business entity name or description. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | No description | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalBusinessId` | string | Yes | Business ID to update | +| `name` | string | No | Updated business name | +| `description` | string | No | Updated business description | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalBusinessId` | string | Business ID | +| `name` | string | Business name | +| `description` | string | Business description | +| `activationStatus` | string | Activation status | + +### `doordash_create_store` + +Creates a store location under a business for delivery pickup. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | No description | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalBusinessId` | string | Yes | Parent business ID | +| `externalStoreId` | string | Yes | Unique store identifier | +| `name` | string | Yes | No description | +| `phoneNumber` | string | Yes | Store phone number | +| `address` | string | Yes | No description | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalStoreId` | string | Store ID | +| `name` | string | Store name | +| `phoneNumber` | string | Store phone number | +| `address` | string | Store address | + +### `doordash_list_stores` + +Lists all stores under a business. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | No description | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalBusinessId` | string | Yes | Business ID to list stores for | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `stores` | array | List of stores | +| ↳ `externalStoreId` | string | Store ID | +| ↳ `name` | string | Store name | +| ↳ `phoneNumber` | string | Store phone number | +| ↳ `address` | string | Store address | + +### `doordash_get_store` + +Retrieves details of a specific store. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | No description | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalBusinessId` | string | Yes | Parent business ID | +| `externalStoreId` | string | Yes | Store ID to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalStoreId` | string | Store ID | +| `name` | string | Store name | +| `phoneNumber` | string | Store phone number | +| `address` | string | Store address | + +### `doordash_update_store` + +Updates a store location name, phone number, or address. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `developerId` | string | Yes | DoorDash Developer ID | +| `keyId` | string | Yes | No description | +| `signingSecret` | string | Yes | DoorDash Signing Secret | +| `externalBusinessId` | string | Yes | Parent business ID | +| `externalStoreId` | string | Yes | Store ID to update | +| `name` | string | No | Updated store name | +| `phoneNumber` | string | No | Updated phone number | +| `address` | string | No | Updated address | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `externalStoreId` | string | Store ID | +| `name` | string | Store name | +| `phoneNumber` | string | Store phone number | +| `address` | string | Store address | + + diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index a52a54cf0f8..df6e4eaa306 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -29,6 +29,7 @@ "devin", "discord", "docusign", + "doordash", "dropbox", "dspy", "dub", @@ -177,4 +178,4 @@ "zep", "zoom" ] -} +} \ No newline at end of file diff --git a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts index 1d77fc88889..99c95925aa7 100644 --- a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts +++ b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts @@ -33,8 +33,9 @@ import { DatadogIcon, DevinIcon, DiscordIcon, - DocumentIcon, DocuSignIcon, + DocumentIcon, + DoordashIcon, DropboxIcon, DsPyIcon, DubIcon, @@ -50,8 +51,8 @@ import { FirecrawlIcon, FirefliesIcon, GammaIcon, - GithubIcon, GitLabIcon, + GithubIcon, GmailIcon, GongIcon, GoogleAdsIcon, @@ -97,9 +98,9 @@ import { LinkupIcon, LoopsIcon, LumaIcon, + MailServerIcon, MailchimpIcon, MailgunIcon, - MailServerIcon, Mem0Icon, MicrosoftDataverseIcon, MicrosoftExcelIcon, @@ -137,6 +138,8 @@ import { RevenueCatIcon, RipplingIcon, S3Icon, + SQSIcon, + STTIcon, SalesforceIcon, SearchIcon, SendgridIcon, @@ -148,19 +151,17 @@ import { SimilarwebIcon, SlackIcon, SmtpIcon, - SQSIcon, SshIcon, - STTIcon, StagehandIcon, StripeIcon, SupabaseIcon, + TTSIcon, TavilyIcon, TelegramIcon, TextractIcon, TinybirdIcon, TranslateIcon, TrelloIcon, - TTSIcon, TwilioIcon, TypeformIcon, UpstashIcon, @@ -172,11 +173,11 @@ import { WikipediaIcon, WordpressIcon, WorkdayIcon, - xIcon, YouTubeIcon, ZendeskIcon, ZepIcon, ZoomIcon, + xIcon, } from '@/components/icons' type IconComponent = ComponentType> @@ -210,6 +211,7 @@ export const blockTypeToIconMap: Record = { devin: DevinIcon, discord: DiscordIcon, docusign: DocuSignIcon, + doordash: DoordashIcon, dropbox: DropboxIcon, dspy: DsPyIcon, dub: DubIcon, diff --git a/apps/sim/app/(landing)/integrations/data/integrations.json b/apps/sim/app/(landing)/integrations/data/integrations.json index 95d2ef9ea29..6923d557c3b 100644 --- a/apps/sim/app/(landing)/integrations/data/integrations.json +++ b/apps/sim/app/(landing)/integrations/data/integrations.json @@ -52,7 +52,10 @@ "authType": "api-key", "category": "tools", "integrationType": "security", - "tags": ["secrets-management", "identity"] + "tags": [ + "secrets-management", + "identity" + ] }, { "type": "a2a", @@ -103,7 +106,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["agentic", "automation"] + "tags": [ + "agentic", + "automation" + ] }, { "type": "ahrefs", @@ -154,7 +160,11 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["seo", "marketing", "data-analytics"] + "tags": [ + "seo", + "marketing", + "data-analytics" + ] }, { "type": "airtable", @@ -211,7 +221,10 @@ "authType": "oauth", "category": "tools", "integrationType": "databases", - "tags": ["spreadsheet", "automation"] + "tags": [ + "spreadsheet", + "automation" + ] }, { "type": "airweave", @@ -229,7 +242,10 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["vector-search", "knowledge-base"] + "tags": [ + "vector-search", + "knowledge-base" + ] }, { "type": "algolia", @@ -308,7 +324,10 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["vector-search", "knowledge-base"] + "tags": [ + "vector-search", + "knowledge-base" + ] }, { "type": "dynamodb", @@ -355,7 +374,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["cloud", "data-warehouse"] + "tags": [ + "cloud", + "data-warehouse" + ] }, { "type": "rds", @@ -398,7 +420,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["cloud", "data-warehouse"] + "tags": [ + "cloud", + "data-warehouse" + ] }, { "type": "sqs", @@ -421,7 +446,11 @@ "authType": "none", "category": "tools", "integrationType": "developer-tools", - "tags": ["cloud", "messaging", "automation"] + "tags": [ + "cloud", + "messaging", + "automation" + ] }, { "type": "amplitude", @@ -484,7 +513,10 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["data-analytics", "marketing"] + "tags": [ + "data-analytics", + "marketing" + ] }, { "type": "apify", @@ -511,7 +543,11 @@ "authType": "api-key", "category": "tools", "integrationType": "automation", - "tags": ["web-scraping", "automation", "data-analytics"] + "tags": [ + "web-scraping", + "automation", + "data-analytics" + ] }, { "type": "apollo", @@ -630,7 +666,10 @@ "authType": "api-key", "category": "tools", "integrationType": "sales-intelligence", - "tags": ["enrichment", "sales-engagement"] + "tags": [ + "enrichment", + "sales-engagement" + ] }, { "type": "arxiv", @@ -661,7 +700,10 @@ "authType": "none", "category": "tools", "integrationType": "search", - "tags": ["document-processing", "knowledge-base"] + "tags": [ + "document-processing", + "knowledge-base" + ] }, { "type": "asana", @@ -704,7 +746,11 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["project-management", "ticketing", "automation"] + "tags": [ + "project-management", + "ticketing", + "automation" + ] }, { "type": "ashby", @@ -866,7 +912,9 @@ "authType": "api-key", "category": "tools", "integrationType": "hr", - "tags": ["hiring"] + "tags": [ + "hiring" + ] }, { "type": "attio", @@ -1136,7 +1184,10 @@ "authType": "oauth", "category": "tools", "integrationType": "crm", - "tags": ["sales-engagement", "enrichment"] + "tags": [ + "sales-engagement", + "enrichment" + ] }, { "type": "textract_v2", @@ -1154,7 +1205,11 @@ "authType": "none", "category": "tools", "integrationType": "ai", - "tags": ["document-processing", "ocr", "cloud"] + "tags": [ + "document-processing", + "ocr", + "cloud" + ] }, { "type": "microsoft_ad", @@ -1225,7 +1280,10 @@ "authType": "oauth", "category": "tools", "integrationType": "security", - "tags": ["identity", "microsoft-365"] + "tags": [ + "identity", + "microsoft-365" + ] }, { "type": "box", @@ -1304,7 +1362,11 @@ "authType": "oauth", "category": "tools", "integrationType": "file-storage", - "tags": ["cloud", "content-management", "e-signatures"] + "tags": [ + "cloud", + "content-management", + "e-signatures" + ] }, { "type": "brandfetch", @@ -1331,7 +1393,10 @@ "authType": "api-key", "category": "tools", "integrationType": "sales-intelligence", - "tags": ["enrichment", "marketing"] + "tags": [ + "enrichment", + "marketing" + ] }, { "type": "browser_use", @@ -1349,7 +1414,11 @@ "authType": "api-key", "category": "tools", "integrationType": "automation", - "tags": ["web-scraping", "automation", "agentic"] + "tags": [ + "web-scraping", + "automation", + "agentic" + ] }, { "type": "calcom", @@ -1490,7 +1559,11 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["scheduling", "calendar", "meeting"] + "tags": [ + "scheduling", + "calendar", + "meeting" + ] }, { "type": "calendly", @@ -1558,7 +1631,11 @@ "authType": "api-key", "category": "tools", "integrationType": "productivity", - "tags": ["scheduling", "calendar", "meeting"] + "tags": [ + "scheduling", + "calendar", + "meeting" + ] }, { "type": "circleback", @@ -1592,7 +1669,11 @@ "authType": "none", "category": "triggers", "integrationType": "ai", - "tags": ["meeting", "note-taking", "automation"] + "tags": [ + "meeting", + "note-taking", + "automation" + ] }, { "type": "clay", @@ -1610,7 +1691,11 @@ "authType": "none", "category": "tools", "integrationType": "sales-intelligence", - "tags": ["enrichment", "sales-engagement", "data-analytics"] + "tags": [ + "enrichment", + "sales-engagement", + "data-analytics" + ] }, { "type": "clerk", @@ -1673,7 +1758,10 @@ "authType": "none", "category": "tools", "integrationType": "security", - "tags": ["identity", "automation"] + "tags": [ + "identity", + "automation" + ] }, { "type": "cloudflare", @@ -1744,7 +1832,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["cloud", "monitoring"] + "tags": [ + "cloud", + "monitoring" + ] }, { "type": "confluence_v2", @@ -2028,7 +2119,11 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["knowledge-base", "content-management", "note-taking"] + "tags": [ + "knowledge-base", + "content-management", + "note-taking" + ] }, { "type": "cursor_v2", @@ -2075,7 +2170,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["agentic", "automation"] + "tags": [ + "agentic", + "automation" + ] }, { "type": "databricks", @@ -2126,7 +2224,11 @@ "authType": "api-key", "category": "tools", "integrationType": "databases", - "tags": ["data-warehouse", "data-analytics", "cloud"] + "tags": [ + "data-warehouse", + "data-analytics", + "cloud" + ] }, { "type": "datadog", @@ -2193,7 +2295,11 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["monitoring", "incident-management", "error-tracking"] + "tags": [ + "monitoring", + "incident-management", + "error-tracking" + ] }, { "type": "devin", @@ -2228,7 +2334,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["agentic", "automation"] + "tags": [ + "agentic", + "automation" + ] }, { "type": "discord", @@ -2387,7 +2496,11 @@ "authType": "none", "category": "tools", "integrationType": "communication", - "tags": ["messaging", "webhooks", "automation"] + "tags": [ + "messaging", + "webhooks", + "automation" + ] }, { "type": "docusign", @@ -2438,7 +2551,83 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["e-signatures", "document-processing"] + "tags": [ + "e-signatures", + "document-processing" + ] + }, + { + "type": "doordash", + "slug": "doordash", + "name": "DoorDash", + "description": "Create and manage DoorDash Drive deliveries, businesses, and stores", + "longDescription": "Integrate DoorDash Drive into workflows. Create delivery quotes, accept quotes, create deliveries, track status, update details, cancel deliveries, and manage businesses and store locations.", + "bgColor": "#FF3008", + "iconName": "DoordashIcon", + "docsUrl": "https://docs.sim.ai/tools/doordash", + "operations": [ + { + "name": "Create Quote", + "description": "Creates a delivery quote to validate coverage, pricing, and estimated delivery times." + }, + { + "name": "Accept Quote", + "description": "Accepts a delivery quote to formally create the delivery. Must be called within 5 minutes of creating the quote." + }, + { + "name": "Create Delivery", + "description": "Creates a delivery directly without a prior quote. Skips price confirmation." + }, + { + "name": "Get Delivery", + "description": "Retrieves the current status and details of a delivery." + }, + { + "name": "Update Delivery", + "description": "Updates a delivery. Only tip and dropoff details can be modified after creation." + }, + { + "name": "Cancel Delivery", + "description": "Cancels a delivery. Cannot be used after a Dasher has been assigned to the delivery." + }, + { + "name": "Create Business", + "description": "Creates a new business entity for organizing delivery locations." + }, + { + "name": "List Businesses", + "description": "Lists all businesses owned by the developer." + }, + { + "name": "Update Business", + "description": "Updates a business entity name or description." + }, + { + "name": "Create Store", + "description": "Creates a store location under a business for delivery pickup." + }, + { + "name": "List Stores", + "description": "Lists all stores under a business." + }, + { + "name": "Get Store", + "description": "Retrieves details of a specific store." + }, + { + "name": "Update Store", + "description": "Updates a store location name, phone number, or address." + } + ], + "operationCount": 13, + "triggers": [], + "triggerCount": 0, + "authType": "none", + "category": "tools", + "integrationType": "ecommerce", + "tags": [ + "automation" + ] }, { "type": "dropbox", @@ -2497,7 +2686,10 @@ "authType": "oauth", "category": "tools", "integrationType": "file-storage", - "tags": ["cloud", "document-processing"] + "tags": [ + "cloud", + "document-processing" + ] }, { "type": "dspy", @@ -2528,7 +2720,11 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["llm", "agentic", "automation"] + "tags": [ + "llm", + "agentic", + "automation" + ] }, { "type": "dub", @@ -2575,7 +2771,11 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["link-management", "marketing", "data-analytics"] + "tags": [ + "link-management", + "marketing", + "data-analytics" + ] }, { "type": "duckduckgo", @@ -2593,7 +2793,10 @@ "authType": "none", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "seo"] + "tags": [ + "web-scraping", + "seo" + ] }, { "type": "elasticsearch", @@ -2664,7 +2867,10 @@ "authType": "api-key", "category": "tools", "integrationType": "databases", - "tags": ["vector-search", "data-analytics"] + "tags": [ + "vector-search", + "data-analytics" + ] }, { "type": "elevenlabs", @@ -2682,7 +2888,9 @@ "authType": "api-key", "category": "tools", "integrationType": "media", - "tags": ["text-to-speech"] + "tags": [ + "text-to-speech" + ] }, { "type": "openai", @@ -2700,7 +2908,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["llm", "vector-search"] + "tags": [ + "llm", + "vector-search" + ] }, { "type": "enrich", @@ -2835,7 +3046,10 @@ "authType": "api-key", "category": "tools", "integrationType": "sales-intelligence", - "tags": ["enrichment", "data-analytics"] + "tags": [ + "enrichment", + "data-analytics" + ] }, { "type": "evernote", @@ -2898,7 +3112,10 @@ "authType": "api-key", "category": "tools", "integrationType": "documents", - "tags": ["note-taking", "knowledge-base"] + "tags": [ + "note-taking", + "knowledge-base" + ] }, { "type": "exa", @@ -2937,7 +3154,10 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "enrichment"] + "tags": [ + "web-scraping", + "enrichment" + ] }, { "type": "fathom", @@ -2987,7 +3207,10 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["meeting", "note-taking"] + "tags": [ + "meeting", + "note-taking" + ] }, { "type": "file_v3", @@ -3005,7 +3228,9 @@ "authType": "none", "category": "tools", "integrationType": "file-storage", - "tags": ["document-processing"] + "tags": [ + "document-processing" + ] }, { "type": "firecrawl", @@ -3048,7 +3273,10 @@ "authType": "api-key", "category": "tools", "integrationType": "automation", - "tags": ["web-scraping", "automation"] + "tags": [ + "web-scraping", + "automation" + ] }, { "type": "fireflies_v2", @@ -3113,7 +3341,11 @@ "authType": "api-key", "category": "tools", "integrationType": "media", - "tags": ["meeting", "speech-to-text", "note-taking"] + "tags": [ + "meeting", + "speech-to-text", + "note-taking" + ] }, { "type": "gamma", @@ -3152,7 +3384,10 @@ "authType": "api-key", "category": "tools", "integrationType": "design", - "tags": ["document-processing", "content-management"] + "tags": [ + "document-processing", + "content-management" + ] }, { "type": "github_v2", @@ -3559,7 +3794,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["version-control", "ci-cd"] + "tags": [ + "version-control", + "ci-cd" + ] }, { "type": "gitlab", @@ -3654,7 +3892,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["version-control", "ci-cd"] + "tags": [ + "version-control", + "ci-cd" + ] }, { "type": "gmail_v2", @@ -3721,7 +3962,10 @@ "authType": "oauth", "category": "tools", "integrationType": "email", - "tags": ["google-workspace", "messaging"] + "tags": [ + "google-workspace", + "messaging" + ] }, { "type": "gong", @@ -3812,7 +4056,11 @@ "authType": "none", "category": "tools", "integrationType": "sales-intelligence", - "tags": ["meeting", "sales-engagement", "speech-to-text"] + "tags": [ + "meeting", + "sales-engagement", + "speech-to-text" + ] }, { "type": "google_ads", @@ -3855,7 +4103,11 @@ "authType": "oauth", "category": "tools", "integrationType": "analytics", - "tags": ["marketing", "google-workspace", "data-analytics"] + "tags": [ + "marketing", + "google-workspace", + "data-analytics" + ] }, { "type": "google_bigquery", @@ -3894,7 +4146,11 @@ "authType": "oauth", "category": "tools", "integrationType": "databases", - "tags": ["data-warehouse", "google-workspace", "data-analytics"] + "tags": [ + "data-warehouse", + "google-workspace", + "data-analytics" + ] }, { "type": "google_books", @@ -3921,7 +4177,11 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["google-workspace", "knowledge-base", "content-management"] + "tags": [ + "google-workspace", + "knowledge-base", + "content-management" + ] }, { "type": "google_calendar_v2", @@ -3980,7 +4240,11 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["calendar", "scheduling", "google-workspace"] + "tags": [ + "calendar", + "scheduling", + "google-workspace" + ] }, { "type": "google_contacts", @@ -4023,7 +4287,11 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["google-workspace", "customer-support", "enrichment"] + "tags": [ + "google-workspace", + "customer-support", + "enrichment" + ] }, { "type": "google_docs", @@ -4054,7 +4322,11 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["google-workspace", "document-processing", "content-management"] + "tags": [ + "google-workspace", + "document-processing", + "content-management" + ] }, { "type": "google_drive", @@ -4129,7 +4401,11 @@ "authType": "oauth", "category": "tools", "integrationType": "file-storage", - "tags": ["cloud", "google-workspace", "document-processing"] + "tags": [ + "cloud", + "google-workspace", + "document-processing" + ] }, { "type": "google_forms", @@ -4190,7 +4466,11 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["google-workspace", "forms", "data-analytics"] + "tags": [ + "google-workspace", + "forms", + "data-analytics" + ] }, { "type": "google_groups", @@ -4273,7 +4553,11 @@ "authType": "oauth", "category": "tools", "integrationType": "communication", - "tags": ["google-workspace", "messaging", "identity"] + "tags": [ + "google-workspace", + "messaging", + "identity" + ] }, { "type": "google_maps", @@ -4344,7 +4628,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["google-workspace", "enrichment"] + "tags": [ + "google-workspace", + "enrichment" + ] }, { "type": "google_meet", @@ -4387,7 +4674,11 @@ "authType": "oauth", "category": "tools", "integrationType": "communication", - "tags": ["meeting", "google-workspace", "scheduling"] + "tags": [ + "meeting", + "google-workspace", + "scheduling" + ] }, { "type": "google_pagespeed", @@ -4405,7 +4696,11 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["google-workspace", "seo", "monitoring"] + "tags": [ + "google-workspace", + "seo", + "monitoring" + ] }, { "type": "google_search", @@ -4423,7 +4718,11 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["google-workspace", "web-scraping", "seo"] + "tags": [ + "google-workspace", + "web-scraping", + "seo" + ] }, { "type": "google_sheets_v2", @@ -4486,7 +4785,11 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["spreadsheet", "google-workspace", "data-analytics"] + "tags": [ + "spreadsheet", + "google-workspace", + "data-analytics" + ] }, { "type": "google_slides_v2", @@ -4561,7 +4864,11 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["google-workspace", "document-processing", "content-management"] + "tags": [ + "google-workspace", + "document-processing", + "content-management" + ] }, { "type": "google_tasks", @@ -4604,7 +4911,11 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["google-workspace", "project-management", "scheduling"] + "tags": [ + "google-workspace", + "project-management", + "scheduling" + ] }, { "type": "google_translate", @@ -4631,7 +4942,11 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["google-workspace", "content-management", "automation"] + "tags": [ + "google-workspace", + "content-management", + "automation" + ] }, { "type": "google_vault", @@ -4678,7 +4993,11 @@ "authType": "oauth", "category": "tools", "integrationType": "security", - "tags": ["google-workspace", "secrets-management", "document-processing"] + "tags": [ + "google-workspace", + "secrets-management", + "document-processing" + ] }, { "type": "grafana", @@ -4773,7 +5092,10 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["monitoring", "data-analytics"] + "tags": [ + "monitoring", + "data-analytics" + ] }, { "type": "grain", @@ -4869,7 +5191,10 @@ "authType": "api-key", "category": "tools", "integrationType": "media", - "tags": ["meeting", "note-taking"] + "tags": [ + "meeting", + "note-taking" + ] }, { "type": "granola", @@ -4896,7 +5221,10 @@ "authType": "api-key", "category": "tools", "integrationType": "productivity", - "tags": ["meeting", "note-taking"] + "tags": [ + "meeting", + "note-taking" + ] }, { "type": "greenhouse", @@ -4959,7 +5287,9 @@ "authType": "api-key", "category": "tools", "integrationType": "hr", - "tags": ["hiring"] + "tags": [ + "hiring" + ] }, { "type": "greptile", @@ -4994,7 +5324,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["version-control", "knowledge-base"] + "tags": [ + "version-control", + "knowledge-base" + ] }, { "type": "hex", @@ -5077,7 +5410,10 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["data-warehouse", "data-analytics"] + "tags": [ + "data-warehouse", + "data-analytics" + ] }, { "type": "hubspot", @@ -5303,7 +5639,11 @@ "authType": "oauth", "category": "tools", "integrationType": "crm", - "tags": ["marketing", "sales-engagement", "customer-support"] + "tags": [ + "marketing", + "sales-engagement", + "customer-support" + ] }, { "type": "huggingface", @@ -5321,7 +5661,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["llm", "agentic"] + "tags": [ + "llm", + "agentic" + ] }, { "type": "hunter", @@ -5364,7 +5707,10 @@ "authType": "api-key", "category": "tools", "integrationType": "sales-intelligence", - "tags": ["enrichment", "sales-engagement"] + "tags": [ + "enrichment", + "sales-engagement" + ] }, { "type": "image_generator", @@ -5382,7 +5728,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["image-generation", "llm"] + "tags": [ + "image-generation", + "llm" + ] }, { "type": "imap", @@ -5406,7 +5755,10 @@ "authType": "none", "category": "triggers", "integrationType": "email", - "tags": ["messaging", "automation"] + "tags": [ + "messaging", + "automation" + ] }, { "type": "incidentio", @@ -5601,7 +5953,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["incident-management", "monitoring"] + "tags": [ + "incident-management", + "monitoring" + ] }, { "type": "infisical", @@ -5640,7 +5995,9 @@ "authType": "api-key", "category": "tools", "integrationType": "security", - "tags": ["secrets-management"] + "tags": [ + "secrets-management" + ] }, { "type": "intercom_v2", @@ -5783,7 +6140,10 @@ "authType": "api-key", "category": "tools", "integrationType": "customer-support", - "tags": ["customer-support", "messaging"] + "tags": [ + "customer-support", + "messaging" + ] }, { "type": "jina", @@ -5810,7 +6170,10 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "knowledge-base"] + "tags": [ + "web-scraping", + "knowledge-base" + ] }, { "type": "jira", @@ -5956,7 +6319,10 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["project-management", "ticketing"] + "tags": [ + "project-management", + "ticketing" + ] }, { "type": "jira_service_management", @@ -6059,7 +6425,11 @@ "authType": "oauth", "category": "tools", "integrationType": "customer-support", - "tags": ["customer-support", "ticketing", "incident-management"] + "tags": [ + "customer-support", + "ticketing", + "incident-management" + ] }, { "type": "kalshi_v2", @@ -6146,7 +6516,10 @@ "authType": "none", "category": "tools", "integrationType": "analytics", - "tags": ["prediction-markets", "data-analytics"] + "tags": [ + "prediction-markets", + "data-analytics" + ] }, { "type": "ketch", @@ -6185,7 +6558,9 @@ "authType": "none", "category": "tools", "integrationType": "security", - "tags": ["identity"] + "tags": [ + "identity" + ] }, { "type": "knowledge", @@ -6285,7 +6660,11 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["monitoring", "llm", "data-analytics"] + "tags": [ + "monitoring", + "llm", + "data-analytics" + ] }, { "type": "lemlist", @@ -6362,7 +6741,11 @@ "authType": "api-key", "category": "tools", "integrationType": "email", - "tags": ["sales-engagement", "email-marketing", "automation"] + "tags": [ + "sales-engagement", + "email-marketing", + "automation" + ] }, { "type": "linear", @@ -6769,7 +7152,10 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["project-management", "ticketing"] + "tags": [ + "project-management", + "ticketing" + ] }, { "type": "linkedin", @@ -6796,7 +7182,11 @@ "authType": "oauth", "category": "tools", "integrationType": "social", - "tags": ["marketing", "sales-engagement", "enrichment"] + "tags": [ + "marketing", + "sales-engagement", + "enrichment" + ] }, { "type": "linkup", @@ -6814,7 +7204,10 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "enrichment"] + "tags": [ + "web-scraping", + "enrichment" + ] }, { "type": "loops", @@ -6873,7 +7266,11 @@ "authType": "api-key", "category": "tools", "integrationType": "email", - "tags": ["email-marketing", "marketing", "automation"] + "tags": [ + "email-marketing", + "marketing", + "automation" + ] }, { "type": "luma", @@ -6916,7 +7313,11 @@ "authType": "api-key", "category": "tools", "integrationType": "productivity", - "tags": ["events", "calendar", "scheduling"] + "tags": [ + "events", + "calendar", + "scheduling" + ] }, { "type": "mailchimp", @@ -7227,7 +7628,11 @@ "authType": "api-key", "category": "tools", "integrationType": "email", - "tags": ["email-marketing", "marketing", "automation"] + "tags": [ + "email-marketing", + "marketing", + "automation" + ] }, { "type": "mailgun", @@ -7278,7 +7683,10 @@ "authType": "api-key", "category": "tools", "integrationType": "email", - "tags": ["messaging", "email-marketing"] + "tags": [ + "messaging", + "email-marketing" + ] }, { "type": "mem0", @@ -7309,7 +7717,11 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["llm", "knowledge-base", "agentic"] + "tags": [ + "llm", + "knowledge-base", + "agentic" + ] }, { "type": "memory", @@ -7429,7 +7841,11 @@ "authType": "oauth", "category": "tools", "integrationType": "databases", - "tags": ["microsoft-365", "data-warehouse", "cloud"] + "tags": [ + "microsoft-365", + "data-warehouse", + "cloud" + ] }, { "type": "microsoft_excel_v2", @@ -7456,7 +7872,10 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["spreadsheet", "microsoft-365"] + "tags": [ + "spreadsheet", + "microsoft-365" + ] }, { "type": "microsoft_planner", @@ -7527,7 +7946,11 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["project-management", "microsoft-365", "ticketing"] + "tags": [ + "project-management", + "microsoft-365", + "ticketing" + ] }, { "type": "microsoft_teams", @@ -7608,7 +8031,10 @@ "authType": "oauth", "category": "tools", "integrationType": "communication", - "tags": ["messaging", "microsoft-365"] + "tags": [ + "messaging", + "microsoft-365" + ] }, { "type": "mistral_parse_v3", @@ -7626,7 +8052,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["document-processing", "ocr"] + "tags": [ + "document-processing", + "ocr" + ] }, { "type": "mongodb", @@ -7669,7 +8098,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["data-warehouse", "cloud"] + "tags": [ + "data-warehouse", + "cloud" + ] }, { "type": "mysql", @@ -7712,7 +8144,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["data-warehouse", "data-analytics"] + "tags": [ + "data-warehouse", + "data-analytics" + ] }, { "type": "neo4j", @@ -7759,7 +8194,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["data-warehouse", "data-analytics"] + "tags": [ + "data-warehouse", + "data-analytics" + ] }, { "type": "notion_v2", @@ -7777,7 +8215,11 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["note-taking", "knowledge-base", "content-management"] + "tags": [ + "note-taking", + "knowledge-base", + "content-management" + ] }, { "type": "obsidian", @@ -7856,7 +8298,10 @@ "authType": "api-key", "category": "tools", "integrationType": "documents", - "tags": ["note-taking", "knowledge-base"] + "tags": [ + "note-taking", + "knowledge-base" + ] }, { "type": "okta", @@ -7947,7 +8392,10 @@ "authType": "api-key", "category": "tools", "integrationType": "security", - "tags": ["identity", "automation"] + "tags": [ + "identity", + "automation" + ] }, { "type": "onedrive", @@ -7990,7 +8438,11 @@ "authType": "oauth", "category": "tools", "integrationType": "file-storage", - "tags": ["microsoft-365", "cloud", "document-processing"] + "tags": [ + "microsoft-365", + "cloud", + "document-processing" + ] }, { "type": "outlook", @@ -8045,7 +8497,11 @@ "authType": "oauth", "category": "tools", "integrationType": "email", - "tags": ["microsoft-365", "messaging", "automation"] + "tags": [ + "microsoft-365", + "messaging", + "automation" + ] }, { "type": "pagerduty", @@ -8088,7 +8544,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["incident-management", "monitoring"] + "tags": [ + "incident-management", + "monitoring" + ] }, { "type": "parallel_ai", @@ -8119,7 +8578,11 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "llm", "agentic"] + "tags": [ + "web-scraping", + "llm", + "agentic" + ] }, { "type": "perplexity", @@ -8146,7 +8609,11 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["llm", "web-scraping", "agentic"] + "tags": [ + "llm", + "web-scraping", + "agentic" + ] }, { "type": "pinecone", @@ -8185,7 +8652,10 @@ "authType": "api-key", "category": "tools", "integrationType": "databases", - "tags": ["vector-search", "knowledge-base"] + "tags": [ + "vector-search", + "knowledge-base" + ] }, { "type": "pipedrive", @@ -8276,7 +8746,10 @@ "authType": "oauth", "category": "tools", "integrationType": "crm", - "tags": ["sales-engagement", "project-management"] + "tags": [ + "sales-engagement", + "project-management" + ] }, { "type": "polymarket", @@ -8375,7 +8848,10 @@ "authType": "none", "category": "tools", "integrationType": "analytics", - "tags": ["prediction-markets", "data-analytics"] + "tags": [ + "prediction-markets", + "data-analytics" + ] }, { "type": "postgresql", @@ -8418,7 +8894,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["data-warehouse", "data-analytics"] + "tags": [ + "data-warehouse", + "data-analytics" + ] }, { "type": "posthog", @@ -8609,7 +9088,10 @@ "authType": "none", "category": "tools", "integrationType": "analytics", - "tags": ["data-analytics", "monitoring"] + "tags": [ + "data-analytics", + "monitoring" + ] }, { "type": "pulse_v2", @@ -8627,7 +9109,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["document-processing", "ocr"] + "tags": [ + "document-processing", + "ocr" + ] }, { "type": "qdrant", @@ -8658,7 +9143,10 @@ "authType": "api-key", "category": "tools", "integrationType": "databases", - "tags": ["vector-search", "knowledge-base"] + "tags": [ + "vector-search", + "knowledge-base" + ] }, { "type": "quiver", @@ -8689,7 +9177,9 @@ "authType": "api-key", "category": "tools", "integrationType": "design", - "tags": ["image-generation"] + "tags": [ + "image-generation" + ] }, { "type": "reddit", @@ -8776,7 +9266,10 @@ "authType": "oauth", "category": "tools", "integrationType": "social", - "tags": ["content-management", "web-scraping"] + "tags": [ + "content-management", + "web-scraping" + ] }, { "type": "redis", @@ -8883,7 +9376,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["cloud", "data-warehouse"] + "tags": [ + "cloud", + "data-warehouse" + ] }, { "type": "reducto_v2", @@ -8901,7 +9397,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["document-processing", "ocr"] + "tags": [ + "document-processing", + "ocr" + ] }, { "type": "resend", @@ -8952,7 +9451,10 @@ "authType": "none", "category": "tools", "integrationType": "email", - "tags": ["email-marketing", "messaging"] + "tags": [ + "email-marketing", + "messaging" + ] }, { "type": "revenuecat", @@ -9011,7 +9513,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ecommerce", - "tags": ["payments", "subscriptions"] + "tags": [ + "payments", + "subscriptions" + ] }, { "type": "rippling", @@ -9106,7 +9611,9 @@ "authType": "api-key", "category": "tools", "integrationType": "hr", - "tags": ["hiring"] + "tags": [ + "hiring" + ] }, { "type": "s3", @@ -9145,7 +9652,10 @@ "authType": "none", "category": "tools", "integrationType": "file-storage", - "tags": ["cloud", "data-warehouse"] + "tags": [ + "cloud", + "data-warehouse" + ] }, { "type": "salesforce", @@ -9304,7 +9814,10 @@ "authType": "oauth", "category": "tools", "integrationType": "crm", - "tags": ["sales-engagement", "customer-support"] + "tags": [ + "sales-engagement", + "customer-support" + ] }, { "type": "search", @@ -9322,7 +9835,10 @@ "authType": "none", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "seo"] + "tags": [ + "web-scraping", + "seo" + ] }, { "type": "sendgrid", @@ -9405,7 +9921,10 @@ "authType": "api-key", "category": "tools", "integrationType": "email", - "tags": ["email-marketing", "messaging"] + "tags": [ + "email-marketing", + "messaging" + ] }, { "type": "sentry", @@ -9472,7 +9991,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["error-tracking", "monitoring"] + "tags": [ + "error-tracking", + "monitoring" + ] }, { "type": "serper", @@ -9490,7 +10012,10 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "seo"] + "tags": [ + "web-scraping", + "seo" + ] }, { "type": "servicenow", @@ -9525,7 +10050,11 @@ "authType": "none", "category": "tools", "integrationType": "customer-support", - "tags": ["customer-support", "ticketing", "incident-management"] + "tags": [ + "customer-support", + "ticketing", + "incident-management" + ] }, { "type": "sftp", @@ -9568,7 +10097,10 @@ "authType": "none", "category": "tools", "integrationType": "file-storage", - "tags": ["cloud", "automation"] + "tags": [ + "cloud", + "automation" + ] }, { "type": "sharepoint", @@ -9619,7 +10151,11 @@ "authType": "oauth", "category": "tools", "integrationType": "documents", - "tags": ["microsoft-365", "content-management", "document-processing"] + "tags": [ + "microsoft-365", + "content-management", + "document-processing" + ] }, { "type": "shopify", @@ -9722,7 +10258,10 @@ "authType": "oauth", "category": "tools", "integrationType": "ecommerce", - "tags": ["payments", "subscriptions"] + "tags": [ + "payments", + "subscriptions" + ] }, { "type": "similarweb", @@ -9761,7 +10300,11 @@ "authType": "api-key", "category": "tools", "integrationType": "analytics", - "tags": ["marketing", "data-analytics", "seo"] + "tags": [ + "marketing", + "data-analytics", + "seo" + ] }, { "type": "slack", @@ -9886,7 +10429,11 @@ "authType": "oauth", "category": "tools", "integrationType": "communication", - "tags": ["messaging", "webhooks", "automation"] + "tags": [ + "messaging", + "webhooks", + "automation" + ] }, { "type": "smtp", @@ -9904,7 +10451,10 @@ "authType": "none", "category": "tools", "integrationType": "email", - "tags": ["email-marketing", "messaging"] + "tags": [ + "email-marketing", + "messaging" + ] }, { "type": "stt_v2", @@ -9922,7 +10472,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["speech-to-text", "document-processing"] + "tags": [ + "speech-to-text", + "document-processing" + ] }, { "type": "ssh", @@ -9993,7 +10546,10 @@ "authType": "none", "category": "tools", "integrationType": "developer-tools", - "tags": ["cloud", "automation"] + "tags": [ + "cloud", + "automation" + ] }, { "type": "stagehand", @@ -10020,7 +10576,11 @@ "authType": "api-key", "category": "tools", "integrationType": "automation", - "tags": ["web-scraping", "automation", "agentic"] + "tags": [ + "web-scraping", + "automation", + "agentic" + ] }, { "type": "stripe", @@ -10245,7 +10805,11 @@ "authType": "api-key", "category": "tools", "integrationType": "ecommerce", - "tags": ["payments", "subscriptions", "webhooks"] + "tags": [ + "payments", + "subscriptions", + "webhooks" + ] }, { "type": "supabase", @@ -10352,7 +10916,11 @@ "authType": "api-key", "category": "tools", "integrationType": "databases", - "tags": ["cloud", "data-warehouse", "vector-search"] + "tags": [ + "cloud", + "data-warehouse", + "vector-search" + ] }, { "type": "tavily", @@ -10387,7 +10955,10 @@ "authType": "api-key", "category": "tools", "integrationType": "search", - "tags": ["web-scraping", "enrichment"] + "tags": [ + "web-scraping", + "enrichment" + ] }, { "type": "telegram", @@ -10440,7 +11011,11 @@ "authType": "none", "category": "tools", "integrationType": "communication", - "tags": ["messaging", "webhooks", "automation"] + "tags": [ + "messaging", + "webhooks", + "automation" + ] }, { "type": "tts", @@ -10458,7 +11033,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["text-to-speech", "llm"] + "tags": [ + "text-to-speech", + "llm" + ] }, { "type": "tinybird", @@ -10485,7 +11063,10 @@ "authType": "none", "category": "tools", "integrationType": "analytics", - "tags": ["data-warehouse", "data-analytics"] + "tags": [ + "data-warehouse", + "data-analytics" + ] }, { "type": "translate", @@ -10503,7 +11084,10 @@ "authType": "none", "category": "tools", "integrationType": "ai", - "tags": ["document-processing", "llm"] + "tags": [ + "document-processing", + "llm" + ] }, { "type": "trello", @@ -10546,7 +11130,10 @@ "authType": "oauth", "category": "tools", "integrationType": "productivity", - "tags": ["project-management", "ticketing"] + "tags": [ + "project-management", + "ticketing" + ] }, { "type": "twilio_sms", @@ -10564,7 +11151,10 @@ "authType": "none", "category": "tools", "integrationType": "communication", - "tags": ["messaging", "automation"] + "tags": [ + "messaging", + "automation" + ] }, { "type": "twilio_voice", @@ -10601,7 +11191,10 @@ "authType": "none", "category": "tools", "integrationType": "communication", - "tags": ["messaging", "text-to-speech"] + "tags": [ + "messaging", + "text-to-speech" + ] }, { "type": "typeform", @@ -10658,7 +11251,10 @@ "authType": "api-key", "category": "tools", "integrationType": "documents", - "tags": ["forms", "data-analytics"] + "tags": [ + "forms", + "data-analytics" + ] }, { "type": "upstash", @@ -10741,7 +11337,10 @@ "authType": "none", "category": "tools", "integrationType": "databases", - "tags": ["cloud", "data-warehouse"] + "tags": [ + "cloud", + "data-warehouse" + ] }, { "type": "vercel", @@ -10960,7 +11559,10 @@ "authType": "api-key", "category": "tools", "integrationType": "developer-tools", - "tags": ["cloud", "ci-cd"] + "tags": [ + "cloud", + "ci-cd" + ] }, { "type": "video_generator_v2", @@ -10978,7 +11580,10 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["video-generation", "llm"] + "tags": [ + "video-generation", + "llm" + ] }, { "type": "vision_v2", @@ -10996,7 +11601,11 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["llm", "document-processing", "ocr"] + "tags": [ + "llm", + "document-processing", + "ocr" + ] }, { "type": "wealthbox", @@ -11039,7 +11648,10 @@ "authType": "oauth", "category": "tools", "integrationType": "crm", - "tags": ["sales-engagement", "customer-support"] + "tags": [ + "sales-engagement", + "customer-support" + ] }, { "type": "webflow", @@ -11099,7 +11711,10 @@ "authType": "oauth", "category": "tools", "integrationType": "design", - "tags": ["content-management", "seo"] + "tags": [ + "content-management", + "seo" + ] }, { "type": "whatsapp", @@ -11123,7 +11738,10 @@ "authType": "api-key", "category": "tools", "integrationType": "communication", - "tags": ["messaging", "automation"] + "tags": [ + "messaging", + "automation" + ] }, { "type": "wikipedia", @@ -11158,7 +11776,10 @@ "authType": "none", "category": "tools", "integrationType": "search", - "tags": ["knowledge-base", "web-scraping"] + "tags": [ + "knowledge-base", + "web-scraping" + ] }, { "type": "wordpress", @@ -11281,7 +11902,10 @@ "authType": "oauth", "category": "tools", "integrationType": "design", - "tags": ["content-management", "seo"] + "tags": [ + "content-management", + "seo" + ] }, { "type": "workday", @@ -11340,7 +11964,10 @@ "authType": "none", "category": "tools", "integrationType": "hr", - "tags": ["hiring", "project-management"] + "tags": [ + "hiring", + "project-management" + ] }, { "type": "x", @@ -11471,7 +12098,10 @@ "authType": "oauth", "category": "tools", "integrationType": "social", - "tags": ["marketing", "messaging"] + "tags": [ + "marketing", + "messaging" + ] }, { "type": "youtube", @@ -11526,7 +12156,11 @@ "authType": "api-key", "category": "tools", "integrationType": "media", - "tags": ["google-workspace", "marketing", "content-management"] + "tags": [ + "google-workspace", + "marketing", + "content-management" + ] }, { "type": "zendesk", @@ -11649,7 +12283,10 @@ "authType": "none", "category": "tools", "integrationType": "customer-support", - "tags": ["customer-support", "ticketing"] + "tags": [ + "customer-support", + "ticketing" + ] }, { "type": "zep", @@ -11704,7 +12341,11 @@ "authType": "api-key", "category": "tools", "integrationType": "ai", - "tags": ["llm", "knowledge-base", "agentic"] + "tags": [ + "llm", + "knowledge-base", + "agentic" + ] }, { "type": "zoom", @@ -11763,6 +12404,10 @@ "authType": "oauth", "category": "tools", "integrationType": "communication", - "tags": ["meeting", "calendar", "scheduling"] + "tags": [ + "meeting", + "calendar", + "scheduling" + ] } -] +] \ No newline at end of file diff --git a/apps/sim/app/api/tools/doordash/route.ts b/apps/sim/app/api/tools/doordash/route.ts new file mode 100644 index 00000000000..9a9e728d015 --- /dev/null +++ b/apps/sim/app/api/tools/doordash/route.ts @@ -0,0 +1,409 @@ +import { createLogger } from '@sim/logger' +import { SignJWT } from 'jose' +import { NextResponse, type NextRequest } from 'next/server' +import { z } from 'zod' +import { checkInternalAuth } from '@/lib/auth/hybrid' + +const logger = createLogger('DoordashAPI') + +const DOORDASH_BASE_URL = 'https://openapi.doordash.com' +const DRIVE_V2 = `${DOORDASH_BASE_URL}/drive/v2` +const DEVELOPER_V1 = `${DOORDASH_BASE_URL}/developer/v1` + +const RequestSchema = z.object({ + operation: z.enum([ + 'create_quote', + 'accept_quote', + 'create_delivery', + 'get_delivery', + 'update_delivery', + 'cancel_delivery', + 'create_business', + 'list_businesses', + 'update_business', + 'create_store', + 'list_stores', + 'get_store', + 'update_store', + ]), + developerId: z.string(), + keyId: z.string(), + signingSecret: z.string(), + externalDeliveryId: z.string().optional(), + pickupAddress: z.string().optional(), + pickupPhoneNumber: z.string().optional(), + pickupBusinessName: z.string().optional(), + dropoffAddress: z.string().optional(), + dropoffPhoneNumber: z.string().optional(), + dropoffBusinessName: z.string().optional(), + orderValue: z.string().optional(), + pickupInstructions: z.string().optional(), + dropoffInstructions: z.string().optional(), + tip: z.string().optional(), + dropoffContactSendNotifications: z.string().optional(), + actionIfUndeliverable: z.string().optional(), + contactlessDropoff: z.string().optional(), + dropoffRequiresSignature: z.string().optional(), + dropoffContactGivenName: z.string().optional(), + dropoffContactFamilyName: z.string().optional(), + pickupTime: z.string().optional(), + dropoffTime: z.string().optional(), + externalBusinessId: z.string().optional(), + externalStoreId: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), + phoneNumber: z.string().optional(), + address: z.string().optional(), +}) + +/** + * Generates a DoorDash JWT for API authentication. + */ +async function generateJwt( + developerId: string, + keyId: string, + signingSecret: string +): Promise { + const decodedSecret = Buffer.from(signingSecret.replace(/-/g, '+').replace(/_/g, '/'), 'base64') + + const now = Math.floor(Date.now() / 1000) + + const jwt = await new SignJWT({}) + .setProtectedHeader({ alg: 'HS256', typ: 'JWT', kid: keyId, 'dd-ver': 'DD-JWT-V1' }) + .setIssuedAt(now) + .setIssuer(developerId) + .setAudience('doordash') + .setExpirationTime(now + 300) + .sign(decodedSecret) + + return jwt +} + +/** + * Extracts delivery output fields from a DoorDash API response. + */ +function extractDeliveryOutput(data: Record) { + return { + externalDeliveryId: (data.external_delivery_id as string) ?? '', + deliveryStatus: (data.delivery_status as string) ?? '', + fee: (data.fee as number) ?? null, + tip: (data.tip as number) ?? null, + orderValue: (data.order_value as number) ?? null, + currency: (data.currency as string) ?? null, + trackingUrl: (data.tracking_url as string) ?? null, + supportReference: (data.support_reference as string) ?? null, + dasherName: (data.dasher_name as string) ?? null, + dasherId: (data.dasher_id as number) ?? null, + contactlessDropoff: (data.contactless_dropoff as boolean) ?? null, + dropoffVerificationImageUrl: (data.dropoff_verification_image_url as string) ?? null, + cancellationReason: (data.cancellation_reason as string) ?? null, + pickupTimeEstimated: (data.pickup_time_estimated as string) ?? null, + pickupTimeActual: (data.pickup_time_actual as string) ?? null, + dropoffTimeEstimated: (data.dropoff_time_estimated as string) ?? null, + dropoffTimeActual: (data.dropoff_time_actual as string) ?? null, + pickupAddress: (data.pickup_address as string) ?? null, + dropoffAddress: (data.dropoff_address as string) ?? null, + updatedAt: (data.updated_at as string) ?? null, + } +} + +/** + * Extracts business output fields from a DoorDash API response. + */ +function extractBusinessOutput(data: Record) { + return { + externalBusinessId: (data.external_business_id as string) ?? '', + name: (data.name as string) ?? '', + description: (data.description as string) ?? null, + activationStatus: (data.activation_status as string) ?? null, + } +} + +/** + * Extracts store output fields from a DoorDash API response. + */ +function extractStoreOutput(data: Record) { + return { + externalStoreId: (data.external_store_id as string) ?? '', + name: (data.name as string) ?? '', + phoneNumber: (data.phone_number as string) ?? null, + address: (data.address as string) ?? null, + } +} + +export async function POST(request: NextRequest) { + const authResult = await checkInternalAuth(request, { requireWorkflowId: false }) + if (!authResult.success) { + return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 }) + } + + let body: z.infer + try { + const raw = await request.json() + body = RequestSchema.parse(raw) + } catch (error) { + logger.error('Invalid request body', { error }) + return NextResponse.json({ success: false, error: 'Invalid request body' }, { status: 400 }) + } + + let jwt: string + try { + jwt = await generateJwt(body.developerId, body.keyId, body.signingSecret) + } catch (error) { + logger.error('Failed to generate JWT', { error }) + return NextResponse.json( + { success: false, error: 'Failed to generate DoorDash JWT. Check your credentials.' }, + { status: 400 } + ) + } + + const headers: Record = { + Authorization: `Bearer ${jwt}`, + 'Content-Type': 'application/json', + } + + try { + let url: string + let method: string + let requestBody: Record | undefined + + switch (body.operation) { + case 'create_quote': { + url = `${DRIVE_V2}/quotes` + method = 'POST' + requestBody = { + external_delivery_id: body.externalDeliveryId?.trim(), + pickup_address: body.pickupAddress, + pickup_phone_number: body.pickupPhoneNumber, + pickup_business_name: body.pickupBusinessName, + dropoff_address: body.dropoffAddress, + dropoff_phone_number: body.dropoffPhoneNumber, + dropoff_business_name: body.dropoffBusinessName, + order_value: Number(body.orderValue), + ...(body.pickupInstructions && { pickup_instructions: body.pickupInstructions }), + ...(body.dropoffInstructions && { dropoff_instructions: body.dropoffInstructions }), + ...(body.tip && { tip: Number(body.tip) }), + ...(body.dropoffContactSendNotifications && { + dropoff_contact_send_notifications: body.dropoffContactSendNotifications === 'true', + }), + ...(body.actionIfUndeliverable && { + action_if_undeliverable: body.actionIfUndeliverable, + }), + ...(body.contactlessDropoff && { + contactless_dropoff: body.contactlessDropoff === 'true', + }), + ...(body.dropoffRequiresSignature && { + dropoff_requires_signature: body.dropoffRequiresSignature === 'true', + }), + ...(body.dropoffContactGivenName && { + dropoff_contact_given_name: body.dropoffContactGivenName, + }), + ...(body.dropoffContactFamilyName && { + dropoff_contact_family_name: body.dropoffContactFamilyName, + }), + ...(body.pickupTime && { pickup_time: body.pickupTime }), + ...(body.dropoffTime && { dropoff_time: body.dropoffTime }), + } + break + } + + case 'accept_quote': { + url = `${DRIVE_V2}/quotes/${encodeURIComponent(body.externalDeliveryId?.trim() ?? '')}/accept` + method = 'POST' + requestBody = { + ...(body.tip && { tip: Number(body.tip) }), + ...(body.dropoffPhoneNumber && { dropoff_phone_number: body.dropoffPhoneNumber }), + } + break + } + + case 'create_delivery': { + url = `${DRIVE_V2}/deliveries` + method = 'POST' + requestBody = { + external_delivery_id: body.externalDeliveryId?.trim(), + pickup_address: body.pickupAddress, + pickup_phone_number: body.pickupPhoneNumber, + pickup_business_name: body.pickupBusinessName, + dropoff_address: body.dropoffAddress, + dropoff_phone_number: body.dropoffPhoneNumber, + dropoff_business_name: body.dropoffBusinessName, + order_value: Number(body.orderValue), + ...(body.pickupInstructions && { pickup_instructions: body.pickupInstructions }), + ...(body.dropoffInstructions && { dropoff_instructions: body.dropoffInstructions }), + ...(body.tip && { tip: Number(body.tip) }), + ...(body.dropoffContactSendNotifications && { + dropoff_contact_send_notifications: body.dropoffContactSendNotifications === 'true', + }), + ...(body.actionIfUndeliverable && { + action_if_undeliverable: body.actionIfUndeliverable, + }), + ...(body.contactlessDropoff && { + contactless_dropoff: body.contactlessDropoff === 'true', + }), + ...(body.dropoffRequiresSignature && { + dropoff_requires_signature: body.dropoffRequiresSignature === 'true', + }), + ...(body.dropoffContactGivenName && { + dropoff_contact_given_name: body.dropoffContactGivenName, + }), + ...(body.dropoffContactFamilyName && { + dropoff_contact_family_name: body.dropoffContactFamilyName, + }), + ...(body.pickupTime && { pickup_time: body.pickupTime }), + ...(body.dropoffTime && { dropoff_time: body.dropoffTime }), + } + break + } + + case 'get_delivery': { + url = `${DRIVE_V2}/deliveries/${encodeURIComponent(body.externalDeliveryId?.trim() ?? '')}` + method = 'GET' + break + } + + case 'update_delivery': { + url = `${DRIVE_V2}/deliveries/${encodeURIComponent(body.externalDeliveryId?.trim() ?? '')}` + method = 'PATCH' + requestBody = { + ...(body.tip && { tip: Number(body.tip) }), + ...(body.dropoffPhoneNumber && { dropoff_phone_number: body.dropoffPhoneNumber }), + ...(body.dropoffInstructions && { dropoff_instructions: body.dropoffInstructions }), + } + break + } + + case 'cancel_delivery': { + url = `${DRIVE_V2}/deliveries/${encodeURIComponent(body.externalDeliveryId?.trim() ?? '')}/cancel` + method = 'PUT' + requestBody = {} + break + } + + case 'create_business': { + url = `${DEVELOPER_V1}/businesses` + method = 'POST' + requestBody = { + external_business_id: body.externalBusinessId?.trim(), + name: body.name, + ...(body.description && { description: body.description }), + } + break + } + + case 'list_businesses': { + url = `${DEVELOPER_V1}/businesses` + method = 'GET' + break + } + + case 'update_business': { + url = `${DEVELOPER_V1}/businesses/${encodeURIComponent(body.externalBusinessId?.trim() ?? '')}` + method = 'PATCH' + requestBody = { + ...(body.name && { name: body.name }), + ...(body.description && { description: body.description }), + } + break + } + + case 'create_store': { + url = `${DEVELOPER_V1}/businesses/${encodeURIComponent(body.externalBusinessId?.trim() ?? '')}/stores` + method = 'POST' + requestBody = { + external_store_id: body.externalStoreId?.trim(), + name: body.name, + phone_number: body.phoneNumber, + address: body.address, + } + break + } + + case 'list_stores': { + url = `${DEVELOPER_V1}/businesses/${encodeURIComponent(body.externalBusinessId?.trim() ?? '')}/stores` + method = 'GET' + break + } + + case 'get_store': { + url = `${DEVELOPER_V1}/businesses/${encodeURIComponent(body.externalBusinessId?.trim() ?? '')}/stores/${encodeURIComponent(body.externalStoreId?.trim() ?? '')}` + method = 'GET' + break + } + + case 'update_store': { + url = `${DEVELOPER_V1}/businesses/${encodeURIComponent(body.externalBusinessId?.trim() ?? '')}/stores/${encodeURIComponent(body.externalStoreId?.trim() ?? '')}` + method = 'PATCH' + requestBody = { + ...(body.name && { name: body.name }), + ...(body.phoneNumber && { phone_number: body.phoneNumber }), + ...(body.address && { address: body.address }), + } + break + } + } + + const fetchOptions: RequestInit = { + method, + headers, + ...(requestBody && { body: JSON.stringify(requestBody) }), + } + + const response = await fetch(url, fetchOptions) + const data = await response.json() + + if (!response.ok) { + const errorMessage = + (data as Record).message ?? + (data as Record).error ?? + `DoorDash API error (${response.status})` + logger.error('DoorDash API error', { status: response.status, error: errorMessage }) + return NextResponse.json( + { success: false, error: String(errorMessage) }, + { status: response.status } + ) + } + + let output: Record + + switch (body.operation) { + case 'list_businesses': { + const results = Array.isArray(data) ? data : (data as Record).result ?? [] + output = { + businesses: (results as Record[]).map(extractBusinessOutput), + } + break + } + case 'create_business': + case 'update_business': { + output = extractBusinessOutput(data as Record) + break + } + case 'list_stores': { + const results = Array.isArray(data) ? data : (data as Record).result ?? [] + output = { + stores: (results as Record[]).map(extractStoreOutput), + } + break + } + case 'create_store': + case 'get_store': + case 'update_store': { + output = extractStoreOutput(data as Record) + break + } + default: { + output = extractDeliveryOutput(data as Record) + break + } + } + + return NextResponse.json({ success: true, output }) + } catch (error) { + logger.error('DoorDash API request failed', { error }) + return NextResponse.json( + { success: false, error: 'Failed to communicate with DoorDash API' }, + { status: 500 } + ) + } +} diff --git a/apps/sim/blocks/blocks/doordash.ts b/apps/sim/blocks/blocks/doordash.ts new file mode 100644 index 00000000000..1ac209fb2c9 --- /dev/null +++ b/apps/sim/blocks/blocks/doordash.ts @@ -0,0 +1,475 @@ +import { DoordashIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import { AuthMode, IntegrationType } from '@/blocks/types' +import type { DoordashDeliveryResponse } from '@/tools/doordash/types' + +export const DoordashBlock: BlockConfig = { + type: 'doordash', + name: 'DoorDash', + description: 'Create and manage DoorDash Drive deliveries, businesses, and stores', + longDescription: + 'Integrate DoorDash Drive into workflows. Create delivery quotes, accept quotes, create deliveries, track status, update details, cancel deliveries, and manage businesses and store locations.', + docsLink: 'https://docs.sim.ai/tools/doordash', + category: 'tools', + integrationType: IntegrationType.Ecommerce, + tags: ['automation'], + bgColor: '#FF3008', + icon: DoordashIcon, + authMode: AuthMode.ApiKey, + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + { label: 'Create Quote', id: 'create_quote' }, + { label: 'Accept Quote', id: 'accept_quote' }, + { label: 'Create Delivery', id: 'create_delivery' }, + { label: 'Get Delivery', id: 'get_delivery' }, + { label: 'Update Delivery', id: 'update_delivery' }, + { label: 'Cancel Delivery', id: 'cancel_delivery' }, + { label: 'Create Business', id: 'create_business' }, + { label: 'List Businesses', id: 'list_businesses' }, + { label: 'Update Business', id: 'update_business' }, + { label: 'Create Store', id: 'create_store' }, + { label: 'List Stores', id: 'list_stores' }, + { label: 'Get Store', id: 'get_store' }, + { label: 'Update Store', id: 'update_store' }, + ], + value: () => 'create_quote', + }, + + // Credentials (common to all operations) + { + id: 'developerId', + title: 'Developer ID', + type: 'short-input', + placeholder: 'Enter your DoorDash Developer ID', + password: true, + required: true, + }, + { + id: 'keyId', + title: 'Key ID', + type: 'short-input', + placeholder: 'Enter your DoorDash Key ID', + password: true, + required: true, + }, + { + id: 'signingSecret', + title: 'Signing Secret', + type: 'short-input', + placeholder: 'Enter your DoorDash Signing Secret', + password: true, + required: true, + }, + + // Delivery ID (delivery operations only) + { + id: 'externalDeliveryId', + title: 'External Delivery ID', + type: 'short-input', + placeholder: 'Unique delivery identifier (e.g., D-12345)', + required: { + field: 'operation', + value: [ + 'create_quote', + 'accept_quote', + 'create_delivery', + 'get_delivery', + 'update_delivery', + 'cancel_delivery', + ], + }, + condition: { + field: 'operation', + value: [ + 'create_quote', + 'accept_quote', + 'create_delivery', + 'get_delivery', + 'update_delivery', + 'cancel_delivery', + ], + }, + }, + + // Pickup fields (create_quote and create_delivery) + { + id: 'pickupAddress', + title: 'Pickup Address', + type: 'short-input', + placeholder: '901 Market Street, San Francisco, CA 94103', + required: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'pickupPhoneNumber', + title: 'Pickup Phone', + type: 'short-input', + placeholder: '+16505555555', + required: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'pickupBusinessName', + title: 'Pickup Business Name', + type: 'short-input', + placeholder: 'Business name at pickup', + required: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + + // Dropoff fields (create_quote and create_delivery) + { + id: 'dropoffAddress', + title: 'Dropoff Address', + type: 'short-input', + placeholder: '123 Main Street, San Francisco, CA 94105', + required: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'dropoffPhoneNumber', + title: 'Dropoff Phone', + type: 'short-input', + placeholder: '+16505555555', + required: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + condition: { + field: 'operation', + value: ['create_quote', 'create_delivery', 'accept_quote', 'update_delivery'], + }, + }, + { + id: 'dropoffBusinessName', + title: 'Dropoff Contact Name', + type: 'short-input', + placeholder: 'Recipient name or business', + required: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + + // Order value (create_quote and create_delivery) + { + id: 'orderValue', + title: 'Order Value (cents)', + type: 'short-input', + placeholder: '1999 (for $19.99)', + required: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + + // Recipient name fields (advanced, create_quote/create_delivery) + { + id: 'dropoffContactGivenName', + title: 'Recipient First Name', + type: 'short-input', + placeholder: 'Customer first name', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'dropoffContactFamilyName', + title: 'Recipient Last Name', + type: 'short-input', + placeholder: 'Customer last name', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + + // Optional delivery fields + { + id: 'pickupInstructions', + title: 'Pickup Instructions', + type: 'short-input', + placeholder: 'Instructions for the Dasher at pickup', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'dropoffInstructions', + title: 'Dropoff Instructions', + type: 'short-input', + placeholder: 'Instructions for the Dasher at dropoff', + mode: 'advanced', + condition: { + field: 'operation', + value: ['create_quote', 'create_delivery', 'update_delivery'], + }, + }, + { + id: 'tip', + title: 'Tip (cents)', + type: 'short-input', + placeholder: '500 (for $5.00)', + mode: 'advanced', + condition: { + field: 'operation', + value: ['create_quote', 'create_delivery', 'accept_quote', 'update_delivery'], + }, + }, + { + id: 'pickupTime', + title: 'Scheduled Pickup Time', + type: 'short-input', + placeholder: 'ISO 8601 (e.g., 2025-01-15T14:00:00Z)', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + wandConfig: { + enabled: true, + prompt: `Generate an ISO 8601 timestamp for the requested pickup time. Return ONLY the timestamp string - no explanations, no extra text.`, + placeholder: 'Describe when to pick up (e.g., "in 2 hours", "tomorrow at 3pm")...', + generationType: 'timestamp', + }, + }, + { + id: 'dropoffTime', + title: 'Scheduled Dropoff Time', + type: 'short-input', + placeholder: 'ISO 8601 (e.g., 2025-01-15T15:00:00Z)', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + wandConfig: { + enabled: true, + prompt: `Generate an ISO 8601 timestamp for the requested dropoff time. Return ONLY the timestamp string - no explanations, no extra text.`, + placeholder: 'Describe when to deliver (e.g., "by 5pm", "in 3 hours")...', + generationType: 'timestamp', + }, + }, + { + id: 'contactlessDropoff', + title: 'Contactless Dropoff', + type: 'dropdown', + options: [ + { label: 'No', id: '' }, + { label: 'Yes', id: 'true' }, + ], + value: () => '', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'dropoffRequiresSignature', + title: 'Require Signature', + type: 'dropdown', + options: [ + { label: 'No', id: '' }, + { label: 'Yes', id: 'true' }, + ], + value: () => '', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'dropoffContactSendNotifications', + title: 'Send SMS Notifications', + type: 'dropdown', + options: [ + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => 'true', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + { + id: 'actionIfUndeliverable', + title: 'If Undeliverable', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Return to Pickup', id: 'return_to_pickup' }, + ], + value: () => '', + mode: 'advanced', + condition: { field: 'operation', value: ['create_quote', 'create_delivery'] }, + }, + + // Business fields + { + id: 'externalBusinessId', + title: 'Business ID', + type: 'short-input', + placeholder: 'Unique business identifier', + required: { + field: 'operation', + value: [ + 'create_business', + 'update_business', + 'create_store', + 'list_stores', + 'get_store', + 'update_store', + ], + }, + condition: { + field: 'operation', + value: [ + 'create_business', + 'update_business', + 'create_store', + 'list_stores', + 'get_store', + 'update_store', + ], + }, + }, + { + id: 'name', + title: 'Name', + type: 'short-input', + placeholder: 'Business or store name', + required: { + field: 'operation', + value: ['create_business', 'create_store'], + }, + condition: { + field: 'operation', + value: ['create_business', 'update_business', 'create_store', 'update_store'], + }, + }, + { + id: 'description', + title: 'Description', + type: 'short-input', + placeholder: 'Business description', + mode: 'advanced', + condition: { + field: 'operation', + value: ['create_business', 'update_business'], + }, + }, + + // Store fields + { + id: 'externalStoreId', + title: 'Store ID', + type: 'short-input', + placeholder: 'Unique store identifier', + required: { + field: 'operation', + value: ['create_store', 'get_store', 'update_store'], + }, + condition: { + field: 'operation', + value: ['create_store', 'get_store', 'update_store'], + }, + }, + { + id: 'phoneNumber', + title: 'Store Phone', + type: 'short-input', + placeholder: '+16505555555', + required: { field: 'operation', value: 'create_store' }, + condition: { + field: 'operation', + value: ['create_store', 'update_store'], + }, + }, + { + id: 'address', + title: 'Store Address', + type: 'short-input', + placeholder: '901 Market Street, San Francisco, CA 94103', + required: { field: 'operation', value: 'create_store' }, + condition: { + field: 'operation', + value: ['create_store', 'update_store'], + }, + }, + ], + tools: { + access: [ + 'doordash_create_quote', + 'doordash_accept_quote', + 'doordash_create_delivery', + 'doordash_get_delivery', + 'doordash_update_delivery', + 'doordash_cancel_delivery', + 'doordash_create_business', + 'doordash_list_businesses', + 'doordash_update_business', + 'doordash_create_store', + 'doordash_list_stores', + 'doordash_get_store', + 'doordash_update_store', + ], + config: { + tool: (params) => `doordash_${params.operation}`, + params: (params) => { + const result: Record = {} + if (params.orderValue) result.orderValue = String(params.orderValue) + if (params.tip) result.tip = String(params.tip) + if (params.actionIfUndeliverable === '') result.actionIfUndeliverable = undefined + if (params.contactlessDropoff === '') result.contactlessDropoff = undefined + if (params.dropoffRequiresSignature === '') result.dropoffRequiresSignature = undefined + return result + }, + }, + }, + inputs: { + operation: { type: 'string', description: 'Operation to perform' }, + developerId: { type: 'string', description: 'DoorDash Developer ID' }, + keyId: { type: 'string', description: 'DoorDash Key ID' }, + signingSecret: { type: 'string', description: 'DoorDash Signing Secret' }, + externalDeliveryId: { type: 'string', description: 'Unique delivery identifier' }, + pickupAddress: { type: 'string', description: 'Pickup address' }, + pickupPhoneNumber: { type: 'string', description: 'Pickup phone number' }, + pickupBusinessName: { type: 'string', description: 'Pickup business name' }, + dropoffAddress: { type: 'string', description: 'Dropoff address' }, + dropoffPhoneNumber: { type: 'string', description: 'Dropoff phone number' }, + dropoffBusinessName: { type: 'string', description: 'Dropoff contact name' }, + orderValue: { type: 'string', description: 'Order value in cents' }, + dropoffContactGivenName: { type: 'string', description: 'Recipient first name' }, + dropoffContactFamilyName: { type: 'string', description: 'Recipient last name' }, + pickupInstructions: { type: 'string', description: 'Pickup instructions' }, + dropoffInstructions: { type: 'string', description: 'Dropoff instructions' }, + tip: { type: 'string', description: 'Tip amount in cents' }, + pickupTime: { type: 'string', description: 'Scheduled pickup time (ISO 8601)' }, + dropoffTime: { type: 'string', description: 'Scheduled dropoff time (ISO 8601)' }, + contactlessDropoff: { type: 'string', description: 'Contactless dropoff' }, + dropoffRequiresSignature: { type: 'string', description: 'Require signature' }, + dropoffContactSendNotifications: { type: 'string', description: 'Send SMS notifications' }, + actionIfUndeliverable: { type: 'string', description: 'Action if undeliverable' }, + externalBusinessId: { type: 'string', description: 'Business ID' }, + name: { type: 'string', description: 'Business or store name' }, + description: { type: 'string', description: 'Business description' }, + externalStoreId: { type: 'string', description: 'Store ID' }, + phoneNumber: { type: 'string', description: 'Store phone number' }, + address: { type: 'string', description: 'Store address' }, + }, + outputs: { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status' }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + tip: { type: 'number', description: 'Tip amount in cents' }, + orderValue: { type: 'number', description: 'Order value in cents' }, + currency: { type: 'string', description: 'Fee currency code' }, + trackingUrl: { type: 'string', description: 'Delivery tracking URL' }, + supportReference: { type: 'string', description: 'Support reference ID' }, + dasherName: { type: 'string', description: 'Assigned Dasher name' }, + dasherId: { type: 'number', description: 'Assigned Dasher ID' }, + contactlessDropoff: { type: 'boolean', description: 'Whether contactless dropoff was used' }, + dropoffVerificationImageUrl: { type: 'string', description: 'Photo verification URL' }, + cancellationReason: { type: 'string', description: 'Reason for cancellation' }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time' }, + pickupTimeActual: { type: 'string', description: 'Actual pickup time' }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time' }, + dropoffTimeActual: { type: 'string', description: 'Actual dropoff time' }, + pickupAddress: { type: 'string', description: 'Pickup address' }, + dropoffAddress: { type: 'string', description: 'Dropoff address' }, + updatedAt: { type: 'string', description: 'Last updated timestamp' }, + externalBusinessId: { type: 'string', description: 'Business ID' }, + externalStoreId: { type: 'string', description: 'Store ID' }, + name: { type: 'string', description: 'Business or store name' }, + businesses: { + type: 'json', + description: 'List of businesses (externalBusinessId, name, description, activationStatus)', + }, + stores: { + type: 'json', + description: 'List of stores (externalStoreId, name, phoneNumber, address)', + }, + }, +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index ff9fd2dc2c0..dd7564d8677 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -31,6 +31,7 @@ import { DatadogBlock } from '@/blocks/blocks/datadog' import { DevinBlock } from '@/blocks/blocks/devin' import { DiscordBlock } from '@/blocks/blocks/discord' import { DocuSignBlock } from '@/blocks/blocks/docusign' +import { DoordashBlock } from '@/blocks/blocks/doordash' import { DropboxBlock } from '@/blocks/blocks/dropbox' import { DSPyBlock } from '@/blocks/blocks/dspy' import { DubBlock } from '@/blocks/blocks/dub' @@ -244,6 +245,7 @@ export const registry: Record = { devin: DevinBlock, discord: DiscordBlock, docusign: DocuSignBlock, + doordash: DoordashBlock, dropbox: DropboxBlock, dspy: DSPyBlock, dub: DubBlock, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index b79a166e901..f049157d62c 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -1193,6 +1193,18 @@ export function DocuSignIcon(props: SVGProps) { ) } +export function DoordashIcon(props: SVGProps) { + return ( + + + + + ) +} + export function DiscordIcon(props: SVGProps) { return ( = { + id: 'doordash_accept_quote', + name: 'DoorDash Accept Quote', + description: + 'Accepts a delivery quote to formally create the delivery. Must be called within 5 minutes of creating the quote.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Key ID', + }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalDeliveryId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'External delivery ID from the quote', + }, + tip: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Tip amount in cents', + }, + dropoffPhoneNumber: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated dropoff phone number', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'accept_quote', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalDeliveryId: params.externalDeliveryId, + tip: params.tip, + dropoffPhoneNumber: params.dropoffPhoneNumber, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to accept quote' } } + } + + return { + success: true, + output: { + externalDeliveryId: data.output.externalDeliveryId ?? '', + deliveryStatus: data.output.deliveryStatus ?? '', + fee: data.output.fee ?? null, + tip: data.output.tip ?? null, + orderValue: data.output.orderValue ?? null, + currency: data.output.currency ?? null, + trackingUrl: data.output.trackingUrl ?? null, + supportReference: data.output.supportReference ?? null, + dasherName: data.output.dasherName ?? null, + dasherId: data.output.dasherId ?? null, + contactlessDropoff: data.output.contactlessDropoff ?? null, + dropoffVerificationImageUrl: data.output.dropoffVerificationImageUrl ?? null, + cancellationReason: data.output.cancellationReason ?? null, + pickupTimeEstimated: data.output.pickupTimeEstimated ?? null, + pickupTimeActual: data.output.pickupTimeActual ?? null, + dropoffTimeEstimated: data.output.dropoffTimeEstimated ?? null, + dropoffTimeActual: data.output.dropoffTimeActual ?? null, + pickupAddress: data.output.pickupAddress ?? null, + dropoffAddress: data.output.dropoffAddress ?? null, + updatedAt: data.output.updatedAt ?? null, + }, + } + }, + + outputs: { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status' }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + tip: { type: 'number', description: 'Tip amount in cents', optional: true }, + orderValue: { type: 'number', description: 'Order value in cents' }, + currency: { type: 'string', description: 'Fee currency code' }, + trackingUrl: { type: 'string', description: 'Delivery tracking URL' }, + supportReference: { type: 'string', description: 'Support reference ID' }, + dasherName: { type: 'string', description: 'Assigned Dasher name', optional: true }, + dasherId: { type: 'number', description: 'Assigned Dasher ID', optional: true }, + contactlessDropoff: { type: 'boolean', description: 'Whether contactless dropoff was used', optional: true }, + dropoffVerificationImageUrl: { type: 'string', description: 'Photo verification URL at dropoff', optional: true }, + cancellationReason: { type: 'string', description: 'Reason for cancellation', optional: true }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time' }, + pickupTimeActual: { type: 'string', description: 'Actual pickup time', optional: true }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time' }, + dropoffTimeActual: { type: 'string', description: 'Actual dropoff time', optional: true }, + pickupAddress: { type: 'string', description: 'Pickup address' }, + dropoffAddress: { type: 'string', description: 'Dropoff address' }, + updatedAt: { type: 'string', description: 'Last updated timestamp', optional: true }, + }, +} diff --git a/apps/sim/tools/doordash/cancel_delivery.ts b/apps/sim/tools/doordash/cancel_delivery.ts new file mode 100644 index 00000000000..80aae843069 --- /dev/null +++ b/apps/sim/tools/doordash/cancel_delivery.ts @@ -0,0 +1,77 @@ +import type { + DoordashCancelDeliveryParams, + DoordashCancelResponse, +} from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const cancelDeliveryTool: ToolConfig< + DoordashCancelDeliveryParams, + DoordashCancelResponse +> = { + id: 'doordash_cancel_delivery', + name: 'DoorDash Cancel Delivery', + description: + 'Cancels a delivery. Cannot be used after a Dasher has been assigned to the delivery.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Key ID', + }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalDeliveryId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'External delivery ID to cancel', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'cancel_delivery', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalDeliveryId: params.externalDeliveryId, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to cancel delivery' } } + } + + return { + success: true, + output: { + externalDeliveryId: data.output.externalDeliveryId ?? '', + deliveryStatus: data.output.deliveryStatus ?? '', + }, + } + }, + + outputs: { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status (cancelled)' }, + }, +} diff --git a/apps/sim/tools/doordash/create_business.ts b/apps/sim/tools/doordash/create_business.ts new file mode 100644 index 00000000000..075f07a150e --- /dev/null +++ b/apps/sim/tools/doordash/create_business.ts @@ -0,0 +1,76 @@ +import type { DoordashBusinessResponse, DoordashCreateBusinessParams } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const createBusinessTool: ToolConfig = { + id: 'doordash_create_business', + name: 'DoorDash Create Business', + description: 'Creates a new business entity for organizing delivery locations.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { type: 'string', required: true, visibility: 'user-only', description: 'DoorDash Key ID' }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalBusinessId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Unique business identifier', + }, + name: { type: 'string', required: true, visibility: 'user-or-llm', description: 'Business name' }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Business description', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'create_business', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalBusinessId: params.externalBusinessId, + name: params.name, + description: params.description, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to create business' } } + } + return { + success: true, + output: { + externalBusinessId: data.output.externalBusinessId ?? '', + name: data.output.name ?? '', + description: data.output.description ?? null, + activationStatus: data.output.activationStatus ?? null, + }, + } + }, + + outputs: { + externalBusinessId: { type: 'string', description: 'Business ID' }, + name: { type: 'string', description: 'Business name' }, + description: { type: 'string', description: 'Business description', optional: true }, + activationStatus: { type: 'string', description: 'Activation status', optional: true }, + }, +} diff --git a/apps/sim/tools/doordash/create_delivery.ts b/apps/sim/tools/doordash/create_delivery.ts new file mode 100644 index 00000000000..4cd4162eea7 --- /dev/null +++ b/apps/sim/tools/doordash/create_delivery.ts @@ -0,0 +1,238 @@ +import type { + DoordashCreateDeliveryParams, + DoordashDeliveryResponse, +} from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const createDeliveryTool: ToolConfig< + DoordashCreateDeliveryParams, + DoordashDeliveryResponse +> = { + id: 'doordash_create_delivery', + name: 'DoorDash Create Delivery', + description: 'Creates a delivery directly without a prior quote. Skips price confirmation.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Key ID', + }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalDeliveryId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Unique delivery identifier', + }, + pickupAddress: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Pickup address (e.g., "901 Market Street 6th Floor San Francisco, CA 94103")', + }, + pickupPhoneNumber: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Pickup phone number (e.g., "+16505555555")', + }, + pickupBusinessName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Pickup business name', + }, + dropoffAddress: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Dropoff address', + }, + dropoffPhoneNumber: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Dropoff phone number', + }, + dropoffBusinessName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Dropoff contact or business name', + }, + orderValue: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Order value in cents (e.g., "1999" for $19.99)', + }, + pickupInstructions: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Instructions for pickup', + }, + dropoffInstructions: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Instructions for dropoff', + }, + tip: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Tip amount in cents', + }, + dropoffContactSendNotifications: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Send SMS notifications to recipient (true/false)', + }, + actionIfUndeliverable: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Action if undeliverable (e.g., "return_to_pickup")', + }, + contactlessDropoff: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Contactless doorstep delivery with photo verification (true/false)', + }, + dropoffRequiresSignature: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Require signature at dropoff (true/false)', + }, + dropoffContactGivenName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Recipient first name', + }, + dropoffContactFamilyName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Recipient last name', + }, + pickupTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Scheduled pickup time (ISO 8601, mutually exclusive with dropoffTime)', + }, + dropoffTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Scheduled dropoff time (ISO 8601, mutually exclusive with pickupTime)', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'create_delivery', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalDeliveryId: params.externalDeliveryId, + pickupAddress: params.pickupAddress, + pickupPhoneNumber: params.pickupPhoneNumber, + pickupBusinessName: params.pickupBusinessName, + dropoffAddress: params.dropoffAddress, + dropoffPhoneNumber: params.dropoffPhoneNumber, + dropoffBusinessName: params.dropoffBusinessName, + orderValue: params.orderValue, + pickupInstructions: params.pickupInstructions, + dropoffInstructions: params.dropoffInstructions, + tip: params.tip, + dropoffContactSendNotifications: params.dropoffContactSendNotifications, + actionIfUndeliverable: params.actionIfUndeliverable, + contactlessDropoff: params.contactlessDropoff, + dropoffRequiresSignature: params.dropoffRequiresSignature, + dropoffContactGivenName: params.dropoffContactGivenName, + dropoffContactFamilyName: params.dropoffContactFamilyName, + pickupTime: params.pickupTime, + dropoffTime: params.dropoffTime, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to create delivery' } } + } + + return { + success: true, + output: { + externalDeliveryId: data.output.externalDeliveryId ?? '', + deliveryStatus: data.output.deliveryStatus ?? '', + fee: data.output.fee ?? null, + tip: data.output.tip ?? null, + orderValue: data.output.orderValue ?? null, + currency: data.output.currency ?? null, + trackingUrl: data.output.trackingUrl ?? null, + supportReference: data.output.supportReference ?? null, + dasherName: data.output.dasherName ?? null, + dasherId: data.output.dasherId ?? null, + contactlessDropoff: data.output.contactlessDropoff ?? null, + dropoffVerificationImageUrl: data.output.dropoffVerificationImageUrl ?? null, + cancellationReason: data.output.cancellationReason ?? null, + pickupTimeEstimated: data.output.pickupTimeEstimated ?? null, + pickupTimeActual: data.output.pickupTimeActual ?? null, + dropoffTimeEstimated: data.output.dropoffTimeEstimated ?? null, + dropoffTimeActual: data.output.dropoffTimeActual ?? null, + pickupAddress: data.output.pickupAddress ?? null, + dropoffAddress: data.output.dropoffAddress ?? null, + updatedAt: data.output.updatedAt ?? null, + }, + } + }, + + outputs: { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status' }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + tip: { type: 'number', description: 'Tip amount in cents', optional: true }, + orderValue: { type: 'number', description: 'Order value in cents' }, + currency: { type: 'string', description: 'Fee currency code' }, + trackingUrl: { type: 'string', description: 'Delivery tracking URL' }, + supportReference: { type: 'string', description: 'Support reference ID' }, + dasherName: { type: 'string', description: 'Assigned Dasher name', optional: true }, + dasherId: { type: 'number', description: 'Assigned Dasher ID', optional: true }, + contactlessDropoff: { type: 'boolean', description: 'Whether contactless dropoff was used', optional: true }, + dropoffVerificationImageUrl: { type: 'string', description: 'Photo verification URL at dropoff', optional: true }, + cancellationReason: { type: 'string', description: 'Reason for cancellation', optional: true }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time' }, + pickupTimeActual: { type: 'string', description: 'Actual pickup time', optional: true }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time' }, + dropoffTimeActual: { type: 'string', description: 'Actual dropoff time', optional: true }, + pickupAddress: { type: 'string', description: 'Pickup address' }, + dropoffAddress: { type: 'string', description: 'Dropoff address' }, + updatedAt: { type: 'string', description: 'Last updated timestamp', optional: true }, + }, +} diff --git a/apps/sim/tools/doordash/create_quote.ts b/apps/sim/tools/doordash/create_quote.ts new file mode 100644 index 00000000000..d4843c747b9 --- /dev/null +++ b/apps/sim/tools/doordash/create_quote.ts @@ -0,0 +1,205 @@ +import type { DoordashCreateQuoteParams, DoordashQuoteResponse } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const createQuoteTool: ToolConfig = { + id: 'doordash_create_quote', + name: 'DoorDash Create Quote', + description: + 'Creates a delivery quote to validate coverage, pricing, and estimated delivery times.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Key ID', + }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalDeliveryId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Unique delivery identifier', + }, + pickupAddress: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Pickup address (e.g., "901 Market Street 6th Floor San Francisco, CA 94103")', + }, + pickupPhoneNumber: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Pickup phone number (e.g., "+16505555555")', + }, + pickupBusinessName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Pickup business name', + }, + dropoffAddress: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Dropoff address', + }, + dropoffPhoneNumber: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Dropoff phone number', + }, + dropoffBusinessName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Dropoff contact or business name', + }, + orderValue: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Order value in cents (e.g., "1999" for $19.99)', + }, + pickupInstructions: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Instructions for pickup', + }, + dropoffInstructions: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Instructions for dropoff', + }, + tip: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Tip amount in cents', + }, + dropoffContactSendNotifications: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Send SMS notifications to recipient (true/false)', + }, + actionIfUndeliverable: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Action if undeliverable (e.g., "return_to_pickup")', + }, + contactlessDropoff: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Contactless doorstep delivery with photo verification (true/false)', + }, + dropoffRequiresSignature: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Require signature at dropoff (true/false)', + }, + dropoffContactGivenName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Recipient first name', + }, + dropoffContactFamilyName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Recipient last name', + }, + pickupTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Scheduled pickup time (ISO 8601, mutually exclusive with dropoffTime)', + }, + dropoffTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Scheduled dropoff time (ISO 8601, mutually exclusive with pickupTime)', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'create_quote', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalDeliveryId: params.externalDeliveryId, + pickupAddress: params.pickupAddress, + pickupPhoneNumber: params.pickupPhoneNumber, + pickupBusinessName: params.pickupBusinessName, + dropoffAddress: params.dropoffAddress, + dropoffPhoneNumber: params.dropoffPhoneNumber, + dropoffBusinessName: params.dropoffBusinessName, + orderValue: params.orderValue, + pickupInstructions: params.pickupInstructions, + dropoffInstructions: params.dropoffInstructions, + tip: params.tip, + dropoffContactSendNotifications: params.dropoffContactSendNotifications, + actionIfUndeliverable: params.actionIfUndeliverable, + contactlessDropoff: params.contactlessDropoff, + dropoffRequiresSignature: params.dropoffRequiresSignature, + dropoffContactGivenName: params.dropoffContactGivenName, + dropoffContactFamilyName: params.dropoffContactFamilyName, + pickupTime: params.pickupTime, + dropoffTime: params.dropoffTime, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to create quote' } } + } + + return { + success: true, + output: { + externalDeliveryId: data.output.externalDeliveryId ?? '', + deliveryStatus: data.output.deliveryStatus ?? '', + fee: data.output.fee ?? null, + currency: data.output.currency ?? null, + pickupTimeEstimated: data.output.pickupTimeEstimated ?? null, + dropoffTimeEstimated: data.output.dropoffTimeEstimated ?? null, + }, + } + }, + + outputs: { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status' }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + currency: { type: 'string', description: 'Fee currency code' }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time' }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time' }, + }, +} diff --git a/apps/sim/tools/doordash/create_store.ts b/apps/sim/tools/doordash/create_store.ts new file mode 100644 index 00000000000..1a2d60a525b --- /dev/null +++ b/apps/sim/tools/doordash/create_store.ts @@ -0,0 +1,85 @@ +import type { DoordashCreateStoreParams, DoordashStoreResponse } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const createStoreTool: ToolConfig = { + id: 'doordash_create_store', + name: 'DoorDash Create Store', + description: 'Creates a store location under a business for delivery pickup.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { type: 'string', required: true, visibility: 'user-only', description: 'DoorDash Key ID' }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalBusinessId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Parent business ID', + }, + externalStoreId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Unique store identifier', + }, + name: { type: 'string', required: true, visibility: 'user-or-llm', description: 'Store name' }, + phoneNumber: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Store phone number', + }, + address: { type: 'string', required: true, visibility: 'user-or-llm', description: 'Store address' }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'create_store', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalBusinessId: params.externalBusinessId, + externalStoreId: params.externalStoreId, + name: params.name, + phoneNumber: params.phoneNumber, + address: params.address, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to create store' } } + } + return { + success: true, + output: { + externalStoreId: data.output.externalStoreId ?? '', + name: data.output.name ?? '', + phoneNumber: data.output.phoneNumber ?? null, + address: data.output.address ?? null, + }, + } + }, + + outputs: { + externalStoreId: { type: 'string', description: 'Store ID' }, + name: { type: 'string', description: 'Store name' }, + phoneNumber: { type: 'string', description: 'Store phone number' }, + address: { type: 'string', description: 'Store address' }, + }, +} diff --git a/apps/sim/tools/doordash/get_delivery.ts b/apps/sim/tools/doordash/get_delivery.ts new file mode 100644 index 00000000000..a009d316087 --- /dev/null +++ b/apps/sim/tools/doordash/get_delivery.ts @@ -0,0 +1,106 @@ +import type { DoordashDeliveryResponse, DoordashGetDeliveryParams } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const getDeliveryTool: ToolConfig = { + id: 'doordash_get_delivery', + name: 'DoorDash Get Delivery', + description: 'Retrieves the current status and details of a delivery.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Key ID', + }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalDeliveryId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'External delivery ID to look up', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'get_delivery', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalDeliveryId: params.externalDeliveryId, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to get delivery' } } + } + + return { + success: true, + output: { + externalDeliveryId: data.output.externalDeliveryId ?? '', + deliveryStatus: data.output.deliveryStatus ?? '', + fee: data.output.fee ?? null, + tip: data.output.tip ?? null, + orderValue: data.output.orderValue ?? null, + currency: data.output.currency ?? null, + trackingUrl: data.output.trackingUrl ?? null, + supportReference: data.output.supportReference ?? null, + dasherName: data.output.dasherName ?? null, + dasherId: data.output.dasherId ?? null, + contactlessDropoff: data.output.contactlessDropoff ?? null, + dropoffVerificationImageUrl: data.output.dropoffVerificationImageUrl ?? null, + cancellationReason: data.output.cancellationReason ?? null, + pickupTimeEstimated: data.output.pickupTimeEstimated ?? null, + pickupTimeActual: data.output.pickupTimeActual ?? null, + dropoffTimeEstimated: data.output.dropoffTimeEstimated ?? null, + dropoffTimeActual: data.output.dropoffTimeActual ?? null, + pickupAddress: data.output.pickupAddress ?? null, + dropoffAddress: data.output.dropoffAddress ?? null, + updatedAt: data.output.updatedAt ?? null, + }, + } + }, + + outputs: { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status' }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + tip: { type: 'number', description: 'Tip amount in cents', optional: true }, + orderValue: { type: 'number', description: 'Order value in cents' }, + currency: { type: 'string', description: 'Fee currency code' }, + trackingUrl: { type: 'string', description: 'Delivery tracking URL' }, + supportReference: { type: 'string', description: 'Support reference ID' }, + dasherName: { type: 'string', description: 'Assigned Dasher name', optional: true }, + dasherId: { type: 'number', description: 'Assigned Dasher ID', optional: true }, + contactlessDropoff: { type: 'boolean', description: 'Whether contactless dropoff was used', optional: true }, + dropoffVerificationImageUrl: { type: 'string', description: 'Photo verification URL at dropoff', optional: true }, + cancellationReason: { type: 'string', description: 'Reason for cancellation', optional: true }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time' }, + pickupTimeActual: { type: 'string', description: 'Actual pickup time', optional: true }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time' }, + dropoffTimeActual: { type: 'string', description: 'Actual dropoff time', optional: true }, + pickupAddress: { type: 'string', description: 'Pickup address' }, + dropoffAddress: { type: 'string', description: 'Dropoff address' }, + updatedAt: { type: 'string', description: 'Last updated timestamp', optional: true }, + }, +} diff --git a/apps/sim/tools/doordash/get_store.ts b/apps/sim/tools/doordash/get_store.ts new file mode 100644 index 00000000000..d7052634b30 --- /dev/null +++ b/apps/sim/tools/doordash/get_store.ts @@ -0,0 +1,74 @@ +import type { DoordashGetStoreParams, DoordashStoreResponse } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const getStoreTool: ToolConfig = { + id: 'doordash_get_store', + name: 'DoorDash Get Store', + description: 'Retrieves details of a specific store.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { type: 'string', required: true, visibility: 'user-only', description: 'DoorDash Key ID' }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalBusinessId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Parent business ID', + }, + externalStoreId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Store ID to retrieve', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'get_store', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalBusinessId: params.externalBusinessId, + externalStoreId: params.externalStoreId, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to get store' } } + } + return { + success: true, + output: { + externalStoreId: data.output.externalStoreId ?? '', + name: data.output.name ?? '', + phoneNumber: data.output.phoneNumber ?? null, + address: data.output.address ?? null, + }, + } + }, + + outputs: { + externalStoreId: { type: 'string', description: 'Store ID' }, + name: { type: 'string', description: 'Store name' }, + phoneNumber: { type: 'string', description: 'Store phone number' }, + address: { type: 'string', description: 'Store address' }, + }, +} diff --git a/apps/sim/tools/doordash/index.ts b/apps/sim/tools/doordash/index.ts new file mode 100644 index 00000000000..bb42aa3c24a --- /dev/null +++ b/apps/sim/tools/doordash/index.ts @@ -0,0 +1,51 @@ +import { acceptQuoteTool } from '@/tools/doordash/accept_quote' +import { cancelDeliveryTool } from '@/tools/doordash/cancel_delivery' +import { createBusinessTool } from '@/tools/doordash/create_business' +import { createDeliveryTool } from '@/tools/doordash/create_delivery' +import { createQuoteTool } from '@/tools/doordash/create_quote' +import { createStoreTool } from '@/tools/doordash/create_store' +import { getDeliveryTool } from '@/tools/doordash/get_delivery' +import { getStoreTool } from '@/tools/doordash/get_store' +import { listBusinessesTool } from '@/tools/doordash/list_businesses' +import { listStoresTool } from '@/tools/doordash/list_stores' +import { updateBusinessTool } from '@/tools/doordash/update_business' +import { updateDeliveryTool } from '@/tools/doordash/update_delivery' +import { updateStoreTool } from '@/tools/doordash/update_store' + +export const doordashAcceptQuoteTool = acceptQuoteTool +export const doordashCancelDeliveryTool = cancelDeliveryTool +export const doordashCreateBusinessTool = createBusinessTool +export const doordashCreateDeliveryTool = createDeliveryTool +export const doordashCreateQuoteTool = createQuoteTool +export const doordashCreateStoreTool = createStoreTool +export const doordashGetDeliveryTool = getDeliveryTool +export const doordashGetStoreTool = getStoreTool +export const doordashListBusinessesTool = listBusinessesTool +export const doordashListStoresTool = listStoresTool +export const doordashUpdateBusinessTool = updateBusinessTool +export const doordashUpdateDeliveryTool = updateDeliveryTool +export const doordashUpdateStoreTool = updateStoreTool + +export type { + DoordashAcceptQuoteParams, + DoordashBaseParams, + DoordashBusinessListResponse, + DoordashBusinessResponse, + DoordashCancelDeliveryParams, + DoordashCancelResponse, + DoordashCreateBusinessParams, + DoordashCreateDeliveryParams, + DoordashCreateQuoteParams, + DoordashCreateStoreParams, + DoordashDeliveryResponse, + DoordashGetDeliveryParams, + DoordashGetStoreParams, + DoordashListBusinessesParams, + DoordashListStoresParams, + DoordashQuoteResponse, + DoordashStoreListResponse, + DoordashStoreResponse, + DoordashUpdateBusinessParams, + DoordashUpdateDeliveryParams, + DoordashUpdateStoreParams, +} from '@/tools/doordash/types' diff --git a/apps/sim/tools/doordash/list_businesses.ts b/apps/sim/tools/doordash/list_businesses.ts new file mode 100644 index 00000000000..fecd485ebbf --- /dev/null +++ b/apps/sim/tools/doordash/list_businesses.ts @@ -0,0 +1,64 @@ +import type { DoordashBusinessListResponse, DoordashListBusinessesParams } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const listBusinessesTool: ToolConfig< + DoordashListBusinessesParams, + DoordashBusinessListResponse +> = { + id: 'doordash_list_businesses', + name: 'DoorDash List Businesses', + description: 'Lists all businesses owned by the developer.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { type: 'string', required: true, visibility: 'user-only', description: 'DoorDash Key ID' }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'list_businesses', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to list businesses' } } + } + return { success: true, output: { businesses: data.output.businesses ?? [] } } + }, + + outputs: { + businesses: { + type: 'array', + description: 'List of businesses', + items: { + type: 'object', + properties: { + externalBusinessId: { type: 'string', description: 'Business ID' }, + name: { type: 'string', description: 'Business name' }, + description: { type: 'string', description: 'Business description' }, + activationStatus: { type: 'string', description: 'Activation status' }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/doordash/list_stores.ts b/apps/sim/tools/doordash/list_stores.ts new file mode 100644 index 00000000000..f20a02b65e6 --- /dev/null +++ b/apps/sim/tools/doordash/list_stores.ts @@ -0,0 +1,68 @@ +import type { DoordashListStoresParams, DoordashStoreListResponse } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const listStoresTool: ToolConfig = { + id: 'doordash_list_stores', + name: 'DoorDash List Stores', + description: 'Lists all stores under a business.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { type: 'string', required: true, visibility: 'user-only', description: 'DoorDash Key ID' }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalBusinessId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Business ID to list stores for', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'list_stores', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalBusinessId: params.externalBusinessId, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to list stores' } } + } + return { success: true, output: { stores: data.output.stores ?? [] } } + }, + + outputs: { + stores: { + type: 'array', + description: 'List of stores', + items: { + type: 'object', + properties: { + externalStoreId: { type: 'string', description: 'Store ID' }, + name: { type: 'string', description: 'Store name' }, + phoneNumber: { type: 'string', description: 'Store phone number' }, + address: { type: 'string', description: 'Store address' }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/doordash/types.ts b/apps/sim/tools/doordash/types.ts new file mode 100644 index 00000000000..ca6c47a365d --- /dev/null +++ b/apps/sim/tools/doordash/types.ts @@ -0,0 +1,238 @@ +import type { OutputProperty, ToolResponse } from '@/tools/types' + +export interface DoordashBaseParams { + developerId: string + keyId: string + signingSecret: string +} + +export interface DoordashCreateQuoteParams extends DoordashBaseParams { + externalDeliveryId: string + pickupAddress: string + pickupPhoneNumber: string + pickupBusinessName: string + dropoffAddress: string + dropoffPhoneNumber: string + dropoffBusinessName: string + orderValue: string + pickupInstructions?: string + dropoffInstructions?: string + tip?: string + dropoffContactSendNotifications?: string + actionIfUndeliverable?: string + contactlessDropoff?: string + dropoffRequiresSignature?: string + dropoffContactGivenName?: string + dropoffContactFamilyName?: string + pickupTime?: string + dropoffTime?: string +} + +export interface DoordashAcceptQuoteParams extends DoordashBaseParams { + externalDeliveryId: string + tip?: string + dropoffPhoneNumber?: string +} + +export interface DoordashCreateDeliveryParams extends DoordashBaseParams { + externalDeliveryId: string + pickupAddress: string + pickupPhoneNumber: string + pickupBusinessName: string + dropoffAddress: string + dropoffPhoneNumber: string + dropoffBusinessName: string + orderValue: string + pickupInstructions?: string + dropoffInstructions?: string + tip?: string + dropoffContactSendNotifications?: string + actionIfUndeliverable?: string + contactlessDropoff?: string + dropoffRequiresSignature?: string + dropoffContactGivenName?: string + dropoffContactFamilyName?: string + pickupTime?: string + dropoffTime?: string +} + +export interface DoordashGetDeliveryParams extends DoordashBaseParams { + externalDeliveryId: string +} + +export interface DoordashUpdateDeliveryParams extends DoordashBaseParams { + externalDeliveryId: string + tip?: string + dropoffPhoneNumber?: string + dropoffInstructions?: string +} + +export interface DoordashCancelDeliveryParams extends DoordashBaseParams { + externalDeliveryId: string +} + +export interface DoordashQuoteResponse extends ToolResponse { + output: { + externalDeliveryId: string + deliveryStatus: string + fee: number | null + currency: string | null + pickupTimeEstimated: string | null + dropoffTimeEstimated: string | null + } +} + +export interface DoordashDeliveryResponse extends ToolResponse { + output: { + externalDeliveryId: string + deliveryStatus: string + fee: number | null + tip: number | null + orderValue: number | null + currency: string | null + trackingUrl: string | null + supportReference: string | null + dasherName: string | null + dasherId: number | null + contactlessDropoff: boolean | null + dropoffVerificationImageUrl: string | null + cancellationReason: string | null + pickupTimeEstimated: string | null + pickupTimeActual: string | null + dropoffTimeEstimated: string | null + dropoffTimeActual: string | null + pickupAddress: string | null + dropoffAddress: string | null + updatedAt: string | null + } +} + +export interface DoordashCancelResponse extends ToolResponse { + output: { + externalDeliveryId: string + deliveryStatus: string + } +} + +export const QUOTE_OUTPUT_PROPERTIES = { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status (e.g., quote)' }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + currency: { type: 'string', description: 'Fee currency code (e.g., USD)' }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time (ISO 8601)' }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time (ISO 8601)' }, +} as const satisfies Record + +export const DELIVERY_OUTPUT_PROPERTIES = { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { + type: 'string', + description: + 'Delivery status (quote, created, scheduled, assigned, picked_up, delivered, cancelled, returned)', + }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + tip: { type: 'number', description: 'Tip amount in cents', optional: true }, + orderValue: { type: 'number', description: 'Order value in cents' }, + currency: { type: 'string', description: 'Fee currency code (e.g., USD)' }, + trackingUrl: { type: 'string', description: 'Delivery tracking URL' }, + supportReference: { type: 'string', description: 'Support reference ID' }, + dasherName: { type: 'string', description: 'Assigned Dasher name', optional: true }, + dasherId: { type: 'number', description: 'Assigned Dasher ID', optional: true }, + contactlessDropoff: { type: 'boolean', description: 'Whether contactless dropoff was used', optional: true }, + dropoffVerificationImageUrl: { type: 'string', description: 'Photo verification URL at dropoff', optional: true }, + cancellationReason: { type: 'string', description: 'Reason for cancellation', optional: true }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time (ISO 8601)' }, + pickupTimeActual: { + type: 'string', + description: 'Actual pickup time (ISO 8601)', + optional: true, + }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time (ISO 8601)' }, + dropoffTimeActual: { + type: 'string', + description: 'Actual dropoff time (ISO 8601)', + optional: true, + }, + pickupAddress: { type: 'string', description: 'Pickup address' }, + dropoffAddress: { type: 'string', description: 'Dropoff address' }, + updatedAt: { type: 'string', description: 'Last updated timestamp', optional: true }, +} as const satisfies Record + +export interface DoordashCreateBusinessParams extends DoordashBaseParams { + externalBusinessId: string + name: string + description?: string +} + +export interface DoordashListBusinessesParams extends DoordashBaseParams {} + +export interface DoordashUpdateBusinessParams extends DoordashBaseParams { + externalBusinessId: string + name?: string + description?: string +} + +export interface DoordashCreateStoreParams extends DoordashBaseParams { + externalBusinessId: string + externalStoreId: string + name: string + phoneNumber: string + address: string +} + +export interface DoordashListStoresParams extends DoordashBaseParams { + externalBusinessId: string +} + +export interface DoordashGetStoreParams extends DoordashBaseParams { + externalBusinessId: string + externalStoreId: string +} + +export interface DoordashUpdateStoreParams extends DoordashBaseParams { + externalBusinessId: string + externalStoreId: string + name?: string + phoneNumber?: string + address?: string +} + +export interface DoordashBusinessResponse extends ToolResponse { + output: { + externalBusinessId: string + name: string + description: string | null + activationStatus: string | null + } +} + +export interface DoordashBusinessListResponse extends ToolResponse { + output: { + businesses: Array<{ + externalBusinessId: string + name: string + description: string | null + activationStatus: string | null + }> + } +} + +export interface DoordashStoreResponse extends ToolResponse { + output: { + externalStoreId: string + name: string + phoneNumber: string | null + address: string | null + } +} + +export interface DoordashStoreListResponse extends ToolResponse { + output: { + stores: Array<{ + externalStoreId: string + name: string + phoneNumber: string | null + address: string | null + }> + } +} diff --git a/apps/sim/tools/doordash/update_business.ts b/apps/sim/tools/doordash/update_business.ts new file mode 100644 index 00000000000..461c14bb41a --- /dev/null +++ b/apps/sim/tools/doordash/update_business.ts @@ -0,0 +1,81 @@ +import type { DoordashBusinessResponse, DoordashUpdateBusinessParams } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const updateBusinessTool: ToolConfig = { + id: 'doordash_update_business', + name: 'DoorDash Update Business', + description: 'Updates a business entity name or description.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { type: 'string', required: true, visibility: 'user-only', description: 'DoorDash Key ID' }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalBusinessId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Business ID to update', + }, + name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated business name', + }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated business description', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'update_business', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalBusinessId: params.externalBusinessId, + name: params.name, + description: params.description, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to update business' } } + } + return { + success: true, + output: { + externalBusinessId: data.output.externalBusinessId ?? '', + name: data.output.name ?? '', + description: data.output.description ?? null, + activationStatus: data.output.activationStatus ?? null, + }, + } + }, + + outputs: { + externalBusinessId: { type: 'string', description: 'Business ID' }, + name: { type: 'string', description: 'Business name' }, + description: { type: 'string', description: 'Business description', optional: true }, + activationStatus: { type: 'string', description: 'Activation status', optional: true }, + }, +} diff --git a/apps/sim/tools/doordash/update_delivery.ts b/apps/sim/tools/doordash/update_delivery.ts new file mode 100644 index 00000000000..bbfb188158b --- /dev/null +++ b/apps/sim/tools/doordash/update_delivery.ts @@ -0,0 +1,133 @@ +import type { + DoordashDeliveryResponse, + DoordashUpdateDeliveryParams, +} from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const updateDeliveryTool: ToolConfig< + DoordashUpdateDeliveryParams, + DoordashDeliveryResponse +> = { + id: 'doordash_update_delivery', + name: 'DoorDash Update Delivery', + description: 'Updates a delivery. Only tip and dropoff details can be modified after creation.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Key ID', + }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalDeliveryId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'External delivery ID to update', + }, + tip: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated tip amount in cents', + }, + dropoffPhoneNumber: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated dropoff phone number', + }, + dropoffInstructions: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated dropoff instructions', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'update_delivery', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalDeliveryId: params.externalDeliveryId, + tip: params.tip, + dropoffPhoneNumber: params.dropoffPhoneNumber, + dropoffInstructions: params.dropoffInstructions, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to update delivery' } } + } + + return { + success: true, + output: { + externalDeliveryId: data.output.externalDeliveryId ?? '', + deliveryStatus: data.output.deliveryStatus ?? '', + fee: data.output.fee ?? null, + tip: data.output.tip ?? null, + orderValue: data.output.orderValue ?? null, + currency: data.output.currency ?? null, + trackingUrl: data.output.trackingUrl ?? null, + supportReference: data.output.supportReference ?? null, + dasherName: data.output.dasherName ?? null, + dasherId: data.output.dasherId ?? null, + contactlessDropoff: data.output.contactlessDropoff ?? null, + dropoffVerificationImageUrl: data.output.dropoffVerificationImageUrl ?? null, + cancellationReason: data.output.cancellationReason ?? null, + pickupTimeEstimated: data.output.pickupTimeEstimated ?? null, + pickupTimeActual: data.output.pickupTimeActual ?? null, + dropoffTimeEstimated: data.output.dropoffTimeEstimated ?? null, + dropoffTimeActual: data.output.dropoffTimeActual ?? null, + pickupAddress: data.output.pickupAddress ?? null, + dropoffAddress: data.output.dropoffAddress ?? null, + updatedAt: data.output.updatedAt ?? null, + }, + } + }, + + outputs: { + externalDeliveryId: { type: 'string', description: 'External delivery ID' }, + deliveryStatus: { type: 'string', description: 'Delivery status' }, + fee: { type: 'number', description: 'Delivery fee in cents' }, + tip: { type: 'number', description: 'Tip amount in cents', optional: true }, + orderValue: { type: 'number', description: 'Order value in cents' }, + currency: { type: 'string', description: 'Fee currency code' }, + trackingUrl: { type: 'string', description: 'Delivery tracking URL' }, + supportReference: { type: 'string', description: 'Support reference ID' }, + dasherName: { type: 'string', description: 'Assigned Dasher name', optional: true }, + dasherId: { type: 'number', description: 'Assigned Dasher ID', optional: true }, + contactlessDropoff: { type: 'boolean', description: 'Whether contactless dropoff was used', optional: true }, + dropoffVerificationImageUrl: { type: 'string', description: 'Photo verification URL at dropoff', optional: true }, + cancellationReason: { type: 'string', description: 'Reason for cancellation', optional: true }, + pickupTimeEstimated: { type: 'string', description: 'Estimated pickup time' }, + pickupTimeActual: { type: 'string', description: 'Actual pickup time', optional: true }, + dropoffTimeEstimated: { type: 'string', description: 'Estimated dropoff time' }, + dropoffTimeActual: { type: 'string', description: 'Actual dropoff time', optional: true }, + pickupAddress: { type: 'string', description: 'Pickup address' }, + dropoffAddress: { type: 'string', description: 'Dropoff address' }, + updatedAt: { type: 'string', description: 'Last updated timestamp', optional: true }, + }, +} diff --git a/apps/sim/tools/doordash/update_store.ts b/apps/sim/tools/doordash/update_store.ts new file mode 100644 index 00000000000..3dffc414935 --- /dev/null +++ b/apps/sim/tools/doordash/update_store.ts @@ -0,0 +1,95 @@ +import type { DoordashStoreResponse, DoordashUpdateStoreParams } from '@/tools/doordash/types' +import type { ToolConfig } from '@/tools/types' + +export const updateStoreTool: ToolConfig = { + id: 'doordash_update_store', + name: 'DoorDash Update Store', + description: 'Updates a store location name, phone number, or address.', + version: '1.0.0', + + params: { + developerId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Developer ID', + }, + keyId: { type: 'string', required: true, visibility: 'user-only', description: 'DoorDash Key ID' }, + signingSecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'DoorDash Signing Secret', + }, + externalBusinessId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Parent business ID', + }, + externalStoreId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Store ID to update', + }, + name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated store name', + }, + phoneNumber: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated phone number', + }, + address: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated address', + }, + }, + + request: { + url: '/api/tools/doordash', + method: 'POST', + headers: () => ({ 'Content-Type': 'application/json' }), + body: (params) => ({ + operation: 'update_store', + developerId: params.developerId, + keyId: params.keyId, + signingSecret: params.signingSecret, + externalBusinessId: params.externalBusinessId, + externalStoreId: params.externalStoreId, + name: params.name, + phoneNumber: params.phoneNumber, + address: params.address, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!data.success) { + return { success: false, output: { error: data.error ?? 'Failed to update store' } } + } + return { + success: true, + output: { + externalStoreId: data.output.externalStoreId ?? '', + name: data.output.name ?? '', + phoneNumber: data.output.phoneNumber ?? null, + address: data.output.address ?? null, + }, + } + }, + + outputs: { + externalStoreId: { type: 'string', description: 'Store ID' }, + name: { type: 'string', description: 'Store name' }, + phoneNumber: { type: 'string', description: 'Store phone number' }, + address: { type: 'string', description: 'Store address' }, + }, +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 66d70a07f7b..262dcb33f23 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -392,6 +392,21 @@ import { docusignSendEnvelopeTool, docusignVoidEnvelopeTool, } from '@/tools/docusign' +import { + doordashAcceptQuoteTool, + doordashCancelDeliveryTool, + doordashCreateBusinessTool, + doordashCreateDeliveryTool, + doordashCreateQuoteTool, + doordashCreateStoreTool, + doordashGetDeliveryTool, + doordashGetStoreTool, + doordashListBusinessesTool, + doordashListStoresTool, + doordashUpdateBusinessTool, + doordashUpdateDeliveryTool, + doordashUpdateStoreTool, +} from '@/tools/doordash' import { dropboxCopyTool, dropboxCreateFolderTool, @@ -4050,6 +4065,19 @@ export const tools: Record = { docusign_list_templates: docusignListTemplatesTool, docusign_send_envelope: docusignSendEnvelopeTool, docusign_void_envelope: docusignVoidEnvelopeTool, + doordash_accept_quote: doordashAcceptQuoteTool, + doordash_cancel_delivery: doordashCancelDeliveryTool, + doordash_create_business: doordashCreateBusinessTool, + doordash_create_delivery: doordashCreateDeliveryTool, + doordash_create_quote: doordashCreateQuoteTool, + doordash_create_store: doordashCreateStoreTool, + doordash_get_delivery: doordashGetDeliveryTool, + doordash_get_store: doordashGetStoreTool, + doordash_list_businesses: doordashListBusinessesTool, + doordash_list_stores: doordashListStoresTool, + doordash_update_business: doordashUpdateBusinessTool, + doordash_update_delivery: doordashUpdateDeliveryTool, + doordash_update_store: doordashUpdateStoreTool, datadog_submit_metrics: datadogSubmitMetricsTool, datadog_query_timeseries: datadogQueryTimeseriesTool, datadog_create_event: datadogCreateEventTool,