@pipedream/toggl 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,29 +1,11 @@
1
1
  # Overview
2
2
 
3
- The Toggl Track API allows developers to build apps that help measure and
4
- visualize employee productivity. Using the API, it is possible to build tools
5
- such as timesheet managers, project-based dashboards, expense analysis, team
6
- management applications, and more.
3
+ Toggl Track is a time tracking API that lets you start, stop, and manage timers and time entries, as well as manage projects, clients, and tasks associated with time records. With the Toggl Track API on Pipedream, you can automate time tracking activities, synchronize data across platforms, and generate insights from time tracking data to improve productivity and project management.
7
4
 
8
- The Toggl Track API also offers data overviews and integrated reporting, as
9
- well as access to Toggl Track’s easy-to-use user interface. This facilitates
10
- the creation of customized application features that can help businesses save
11
- time and maximize productivity.
5
+ # Example Use Cases
12
6
 
13
- Here are a few examples of what you can build using the Toggl Track API:
7
+ - **Project Time Tracking Automation:** Automatically start a Toggl timer when you begin working on a GitHub issue. When the issue is closed, stop the timer. This creates a seamless link between your coding activity and time tracking.
14
8
 
15
- - Timesheet manager: Create an application that gives users an overview of
16
- their time tracking data.
17
- - Project-based dashboard: Visualize employee’s performance data on a
18
- project-by-project basis.
19
- - Expense analysis: Analyze employees' expense data so that businesses can make
20
- more informed decisions.
21
- - Team management applications: Manage employee workloads more efficiently with
22
- customized tools.
23
- - Customized reports: Build customized reports based on specific criteria
24
- related to time tracking data.
25
- - User interface: Access and integrate Toggl Track's intuitive user interface
26
- into applications.
9
+ - **Client Reporting Workflow:** Generate weekly time reports for clients by aggregating Toggl data and sending it via Gmail. Use the Pipedream workflow to filter time entries by client and project, compile the data, and format it into a nicely structured email.
27
10
 
