Add Activepieces integration for workflow automation

- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,3 @@
{
"presets": [["@nx/js/babel", { "useBuiltIns": "usage" }]]
}

View File

@@ -0,0 +1,18 @@
{
"extends": ["../../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# pieces-google-tasks
This library was generated with [Nx](https://nx.dev).
## Running lint
Run `nx lint pieces-google-tasks` to execute the lint via [ESLint](https://eslint.org/).

View File

@@ -0,0 +1,4 @@
{
"name": "@activepieces/piece-google-tasks",
"version": "0.3.13"
}

View File

@@ -0,0 +1,51 @@
{
"name": "pieces-google-tasks",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/google-tasks/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": [
"{options.outputPath}"
],
"options": {
"outputPath": "dist/packages/pieces/community/google-tasks",
"tsConfig": "packages/pieces/community/google-tasks/tsconfig.lib.json",
"packageJson": "packages/pieces/community/google-tasks/package.json",
"main": "packages/pieces/community/google-tasks/src/index.ts",
"assets": [
"packages/pieces/community/google-tasks/*.md",
{
"input": "packages/pieces/community/google-tasks/src/i18n",
"output": "./src/i18n",
"glob": "**/!(i18n.json)"
}
],
"buildableProjectDepsInPackageJsonType": "dependencies",
"updateBuildableProjectDepsInPackageJson": true
},
"dependsOn": [
"^build",
"prebuild"
]
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}"
]
},
"prebuild": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/pieces/community/google-tasks",
"command": "bun install --no-save --silent"
},
"dependsOn": [
"^build"
]
}
},
"tags": []
}

View File

@@ -0,0 +1,30 @@
{
"Google Tasks": "Google Tasks",
"Task list management application": "Task list management application",
"Add Task": "Add Task",
"Custom API Call": "Custom API Call",
"Add a new task to a specified task list": "Add a new task to a specified task list",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Tasks List": "Tasks List",
"Title": "Title",
"Notes": "Notes",
"Due Date": "Due Date",
"Completed": "Completed",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"Due date of the task (YYYY-MM-DD)": "Due date of the task (YYYY-MM-DD)",
"Mark task as completed": "Mark task as completed",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Task": "New Task",
"Triggers when a task is created": "Triggers when a task is created"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "Anwendung zur Verwaltung der Aufgabenliste",
"Add Task": "Neue Aufgabe",
"Custom API Call": "Eigener API-Aufruf",
"Add a new task to a specified task list": "Neue Aufgabe einer bestimmten Aufgabenliste hinzufügen",
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
"Tasks List": "Aufgabenliste",
"Title": "Titel",
"Notes": "Notizen",
"Due Date": "Fälligkeitsdatum",
"Completed": "Abgeschlossen",
"Method": "Methode",
"Headers": "Kopfzeilen",
"Query Parameters": "Abfrageparameter",
"Body": "Körper",
"Response is Binary ?": "Antwort ist binär?",
"No Error on Failure": "Kein Fehler bei Fehler",
"Timeout (in seconds)": "Timeout (in Sekunden)",
"Due date of the task (YYYY-MM-DD)": "Fälligkeitsdatum der Aufgabe (JJJJ-MM-TT)",
"Mark task as completed": "Aufgabe als erledigt markieren",
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
"GET": "ERHALTEN",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "LÖSCHEN",
"HEAD": "HEAD",
"New Task": "Neue Aufgabe",
"Triggers when a task is created": "Wird ausgelöst, wenn eine Aufgabe erstellt wird"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "Aplicación de gestión de listas de tareas",
"Add Task": "Añadir tarea",
"Custom API Call": "Llamada API personalizada",
"Add a new task to a specified task list": "Añadir una nueva tarea a una lista de tareas especificada",
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
"Tasks List": "Lista de tareas",
"Title": "Título",
"Notes": "Notas",
"Due Date": "Fecha de fin",
"Completed": "Completado",
"Method": "Método",
"Headers": "Encabezados",
"Query Parameters": "Parámetros de consulta",
"Body": "Cuerpo",
"Response is Binary ?": "¿Respuesta es binaria?",
"No Error on Failure": "No hay ningún error en fallo",
"Timeout (in seconds)": "Tiempo de espera (en segundos)",
"Due date of the task (YYYY-MM-DD)": "Fecha límite de la tarea (AAA-MM-DD)",
"Mark task as completed": "Marcar tarea como completada",
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
"GET": "RECOGER",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "BORRAR",
"HEAD": "LIMPIO",
"New Task": "Nueva tarea",
"Triggers when a task is created": "Dispara cuando se crea una tarea"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "Application de gestion de la liste des tâches",
"Add Task": "Ajouter une tâche",
"Custom API Call": "Appel API personnalisé",
"Add a new task to a specified task list": "Ajouter une nouvelle tâche à une liste de tâches spécifiée",
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
"Tasks List": "Liste des tâches",
"Title": "Titre de la page",
"Notes": "Notes",
"Due Date": "Date de fin",
"Completed": "Terminé",
"Method": "Méthode",
"Headers": "En-têtes",
"Query Parameters": "Paramètres de requête",
"Body": "Corps",
"Response is Binary ?": "La réponse est Binaire ?",
"No Error on Failure": "Aucune erreur en cas d'échec",
"Timeout (in seconds)": "Délai d'attente (en secondes)",
"Due date of the task (YYYY-MM-DD)": "Date d'échéance de la tâche (AAAAA-MM-JJ)",
"Mark task as completed": "Marquer la tâche comme terminée",
"Authorization headers are injected automatically from your connection.": "Les en-têtes d'autorisation sont injectés automatiquement à partir de votre connexion.",
"Enable for files like PDFs, images, etc..": "Activer pour les fichiers comme les PDFs, les images, etc.",
"GET": "OBTENIR",
"POST": "POSTER",
"PATCH": "PATCH",
"PUT": "EFFACER",
"DELETE": "SUPPRIMER",
"HEAD": "TÊTE",
"New Task": "Nouvelle tâche",
"Triggers when a task is created": "Déclenche quand une tâche est créée"
}

