Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
{
"extends": "plugin:@taskade/base",
"settings": {
"import/resolver": {
"node": {
"extensions": [
".js",
".jsx",
".ts",
".tsx"
]
}
}
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2021,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"env": {
"node": true,
"es2021": true
},
"ignorePatterns": ["lib/", "build/", "node_modules/", "packages/"],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }]
}
}
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ jobs:
node-version: 20
cache: yarn
- run: yarn install --frozen-lockfile
- run: yarn lint
- run: yarn build
- run: yarn test
55 changes: 55 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Contributing

Thanks for helping extend Taskade's reach. This repo is the public source-of-truth for Taskade actions & triggers, so improvements here ripple out to every platform.

## Quick start

The repo installs with **no auth and no private registries** — clone, build, and test in one go:

```bash
git clone https://github.com/taskade/integrations.git
cd integrations
yarn install
yarn lint # eslint (public config)
yarn build # tsc -> lib/
yarn test # builds, then validates against Zapier's official schema
```

All four should pass before you open a PR. CI runs the same steps.

## Layout

| Path | What |
| --- | --- |
| [`src/`](src) | The Zapier app — `creates/`, `searches/`, `triggers/`, plus `authentication.ts` / `client.ts` / `fields.ts` |
| [`src/index.ts`](src/index.ts) | Registers every operation into the app definition |
| [`src/test/app.test.ts`](src/test/app.test.ts) | Schema-validates the whole app (`zapier-platform-schema`) |
| [`packages/n8n-nodes-taskade/`](packages/n8n-nodes-taskade) | The official n8n community node |

## The contract: the public API

Every operation must run against the **documented public API** — no internal/undocumented routes. That portability is the whole point.