28
- - The API Reference has been updated to V9 and has been relocated [here](https://developers.track.toggl.com/)
29
- - This current implementation in pipdream only utilizes time entries. Toggl also offers coverage at the workspace level down to the individual task level. The workspace docs located [here](https://developers.track.toggl.com/docs/api/workspaces) provide insight in how to begin creating workspaces and allowing other individuals to be added to those workspaces allowing the tracking of whole teams at a time.
11
+ - **Slack Productivity Bot:** Create a Slack bot that prompts team members to log their time if they haven't started a timer by midday. Use Toggl's API to check for active timers and send reminders through Slack, encouraging timely time entry submissions.
@@ -0,0 +1,45 @@
1
+ import toggl from "../../toggl.app.mjs";
2
+
3
+ export default {
4
+ key: "toggl-create-client",
5
+ name: "Create Client",
6
+ description: "Create a new client in Toggl. [See the documentation](https://engineering.toggl.com/docs/api/clients#post-create-client)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ props: {
10
+ toggl,
11
+ workspaceId: {
12
+ propDefinition: [
13
+ toggl,
14
+ "workspaceId",
15
+ ],
16
+ },
17
+ name: {
18
+ propDefinition: [
19
+ toggl,
20
+ "clientName",
21
+ ],
22
+ },
23
+ notes: {
24
+ propDefinition: [
25
+ toggl,
26
+ "notes",
27
+ ],
28
+ },
29
+ },
30
+ async run({ $ }) {
31
+ const response = await this.toggl.createClient({
32
+ $,
33
+ workspaceId: this.workspaceId,
34
+ data: {
35
+ name: this.name,
36
+ notes: this.notes,
37
+ wid: this.workspaceId,
38
+ },
39
+ });
40
+ if (response.id) {
41
+ $.export("$summary", `Successfully created client with ID: ${response.id}`);
42
+ }
43
+ return response;
44
+ },
45
+ };
@@ -0,0 +1,86 @@
1
+ import toggl from "../../toggl.app.mjs";
2
+
3
+ export default {
4
+ key: "toggl-create-project",
5
+ name: "Create Project",
6
+ description: "Create a new project in Toggl. [See the documentation](https://engineering.toggl.com/docs/api/projects#post-workspaceprojects)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ props: {
10
+ toggl,
11
+ workspaceId: {
12
+ propDefinition: [
13
+ toggl,
14
+ "workspaceId",
15
+ ],
16
+ },
17
+ name: {
18
+ propDefinition: [
19
+ toggl,
20
+ "projectName",
21
+ ],
22
+ },
23
+ startDate: {
24
+ propDefinition: [
25
+ toggl,
26
+ "startDate",
27
+ ],
28
+ },
29
+ endDate: {
30
+ propDefinition: [
31
+ toggl,
32
+ "endDate",
33
+ ],
34
+ },
35
+ active: {
36
+ type: "boolean",
37
+ label: "Active",
38
+ description: "Whether the project is active or archived. Defaults to `true`.",
39
+ optional: true,
40
+ default: true,
41
+ },
42
+ isPrivate: {
43
+ type: "boolean",
44
+ label: "Is Private?",
45
+ description: "Whether the project is private or not. Defaults to `false`.",
46
+ optional: true,
47
+ default: false,
48
+ },
49
+ isShared: {
50
+ type: "boolean",
51
+ label: "Is Shared?",
52
+ description: "Whether the project is shared or not. Defaults to `false`.",
53
+ optional: true,
54
+ default: false,
55
+ },
56
+ clientId: {
57
+ propDefinition: [
58
+ toggl,
59
+ "clientId",
60
+ (c) => ({
61
+ workspaceId: c.workspaceId,
62
+ }),
63
+ ],
64
+ optional: true,
65
+ },
66
+ },
67
+ async run({ $ }) {
68
+ const response = await this.toggl.createProject({
69
+ $,
70
+ workspaceId: this.workspaceId,
71
+ data: {
72
+ name: this.name,
73
+ start_date: this.startDate,
74
+ end_date: this.endDate,
75
+ active: this.active,
76
+ is_private: this.isPrivate,
77
+ is_shared: this.isShared,
78
+ client_id: this.clientId,
79
+ },
80
+ });
81
+ if (response.id) {
82
+ $.export("$summary", `Successfully created project with ID: ${response.id}`);
83
+ }
84
+ return response;
85
+ },
86
+ };
@@ -2,7 +2,7 @@ import toggl from "../../toggl.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Get Current Time Entry",
5
- version: "0.0.4",
5
+ version: "0.0.6",
6
6
  key: "toggl-get-current-time-entry",
7
7
  description: "Get the time entry that is running now. [See docs here]https://developers.track.toggl.com/docs/api/time_entries#get-get-current-time-entry)",
8
8
  type: "action",
@@ -2,7 +2,7 @@ import toggl from "../../toggl.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Get Time Entries",
5
- version: "0.0.4",
5
+ version: "0.0.6",
6
6
  key: "toggl-get-time-entries",
7
7
  description: "Get the last thousand time entries. [See docs here](https://developers.track.toggl.com/docs/api/time_entries#get-timeentries)",
8
8
  type: "action",
@@ -2,7 +2,7 @@ import toggl from "../../toggl.app.mjs";
2
2
 
3
3
  export default {
4
4
  name: "Get Time Entry",
5
- version: "0.0.4",
5
+ version: "0.0.6",
6
6
  key: "toggl-get-time-entry",
7
7
  description: "Get details about a specific time entry. [See docs here](https://developers.track.toggl.com/docs/api/time_entries)",
8
8
  type: "action",
@@ -21,8 +21,7 @@ export default {
21
21
  timeEntryId: this.timeEntryId,
22
22
  });
23
23
 
24
- response && $.export("$summary", "Successfully retrieved time entry");
25
-
24
+ $.export("$summary", "Successfully retrieved time entry");
26
25
  return response;
27
26
  },
28
27
  };