View File

@@ -0,0 +1,30 @@
{
"Google Tasks": "Google Tasks",
"Task list management application": "Task list management application",
"Add Task": "Add Task",
"Custom API Call": "Custom API Call",
"Add a new task to a specified task list": "Add a new task to a specified task list",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Tasks List": "Tasks List",
"Title": "Title",
"Notes": "Notes",
"Due Date": "Due Date",
"Completed": "Completed",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"Due date of the task (YYYY-MM-DD)": "Due date of the task (YYYY-MM-DD)",
"Mark task as completed": "Mark task as completed",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Task": "New Task",
"Triggers when a task is created": "Triggers when a task is created"
}

View File

@@ -0,0 +1,30 @@
{
"Google Tasks": "Google Tasks",
"Task list management application": "Task list management application",
"Add Task": "Add Task",
"Custom API Call": "Custom API Call",
"Add a new task to a specified task list": "Add a new task to a specified task list",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Tasks List": "Tasks List",
"Title": "Title",
"Notes": "Notes",
"Due Date": "Due Date",
"Completed": "Completed",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"Due date of the task (YYYY-MM-DD)": "Due date of the task (YYYY-MM-DD)",
"Mark task as completed": "Mark task as completed",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Task": "New Task",
"Triggers when a task is created": "Triggers when a task is created"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "タスクリスト管理アプリケーション",
"Add Task": "タスクを追加",
"Custom API Call": "カスタムAPI通話",
"Add a new task to a specified task list": "指定されたタスクリストに新しいタスクを追加",
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
"Tasks List": "タスク リスト",
"Title": "タイトル",
"Notes": "メモ",
"Due Date": "締切日",
"Completed": "完了",
"Method": "方法",
"Headers": "ヘッダー",
"Query Parameters": "クエリパラメータ",
"Body": "本文",
"Response is Binary ?": "応答はバイナリですか?",
"No Error on Failure": "失敗時にエラーはありません",
"Timeout (in seconds)": "タイムアウト(秒)",
"Due date of the task (YYYY-MM-DD)": "タスクの期限 (YYYY-MM-DD)",
"Mark task as completed": "タスクを完了としてマーク",
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
"GET": "取得",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "削除",
"HEAD": "頭",
"New Task": "新しいタスク",
"Triggers when a task is created": "タスクが作成されたときにトリガーします"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "Taaklijst beheer applicatie",
"Add Task": "Taak toevoegen",
"Custom API Call": "Custom API Call",
"Add a new task to a specified task list": "Een nieuwe taak toevoegen aan een opgegeven takenlijst",
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
"Tasks List": "Taken Lijst",
"Title": "Aanspreektitel",
"Notes": "Opmerkingen",
"Due Date": "Inleverdatum",
"Completed": "Voltooid",
"Method": "Methode",
"Headers": "Kopteksten",
"Query Parameters": "Query parameters",
"Body": "Lichaam",
"Response is Binary ?": "Antwoord is binair?",
"No Error on Failure": "Geen fout bij fout",
"Timeout (in seconds)": "Time-out (in seconden)",
"Due date of the task (YYYY-MM-DD)": "Vervaldatum van de taak (JJJJ-MM-DD)",
"Mark task as completed": "Markeer taak als voltooid",
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
"GET": "KRIJG",
"POST": "POSTE",
"PATCH": "BEKIJK",
"PUT": "PUT",
"DELETE": "VERWIJDEREN",
"HEAD": "HOOFD",
"New Task": "Nieuwe taak",
"Triggers when a task is created": "Triggert wanneer een taak wordt aangemaakt"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "Gerenciamento de lista de tarefas",
"Add Task": "Adicionar tarefa",
"Custom API Call": "Chamada de API personalizada",
"Add a new task to a specified task list": "Adicionar uma nova tarefa a uma lista de tarefas especificada",
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
"Tasks List": "Lista Tarefas",
"Title": "Título",
"Notes": "Observações",
"Due Date": "Data de vencimento",
"Completed": "Concluído",
"Method": "Método",
"Headers": "Cabeçalhos",
"Query Parameters": "Parâmetros da consulta",
"Body": "Conteúdo",
"Response is Binary ?": "A resposta é binária ?",
"No Error on Failure": "Nenhum erro no Failure",
"Timeout (in seconds)": "Tempo limite (em segundos)",
"Due date of the task (YYYY-MM-DD)": "Data de vencimento da tarefa (AAAA-MM-DD)",
"Mark task as completed": "Marcar tarefa como concluída",
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
"GET": "OBTER",
"POST": "POSTAR",
"PATCH": "COMPRAR",
"PUT": "COLOCAR",
"DELETE": "EXCLUIR",
"HEAD": "CABEÇA",
"New Task": "Nova tarefa",
"Triggers when a task is created": "Dispara quando uma tarefa é criada"
}