- **v1 REST** — [spec](https://www.taskade.com/api/documentation/v1/json) · full task/project CRUD
- **v2 Action** — [spec](https://www.taskade.com/api/documentation/v2/json) · action-based, AI-agent prompting
- Auth: OAuth2 or a [Personal Access Token](https://www.taskade.com/settings/api)

If you need an endpoint that isn't public yet, open an issue on [taskade/taskade](https://github.com/taskade/taskade/issues) rather than reaching for an internal route.

## Adding a Zapier operation

1. Add a file under `src/creates/`, `src/searches/`, or `src/triggers/` exporting an operation object (`key`, `noun`, `display`, `operation`).
2. Import and register it in [`src/index.ts`](src/index.ts).
3. `yarn test` — the schema validator will catch a malformed definition before deploy.

## Adding a new platform

Building Taskade for Activepieces, Make, Pipedream, or somewhere new? Open a PR — a `packages/<platform>-taskade/` package alongside the n8n node is the pattern. Reuse the public API calls in `src/` as the reference implementation.

## Pull requests

- Keep PRs focused; conventional-commit titles (`feat(…)`, `fix(…)`, `docs(…)`) are appreciated.
- Green CI (`lint` + `build` + `test`) is required.
- Deploying to the live Zapier app is a separate, deliberate, manual step (`zapier push`) — never automatic on merge.

Questions or ideas? [Open an issue](https://github.com/taskade/integrations/issues).
82 changes: 64 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,57 @@
# Taskade Integrations
<div align="center">

The public source-of-truth for Taskade actions & triggers across automation platforms — starting with the official [Zapier integration](https://zapier.com/apps/taskade/integrations), built entirely on the [Taskade public API](https://docs.taskade.com/).
# Taskade Integration Kit

Building a Taskade integration for another platform (n8n, Activepieces, Make, Pipedream, or your own)? Everything here runs against the documented public API — copy freely. Live OpenAPI specs:
**The public source-of-truth for Taskade actions & triggers — across Zapier, n8n, Activepieces, Make, Pipedream, and anything you build.**

- v1 REST API: `https://www.taskade.com/api/v1` — [spec](https://www.taskade.com/api/documentation/v1/json)
- v2 Action API: `https://www.taskade.com/api/v2` — [spec](https://www.taskade.com/api/documentation/v2/json)
Every integration here runs on the documented [Taskade public API](https://docs.taskade.com). Copy freely.

## Packages
<br>

- [`packages/n8n-nodes-taskade`](packages/n8n-nodes-taskade) — official n8n community node for Taskade, built in this repo
[![Zapier](https://img.shields.io/badge/Zapier-live-FF4A00?style=flat-square&logo=zapier&logoColor=white)](https://zapier.com/apps/taskade/integrations)
[![CI](https://github.com/taskade/integrations/actions/workflows/ci.yml/badge.svg)](https://github.com/taskade/integrations/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-3DA639?style=flat-square)](LICENSE)
[![API Docs](https://img.shields.io/badge/API_Docs-docs.taskade.com-333?style=flat-square)](https://docs.taskade.com)

</div>

---

## Why this exists

[Taskade](https://www.taskade.com) is the **AI-native workspace platform** — projects that remember, agents that think, automations that execute. **[Taskade Genesis](https://www.taskade.com/genesis)** turns one prompt into a live app with all three.

This kit is how that workspace reaches the **outside world**: the actions and triggers that let a Taskade automation (or a Genesis app) create tasks, run an AI agent, or fire on an event in Zapier, n8n, and beyond. One documented API surface, many platforms.

## Part of the Taskade ecosystem

| Repo | What it is |
| --- | --- |
| **[taskade/taskade](https://github.com/taskade/taskade)** | The platform home — the AI-native workspace, **Genesis** app builder, and where to file bugs & feature requests |
| **[taskade/mcp](https://github.com/taskade/mcp)** | Official **MCP server** + OpenAPI→MCP generator — wire Taskade into any AI tool ([`@taskade/mcp-server`](https://www.npmjs.com/package/@taskade/mcp-server)) |
| **[taskade/docs](https://github.com/taskade/docs)** | Source for [docs.taskade.com](https://docs.taskade.com) — the API reference & guides |
| **[taskade/awesome-vibe-coding](https://github.com/taskade/awesome-vibe-coding)** | The complete guide to building software by prompt |
| **[taskade/taskade-sample-app](https://github.com/taskade/taskade-sample-app)** | Genesis App Kit — a Workspace DNA template to build from |
| **taskade/integrations** | 👈 you are here — the integration kit |

## Platforms

| Platform | Status | Where |
| --- | --- | --- |
| **Zapier** | ✅ Live | [zapier.com/apps/taskade](https://zapier.com/apps/taskade/integrations) — source in [`src/`](src) |
| **n8n** | ✅ Source here · npm publish pending | [`packages/n8n-nodes-taskade`](packages/n8n-nodes-taskade) — official community node |
| **Other platforms** | 🔧 Build on the API | Activepieces, Make, Pipedream, or your own — everything below runs against the public API, copy freely |

## Zapier app capabilities

| Type | Key | What it does |
|---|---|---|
| Trigger | `task_due` | Fires when a task is due (instant/webhook) |
| Action | `create_task` | Create a task — with due date, assignee; content > 2000 chars auto-chunks into sibling tasks |
| Trigger | `task_due` | Fires when a task is due (instant / webhook) |
| Action | `create_task` | Create a task — due date, assignee; content > 2000 chars auto-chunks into sibling tasks |
| Action | `complete_task` | Mark a task complete, or reopen it |
| Action | `update_task` | Update a task's content |
| Action | `delete_task` | Delete a task |
| Action | `move_task` | Reorder/reparent a task within a project |
| Action | `move_task` | Reorder / reparent a task within a project |
| Action | `create_project` | Create a project from Markdown |
| Action | `create_project_from_template` | Create a project from a template |
| Action | `run_agent` | Prompt a Taskade AI agent, get its response (v2 `promptAgent`) |
Expand All @@ -30,16 +61,24 @@ Building a Taskade integration for another platform (n8n, Activepieces, Make, Pi

Hidden dropdown helpers (not user-facing): `get_all_spaces`, `get_all_projects`, `get_all_blocks`, `get_all_assignable_members`, `get_all_tasks`, `get_all_project_templates`.

Auth: OAuth2 (`www.taskade.com/oauth2/*`). The API also supports [Personal Access Tokens](https://www.taskade.com/settings/api) (`Authorization: Bearer tskdp_…`) for other platforms.
## Built on the public API

Two live OpenAPI surfaces — both documented, both yours to build on:

- **v1 REST API** — `https://www.taskade.com/api/v1` · [spec](https://www.taskade.com/api/documentation/v1/json) — full task CRUD, projects, members.
- **v2 Action API** — `https://www.taskade.com/api/v2` · [spec](https://www.taskade.com/api/documentation/v2/json) — action-based (`/listSpaces`, `/promptAgent`, …), adds AI-agent prompting.

**Auth:** the Zapier app connects via **OAuth2** (click *Connect* — no token to copy). For direct API calls, the n8n node, or your own integration, use a [Personal Access Token](https://www.taskade.com/settings/api) (`Authorization: Bearer tskdp_…`).

> Note: the `task_due` trigger currently uses Taskade-internal webhook routes. A public webhook-subscription API (`POST /api/v2/subscribeWebhook`) is in progress — once live, event triggers become portable to any platform.
**Event subscriptions (Beta):** `POST /api/v2/subscribeWebhook` registers a `targetUrl` for an event (`task.due` today) and returns a `hookId`; `POST /api/v2/unsubscribeWebhook` removes it. Available on **Pro and above**. This is the portable surface the `task_due` trigger uses — see [Programmatic Webhook Subscriptions](https://docs.taskade.com/apis-living-system-development/webhooks).

## Development

Prerequisites: Node ≥ 18, Yarn, [Zapier CLI](https://docs.zapier.com/platform/build-cli/overview#quick-setup-guide).

```bash
yarn install
yarn lint # eslint (public config — no private packages)
yarn build # tsc -> lib/
yarn test # builds, then validates the app against Zapier's official schema
```
Expand All @@ -63,13 +102,20 @@ zapier logs --type=http --detailed

## Roadmap

- Platform-agnostic operation manifest + per-platform codegen — the existing [n8n node](packages/n8n-nodes-taskade) and future targets (Activepieces, Make, Pipedream) rendered from one source
- Portable event triggers once the public webhook-subscription API ships
- Platform-agnostic operation manifest + per-platform codegen — the existing [n8n node](packages/n8n-nodes-taskade) and future targets (Activepieces, Make, Pipedream) rendered from one source.
- More portable event triggers as additional events light up on the public subscription API (`task.completed`, `task.assigned`, …).

See the [Zapier Integration Guide](https://help.taskade.com/en/articles/8958540-zapier-integration) for end-user docs.

## Related repos
## Contributing

Building a Taskade integration for another platform, or improving an existing one? **[CONTRIBUTING.md](CONTRIBUTING.md)** has the quick start — and now that the repo installs with no auth and no private registries, you can clone, build, and test in one go.

## License

[MIT](LICENSE) — © Taskade.

- [Taskade Docs](https://github.com/taskade/docs) — source for [docs.taskade.com](https://docs.taskade.com)
- [Taskade MCP](https://github.com/taskade/mcp) — official MCP server ([`@taskade/mcp-server`](https://www.npmjs.com/package/@taskade/mcp-server) on npm)
- [Taskade](https://github.com/taskade/taskade) — platform home, including the Genesis AI app builder
<div align="center">
<br>
⭐ <b>Find this useful? <a href="https://github.com/taskade/integrations">Star the repo</a></b> and build the next integration.
</div>
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"name": "taskade",
"version": "1.1.0",
"version": "1.2.0",
"description": "Taskade is a collaboration platform for remote teams to organize and manage projects.",
"main": "index.js",
"scripts": {
"test": "npm run build && jest --testTimeout 10000 --rootDir ./lib/test",
"build": "npm run clean && tsc",
"clean": "rimraf ./lib ./build",
"watch": "npm run clean && tsc --watch"
"watch": "npm run clean && tsc --watch",
"lint": "eslint src --ext .ts"
},
"engines": {
"node": ">=v18",
"npm": ">=5.6.0"
},
"dependencies": {
"@taskade/eslint-plugin": "0.4.0",
"cross-fetch": "^3.1.5",
"moment": "^2.29.1",
"moment-timezone": "^0.5.37",
Expand All @@ -24,6 +24,9 @@
"@types/jest": "^26.0.23",
"@types/node": "^18.12.0",
"@types/node-fetch": "^2.6.12",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"eslint": "^8.57.0",
"jest": "^26.6.3",
"rimraf": "^3.0.2",
"typescript": "5.3.3",
Expand Down
37 changes: 19 additions & 18 deletions src/triggers/taskDue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const perform = async (z: ZObject, bundle: Bundle) => {
return [payload];
};

// performList still uses the internal route — the public Action API v2 does not
// yet expose a "list recent due tasks" sample endpoint. Subscribe/unsubscribe are
// fully on the public API; this remains until a public sample endpoint ships.
const performList = async (z: ZObject, bundle: Bundle) => {
const options: HttpRequestOptions = {
url: 'https://www.taskade.com/webhooks/zapier/taskdue/performlist',
Expand All @@ -45,53 +48,51 @@ const performList = async (z: ZObject, bundle: Bundle) => {
});
};

// Subscribe via the public Action API v2 (POST /api/v2/subscribeWebhook).
// Account-level only: the public endpoint takes { targetUrl, triggerType } and
// ignores scope, so the space/project inputs do not narrow the subscription yet
// (they remain for forward-compatibility once scoped subscriptions ship).
// Requires a paid plan (Pro+); free/Starter accounts receive 402.
const performSubscribe = async (z: ZObject, bundle: Bundle) => {
const options: HttpRequestOptions = {
url: 'https://www.taskade.com/webhooks/zapier/subscribe',
url: 'https://www.taskade.com/api/v2/subscribeWebhook',
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${bundle.authData.access_token}`,
},
params: {},
body: {
hookUrl: bundle.targetUrl,
triggerType: 'TaskDue',
spaceId: bundle.inputData.space_id != null ? bundle.inputData.space_id : null,
projectId: bundle.inputData.project_id != null ? bundle.inputData.project_id : null,
targetUrl: bundle.targetUrl,
triggerType: 'task.due',
},
};

return z
.request('https://www.taskade.com/webhooks/zapier/subscribe', options)
.request('https://www.taskade.com/api/v2/subscribeWebhook', options)
.then((response) => {
response.throwForStatus();
const results = response.json;

// You can do any parsing you need for results here before returning them

return results;
// { ok: true, hookId } — hookId is read back in performUnsubscribe via bundle.subscribeData.
return response.json;
});
};

const performUnsubscribe = async (z: ZObject, bundle: Bundle) => {
const options: HttpRequestOptions = {
url: 'https://www.taskade.com/webhooks/zapier/unsubscribe',
method: 'DELETE',
url: 'https://www.taskade.com/api/v2/unsubscribeWebhook',
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${bundle.authData.access_token}`,
},
params: {
// @ts-ignore
body: {
// @ts-ignore - subscribeData carries the hookId returned by performSubscribe
hookId: bundle.subscribeData.hookId,
},
};

return z.request('https://www.taskade.com/webhooks/zapier/unsubscribe', options);
// return z.request(options).then((response) => z.JSON.parse(response.content));
return z.request('https://www.taskade.com/api/v2/unsubscribeWebhook', options);
};

export default {
Expand Down
Loading
Loading