@@ -0,0 +1,61 @@
1
+ import toggl from "../../toggl.app.mjs";
2
+
3
+ export default {
4
+ key: "toggl-update-client",
5
+ name: "Update Client",
6
+ description: "Updates an existing client in Toggl. [See the documentation](https://engineering.toggl.com/docs/api/clients#put-change-client)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ props: {
10
+ toggl,
11
+ workspaceId: {
12
+ propDefinition: [
13
+ toggl,
14
+ "workspaceId",
15
+ ],
16
+ },
17
+ clientId: {
18
+ propDefinition: [
19
+ toggl,
20
+ "clientId",
21
+ (c) => ({
22
+ workspaceId: c.workspaceId,
23
+ }),
24
+ ],
25
+ },
26
+ name: {
27
+ propDefinition: [
28
+ toggl,
29
+ "clientName",
30
+ ],
31
+ optional: true,
32
+ },
33
+ notes: {
34
+ propDefinition: [
35
+ toggl,
36
+ "notes",
37
+ ],
38
+ },
39
+ },
40
+ async run({ $ }) {
41
+ const client = await this.toggl.getClient({
42
+ $,
43
+ workspaceId: this.workspaceId,
44
+ clientId: this.clientId,
45
+ });
46
+ const response = await this.toggl.updateClient({
47
+ $,
48
+ workspaceId: this.workspaceId,
49
+ clientId: this.clientId,
50
+ data: {
51
+ name: this.name || client.name,
52
+ notes: this.notes || client.notes,
53
+ wid: this.workspaceId,
54
+ },
55
+ });
56
+ if (response.id) {
57
+ $.export("$summary", `Successfully updated client with ID: ${response.id}`);
58
+ }
59
+ return response;
60
+ },
61
+ };
@@ -0,0 +1,101 @@
1
+ import toggl from "../../toggl.app.mjs";
2
+
3
+ export default {
4
+ key: "toggl-update-project",
5
+ name: "Update Project",
6
+ description: "Updates an existing project in Toggl. [See the documentation](https://engineering.toggl.com/docs/api/projects#put-workspaceproject)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ props: {
10
+ toggl,
11
+ workspaceId: {
12
+ propDefinition: [
13
+ toggl,
14
+ "workspaceId",
15
+ ],
16
+ },
17
+ projectId: {
18
+ propDefinition: [
19
+ toggl,
20
+ "projectId",
21
+ (c) => ({
22
+ workspaceId: c.workspaceId,
23
+ }),
24
+ ],
25
+ },
26
+ name: {
27
+ propDefinition: [
28
+ toggl,
29
+ "projectName",
30
+ ],
31
+ optional: true,
32
+ },
33
+ startDate: {
34
+ propDefinition: [
35
+ toggl,
36
+ "startDate",
37
+ ],
38
+ optional: true,
39
+ },
40
+ endDate: {
41
+ propDefinition: [
42
+ toggl,
43
+ "endDate",
44
+ ],
45
+ optional: true,
46
+ },
47
+ active: {
48
+ type: "boolean",
49
+ label: "Active",
50
+ description: "Whether the project is active or archived.",
51
+ optional: true,
52
+ },
53
+ isPrivate: {
54
+ type: "boolean",
55
+ label: "Is Private?",
56
+ description: "Whether the project is private or not.",
57
+ optional: true,
58
+ },
59
+ isShared: {
60
+ type: "boolean",
61
+ label: "Is Shared?",
62
+ description: "Whether the project is shared or not.",
63
+ optional: true,
64
+ },
65
+ clientId: {
66
+ propDefinition: [
67
+ toggl,
68
+ "clientId",
69
+ (c) => ({
70
+ workspaceId: c.workspaceId,
71
+ }),
72
+ ],
73
+ optional: true,
74
+ },
75
+ },
76
+ async run({ $ }) {
77
+ const project = await this.toggl.getProject({
78
+ $,
79
+ workspaceId: this.workspaceId,
80
+ projectId: this.projectId,
81
+ });
82
+ const response = await this.toggl.updateProject({
83
+ $,
84
+ workspaceId: this.workspaceId,
85
+ projectId: this.projectId,
86
+ data: {
87
+ name: this.name || project.name,
88
+ start_date: this.startDate || project.start_date,
89
+ end_date: this.endDate || project.end_date,
90
+ active: this.active || project.active,
91
+ is_private: this.isPrivate || project.isPrivate,
92
+ is_shared: this.isShared || project.is_shared,
93
+ client_id: this.clientId || project.client_id,
94
+ },
95
+ });
96
+ if (response.id) {
97
+ $.export("$summary", `Successfully updated project with ID: ${response.id}`);
98
+ }
99
+ return response;
100
+ },
101
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/toggl",
3
- "version": "0.0.5",
3
+ "version": "0.1.0",
4
4
  "description": "Pipedream Toggl Components",