View File

@@ -0,0 +1,30 @@
{
"Google Tasks": "Google Задачи",
"Task list management application": "Приложение для управления списком задач",
"Add Task": "Добавить задачу",
"Custom API Call": "Пользовательский вызов API",
"Add a new task to a specified task list": "Добавить новую задачу в указанный список задач",
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
"Tasks List": "Список задач",
"Title": "Заголовок",
"Notes": "Примечания",
"Due Date": "Срок сдачи",
"Completed": "Выполнено",
"Method": "Метод",
"Headers": "Заголовки",
"Query Parameters": "Параметры запроса",
"Body": "Тело",
"No Error on Failure": "Нет ошибок при ошибке",
"Timeout (in seconds)": "Таймаут (в секундах)",
"Due date of the task (YYYY-MM-DD)": "Дата выполнения задачи (ГГГГ-ММ-ДД)",
"Mark task as completed": "Пометить задачу как выполненную",
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD",
"New Task": "Новая задача",
"Triggers when a task is created": "Триггеры при создании задачи"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "Task list management application",
"Add Task": "Add Task",
"Custom API Call": "Custom API Call",
"Add a new task to a specified task list": "Add a new task to a specified task list",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Tasks List": "Tasks List",
"Title": "Title",
"Notes": "Notes",
"Due Date": "Due Date",
"Completed": "Completed",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"Due date of the task (YYYY-MM-DD)": "Due date of the task (YYYY-MM-DD)",
"Mark task as completed": "Mark task as completed",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Task": "New Task",
"Triggers when a task is created": "Triggers when a task is created"
}