5
5
  "main": "toggl.app.js",
6
6
  "keywords": [
@@ -14,7 +14,7 @@
14
14
  "access": "public"
15
15
  },
16
16
  "dependencies": {
17
- "@pipedream/platform": "^0.10.0",
17
+ "@pipedream/platform": "^3.0.0",
18
18
  "toggl-api": "^1.0.2"
19
19
  }
20
20
  }
@@ -3,7 +3,7 @@ import base from "../common/base.mjs";
3
3
  export default {
4
4
  ...base,
5
5
  name: "New Start Time Entry (Instant)",
6
- version: "0.0.2",
6
+ version: "0.0.4",
7
7
  key: "toggl-new-start-time-entry",
8
8
  description: "Emit new event when a time entry is started. [See docs here](https://github.com/toggl/toggl_api_docs/blob/master/webhooks.md)",
9
9
  type: "source",
@@ -3,7 +3,7 @@ import base from "../common/base.mjs";
3
3
  export default {
4
4
  ...base,
5
5
  name: "New Time Entry (Instant)",
6
- version: "0.0.2",
6
+ version: "0.0.4",
7
7
  key: "toggl-new-time-entry",
8
8
  description: "Emit new event when a time entry is created. [See docs here](https://github.com/toggl/toggl_api_docs/blob/master/webhooks.md)",
9
9
  type: "source",
@@ -3,7 +3,7 @@ import base from "../common/base.mjs";
3
3
  export default {
4
4
  ...base,
5
5
  name: "New Update Time Entry (Instant)",
6
- version: "0.0.2",
6
+ version: "0.0.4",
7
7
  key: "toggl-new-update-time-entry",
8
8
  description: "Emit new event when a time entry is updated. [See docs here](https://github.com/toggl/toggl_api_docs/blob/master/webhooks.md)",
9
9
  type: "source",
@@ -4,7 +4,7 @@ import constants from "../common/constants.mjs";
4
4
  export default {
5
5
  ...base,
6
6
  name: "New Webhook Event (Instant)",
7
- version: "0.0.2",
7
+ version: "0.0.4",
8
8
  key: "toggl-new-webhook-event",
9
9
  description: "Emit new event on receive a webhook event. [See docs here](https://github.com/toggl/toggl_api_docs/blob/master/webhooks.md)",
10
10
  type: "source",
package/toggl.app.mjs CHANGED
@@ -39,6 +39,62 @@ export default {
39
39
  }));
40
40
  },
41
41
  },
42
+ clientId: {
43
+ label: "Client ID",
44
+ description: "The client ID",
45
+ type: "integer",
46
+ async options({ workspaceId }) {
47
+ const clients = await this.getClients({
48
+ workspaceId,
49
+ });
50
+
51
+ return clients?.map((client) => ({
52
+ label: client.name,
53
+ value: client.id,
54
+ })) || [];
55
+ },
56
+ },
57
+ projectId: {
58
+ label: "Project ID",
59
+ description: "The project ID",
60
+ type: "integer",
61
+ async options({ workspaceId }) {
62
+ const projects = await this.getProjects({
63
+ workspaceId,
64
+ });
65
+
66
+ return projects?.map((project) => ({
67
+ label: project.name,
68
+ value: project.id,
69
+ })) || [];
70
+ },
71
+ },
72
+ clientName: {
73
+ type: "string",
74
+ label: "Name",
75
+ description: "Name of the client",
76
+ },
77
+ notes: {
78
+ type: "string",
79
+ label: "Notes",
80
+ description: "Notes about the client",
81
+ optional: true,
82
+ },
83
+ projectName: {
84
+ type: "string",
85
+ label: "Name",
86
+ description: "Name of the project",
87
+ },
88
+ startDate: {
89
+ type: "string",
90
+ label: "Start Date",
91
+ description: "The start date of the project in `YYYY-MM-DD` format",
92
+ },
93
+ endDate: {
94
+ type: "string",
95
+ label: "End Date",
96
+ description: "The end date of the project in `YYYY-MM-DD` format",
97
+ },
42
98
  },
43
99
  methods: {
44
100
  _apiToken() {
@@ -47,7 +103,7 @@ export default {
47
103
  _apiUrl(apiVersion) {
48
104
  return constants.API_BASE_URL_VERSIONS[apiVersion];
49
105
  },
50
- async _makeRequest(apiVersion, path, options = {}, $ = this) {
106
+ _makeRequest(apiVersion, path, options = {}, $ = this) {
51
107
  return axios($, {
52
108
  url: `${this._apiUrl(apiVersion)}/${path}`,
53
109
  auth: {
@@ -57,7 +113,7 @@ export default {
57
113
  ...options,
58
114
  });
59
115
  },
60
- async createWebhook({
116
+ createWebhook({
61
117
  workspaceId, data,
62
118
  }) {
63
119
  return this._makeRequest("v1", `subscriptions/${workspaceId}`, {
@@ -69,22 +125,30 @@ export default {
69
125
  },
70
126
  });
71
127
  },
72
- async removeWebhook({
128
+ removeWebhook({
73
129
  workspaceId, webhookId,
74
130
  }) {
75
131
  return this._makeRequest("v1", `subscriptions/${workspaceId}/${webhookId}`, {
76
132
  method: "delete",
77
133
  });
78
134
  },
79
- async getWorkspaces({
135
+ getWorkspaces({ $ }) {
136
+ return this._makeRequest("v9", "me/workspaces", {}, $);
137
+ },
138
+ getClients({
139
+ workspaceId, $,
140
+ }) {
141
+ return this._makeRequest("v9", `workspaces/${workspaceId}/clients`, {}, $);
142
+ },
143
+ getProjects({
80
144
  workspaceId, $,
81
145
  }) {
82
- return this._makeRequest("v9", `workspaces/${workspaceId}`, {}, $);
146
+ return this._makeRequest("v9", `workspaces/${workspaceId}/projects`, {}, $);
83
147
  },
84
- async getCurrentTimeEntry({ $ } = {}) {
148
+ getCurrentTimeEntry({ $ } = {}) {
85
149
  return this._makeRequest("v9", "me/time_entries/current", {}, $);
86
150
  },
87
- async getTimeEntries({
151
+ getTimeEntries({
88
152
  params, $,
89
153
  } = {}) {
90
154
  return this._makeRequest("v9", "me/time_entries", {
@@ -94,12 +158,52 @@ export default {
94
158
  },
95
159
  }, $);
96
160
  },
97
- async getTimeEntry({
161
+ getTimeEntry({
98
162
  timeEntryId, $,
99
163
  } = {}) {
100
- const { data } = await this._makeRequest("v8", `time_entries/${timeEntryId}`, {}, $);
101
-
102
- return data;
164
+ return this._makeRequest("v9", `me/time_entries/${timeEntryId}`, {}, $);
165
+ },
166
+ getClient({
167
+ workspaceId, clientId, $,
168
+ } = {}) {
169
+ return this._makeRequest("v9", `workspaces/${workspaceId}/clients/${clientId}`, {}, $);
170
+ },
171
+ getProject({
172
+ workspaceId, projectId, $,
173
+ } = {}) {
174
+ return this._makeRequest("v9", `workspaces/${workspaceId}/projects/${projectId}`, {}, $);
175
+ },
176
+ createClient({
177
+ workspaceId, data, $,
178
+ }) {
179
+ return this._makeRequest("v9", `workspaces/${workspaceId}/clients`, {
180
+ method: "post",
181
+ data,
182
+ }, $);
183
+ },
184
+ createProject({
185
+ workspaceId, data, $,
186
+ }) {
187
+ return this._makeRequest("v9", `workspaces/${workspaceId}/projects`, {
188
+ method: "post",
189
+ data,
190
+ }, $);
191
+ },
192
+ updateClient({
193
+ workspaceId, clientId, data, $,
194
+ }) {
195
+ return this._makeRequest("v9", `workspaces/${workspaceId}/clients/${clientId}`, {
196
+ method: "put",
197
+ data,
198
+ }, $);
199
+ },
200
+ updateProject({
201
+ workspaceId, projectId, data, $,
202
+ }) {
203
+ return this._makeRequest("v9", `workspaces/${workspaceId}/projects/${projectId}`, {
204
+ method: "put",
205
+ data,
206
+ }, $);
103
207
  },
104
208
  },
105
209
  };