View File

@@ -0,0 +1,30 @@
{
"Google Tasks": "Google Tasks",
"Task list management application": "Task list management application",
"Add Task": "Add Task",
"Custom API Call": "Custom API Call",
"Add a new task to a specified task list": "Add a new task to a specified task list",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Tasks List": "Tasks List",
"Title": "Title",
"Notes": "Notes",
"Due Date": "Due Date",
"Completed": "Completed",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"Due date of the task (YYYY-MM-DD)": "Due date of the task (YYYY-MM-DD)",
"Mark task as completed": "Mark task as completed",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Task": "New Task",
"Triggers when a task is created": "Triggers when a task is created"
}

View File

@@ -0,0 +1,31 @@
{
"Task list management application": "Task list management application",
"Add Task": "Add Task",
"Custom API Call": "自定义 API 呼叫",
"Add a new task to a specified task list": "Add a new task to a specified task list",
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
"Tasks List": "Tasks List",
"Title": "标题",
"Notes": "Notes",
"Due Date": "Due Date",
"Completed": "Completed",
"Method": "方法",
"Headers": "信头",
"Query Parameters": "查询参数",
"Body": "正文内容",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "失败时没有错误",
"Timeout (in seconds)": "超时(秒)",
"Due date of the task (YYYY-MM-DD)": "Due date of the task (YYYY-MM-DD)",
"Mark task as completed": "Mark task as completed",
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "获取",
"POST": "帖子",
"PATCH": "PATCH",
"PUT": "弹出",
"DELETE": "删除",
"HEAD": "黑色",
"New Task": "New Task",
"Triggers when a task is created": "Triggers when a task is created"
}

View File

@@ -0,0 +1,41 @@
import { createCustomApiCallAction } from '@activepieces/pieces-common';
import {
OAuth2PropertyValue,
PieceAuth,
createPiece,
} from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { googleTasksAddNewTaskAction } from './lib/actions/new-task';
import { googleTasksCommon } from './lib/common';
import { newTaskTrigger } from './lib/triggers/new-task';
export const googleTasksAuth = PieceAuth.OAuth2({
description: '',
authUrl: 'https://accounts.google.com/o/oauth2/auth',
tokenUrl: 'https://oauth2.googleapis.com/token',
required: true,
scope: ['https://www.googleapis.com/auth/tasks'],
});
export const googleTasks = createPiece({
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/google-tasks.png',
categories: [PieceCategory.PRODUCTIVITY],
actions: [
googleTasksAddNewTaskAction,
createCustomApiCallAction({
baseUrl: () => googleTasksCommon.baseUrl,
auth: googleTasksAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${(auth as OAuth2PropertyValue).access_token}`,
}),
}),
],
displayName: 'Google Tasks',
description: 'Task list management application',
authors: ["Salem-Alaa","kishanprmr","MoShizzle","khaledmashaly","abuaboud"],
triggers: [newTaskTrigger],
auth: googleTasksAuth,
});

View File

@@ -0,0 +1,33 @@
import { createAction } from '@activepieces/pieces-framework';
import { createTask, googleTasksCommon, Task, TaskStatus } from '../common';
import { googleTasksAuth } from '../../';
export const googleTasksAddNewTaskAction = createAction({
auth: googleTasksAuth,
name: 'add_task',
description: 'Add a new task to a specified task list',
displayName: 'Add Task',
props: {
tasks_list: googleTasksCommon.tasksList,
title: googleTasksCommon.title,
notes: googleTasksCommon.notes,
due: googleTasksCommon.due,
completed: googleTasksCommon.completed,
},
async run({ auth, propsValue }) {
const task: Task = {
kind: 'tasks#task',
status: propsValue.completed
? TaskStatus.COMPLETED
: TaskStatus.NEEDS_ACTION,
title: propsValue.title,
completed: propsValue.completed ? new Date().toISOString() : '',
notes: propsValue.notes,
due: propsValue.due
? `${new Date(propsValue.due).toISOString().split('T')[0]}T00:00:00Z`
: undefined,
};
return createTask(auth, propsValue.tasks_list!, task);
},
});

View File

@@ -0,0 +1,161 @@
import { Property, OAuth2PropertyValue } from '@activepieces/pieces-framework';
import {
HttpRequest,
HttpMethod,
AuthenticationType,
httpClient,
} from '@activepieces/pieces-common';
import { googleTasksAuth } from '../..';
export enum TaskStatus {
NEEDS_ACTION = 'needsAction',
COMPLETED = 'completed',
}
/**
* @see https://developers.google.com/tasks/reference/rest/v1/tasklists/list#response-body
*/
export type TasksListResponse = {
kind: string;
etag: string;
nextPageToken: string;
items: TasksList[];
};
/**
* @see https://developers.google.com/tasks/reference/rest/v1/tasklists#resource:-tasklist
*/
export type TasksList = {
kind: string;
id: string;
etag: string;
title: string;
updated: string;
selfLink: string;
};
/**
* @see https://developers.google.com/tasks/reference/rest/v1/tasks#resource:-task
*/
export type Task = {
kind: 'tasks#task';
title: string;
status: TaskStatus;
notes?: string;
/**
* *Optional* RFC 3339 timestamp of due date of the task
*/
due?: string;
/**
* *Optional* RFC 3339 timestamp of completion.
* Filled automatically if `status === 'completed'`
*/
completed?: string;
};
export const googleTasksCommon = {
baseUrl: `https://tasks.googleapis.com`,
/**
* @property Target task list ID where the new task will be created
*/
tasksList: Property.Dropdown<string,true,typeof googleTasksAuth>({
displayName: 'Tasks List',
auth: googleTasksAuth,
refreshers: [],
required: true,
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
placeholder: 'Please connect your account first',
options: [],
};
}
const authProp: OAuth2PropertyValue = auth as OAuth2PropertyValue;
const tasksLists = await getLists(authProp);
return {
disabled: false,
options: tasksLists.map((list) => {
return {
label: list.title,
value: list.id,
};
}),
};
},
}),
title: Property.ShortText({
displayName: 'Title',
required: true,
}),
notes: Property.LongText({
displayName: 'Notes',
required: false,
}),
due: Property.DateTime({
displayName: 'Due Date',
description: 'Due date of the task (YYYY-MM-DD)',
required: false,
}),
completed: Property.Checkbox({
displayName: 'Completed',
description: 'Mark task as completed',
required: false,
}),
};
export async function getLists(
authProp: OAuth2PropertyValue
): Promise<TasksList[]> {
// docs: https://developers.google.com/tasks/reference/rest/v1/tasklists/list
const request: HttpRequest = {
method: HttpMethod.GET,
url: `${googleTasksCommon.baseUrl}/tasks/v1/users/@me/lists`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: authProp.access_token,
},
};
const response = await httpClient.sendRequest<TasksListResponse>(request);
return response.body.items;
}
export async function getTasks(
authProp: OAuth2PropertyValue,
tasklist: string
): Promise<TasksList[]> {
// docs: https://developers.google.com/tasks/reference/rest/v1/tasklists/list
const request: HttpRequest = {
method: HttpMethod.GET,
url: `${googleTasksCommon.baseUrl}/tasks/v1/lists/${tasklist}/tasks`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: authProp.access_token,
},
};
const response = await httpClient.sendRequest<TasksListResponse>(request);
return response.body.items;
}
export async function createTask(
authProp: OAuth2PropertyValue,
taskListId: string,
task: Task
) {
const request: HttpRequest = {
method: HttpMethod.POST,
url: `${googleTasksCommon.baseUrl}/tasks/v1/lists/${taskListId}/tasks`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: authProp.access_token,
},
body: task,
};
return httpClient.sendRequest(request);
}

View File

@@ -0,0 +1,29 @@
---
title: 'Google Tasks'
description: ''
---
## Set up and run an app that calls a Google Tasks API.
1. In the Google Cloud console, enable the Google Tasks API.
- Navigate to [Google Cloud Console](https://console.cloud.google.com/) (make sure you are on the desired project or create a new project if you have none).
- Navigate to **APIs & Services**.
- Navigate to **Library** from the sidemenu.
- Find and enable the **Tasks API**.
2. Click In the Google Cloud console, and go to Menu menu > APIs & Services > Credentials.
3. Click Create Credentials > OAuth client ID.
4. In the Name field, type a name for the credential. This name is only shown in the Google Cloud console.
5. Click Create. The OAuth client created screen appears, showing your new Client ID and Client secret. Make sure to copy them before closing.
6. Click OK. The newly created credential appears under OAuth 2.0 Client IDs.
---
## Triggers
TRIGGERS
---
## Actions
### 1. Create Task

View File

@@ -0,0 +1,73 @@
import {
AppConnectionValueForAuthProperty,
OAuth2PropertyValue,
OAuth2Props,
StaticPropsValue,
TriggerStrategy,
createTrigger,
} from '@activepieces/pieces-framework';
import { googleTasksAuth } from '../..';
import {
DedupeStrategy,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { getTasks, googleTasksCommon } from '../common';
const props = {
tasks_list: googleTasksCommon.tasksList,
};
const polling: Polling<
AppConnectionValueForAuthProperty<typeof googleTasksAuth>,
StaticPropsValue<typeof props>
> = {
strategy: DedupeStrategy.TIMEBASED,
items: async ({ auth, propsValue, lastFetchEpochMS }) => {
const records = await getTasks(auth, propsValue.tasks_list!);
const filtered_records = records.filter((record) => {
const updated = Date.parse(record.updated);
return updated > lastFetchEpochMS;
});
return filtered_records.map((record) => ({
epochMilliSeconds: Date.parse(record.updated),
data: record,
}));
},
};
export const newTaskTrigger = createTrigger({
auth: googleTasksAuth,
name: 'new_task',
displayName: 'New Task',
description: 'Triggers when a task is created',
type: TriggerStrategy.POLLING,
props,
sampleData: {},
async test(context) {
const store = context.store;
const auth = context.auth;
const propsValue = context.propsValue;
return await pollingHelper.test(polling, { store, auth, propsValue, files: context.files });
},
async onEnable(context) {
const store = context.store;
const auth = context.auth;
const propsValue = context.propsValue;
await pollingHelper.onEnable(polling, { store, auth, propsValue });
},
async onDisable(context) {
const store = context.store;
const auth = context.auth;
const propsValue = context.propsValue;
await pollingHelper.onEnable(polling, { store, auth, propsValue });
},
async run(context) {
const store = context.store;
const auth = context.auth;
const propsValue = context.propsValue;
return await pollingHelper.poll(polling, { store, auth, propsValue, files: context.files });
},
});

View File

@@ -0,0 +1,16 @@
{
"extends": "../../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
],
"compilerOptions": {
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}

View File

@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}