Skip to main content
Glama
timeEntry.service.ts•5.6 kB
import { ClockifyApiClient } from '../client.js'; import type { ClockifyTimeEntry, ClockifyTimeEntryRequest } from '../../types/index.js'; export class TimeEntryService { constructor(private client: ClockifyApiClient) {} async createTimeEntry( workspaceId: string, data: ClockifyTimeEntryRequest ): Promise<ClockifyTimeEntry> { return this.client.post<ClockifyTimeEntry>(`/workspaces/${workspaceId}/time-entries`, data); } async getTimeEntriesForUser( workspaceId: string, userId: string, options?: { description?: string; start?: string; end?: string; project?: string; task?: string; tags?: string[]; 'project-required'?: boolean; 'task-required'?: boolean; hydrated?: boolean; page?: number; 'page-size'?: number; } ): Promise<ClockifyTimeEntry[]> { return this.client.get<ClockifyTimeEntry[]>( `/workspaces/${workspaceId}/user/${userId}/time-entries`, options ); } async getTimeEntryById( workspaceId: string, timeEntryId: string, options?: { hydrated?: boolean; } ): Promise<ClockifyTimeEntry> { return this.client.get<ClockifyTimeEntry>( `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, options ); } async updateTimeEntry( workspaceId: string, timeEntryId: string, data: { start?: string; billable?: boolean; description?: string; projectId?: string; taskId?: string; end?: string; tagIds?: string[]; hourlyRate?: { amount: number; currency: string; }; costRate?: { amount: number; currency: string; }; type?: 'REGULAR' | 'BREAK' | 'CLOCK_IN_OUT'; kioskId?: string; customFields?: Array<{ customFieldId: string; value: string | number | boolean; sourceType?: string; name?: string; type?: string; }>; } ): Promise<ClockifyTimeEntry> { return this.client.put<ClockifyTimeEntry>( `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, data ); } async deleteTimeEntry(workspaceId: string, timeEntryId: string): Promise<void> { return this.client.delete(`/workspaces/${workspaceId}/time-entries/${timeEntryId}`); } async stopRunningTimer( workspaceId: string, userId: string, data: { end: string; } ): Promise<ClockifyTimeEntry> { return this.client.patch<ClockifyTimeEntry>( `/workspaces/${workspaceId}/user/${userId}/time-entries`, data ); } async getRunningTimeEntry( workspaceId: string, userId: string ): Promise<ClockifyTimeEntry | null> { const entries = await this.getTimeEntriesForUser(workspaceId, userId, { 'page-size': 1, }); if (entries.length > 0 && !entries[0].timeInterval.end) { return entries[0]; } return null; } async bulkEditTimeEntries( workspaceId: string, timeEntryIds: string[], data: { billable?: boolean; projectId?: string; taskId?: string; tagIds?: string[]; } ): Promise<any> { return this.client.patch(`/workspaces/${workspaceId}/time-entries/bulk`, { timeEntryIds, ...data, }); } async bulkDeleteTimeEntries(workspaceId: string, timeEntryIds: string[]): Promise<void> { return this.client.post(`/workspaces/${workspaceId}/time-entries/delete`, { timeEntryIds, }); } async duplicateTimeEntry(workspaceId: string, timeEntryId: string): Promise<ClockifyTimeEntry> { const original = await this.getTimeEntryById(workspaceId, timeEntryId); const now = new Date(); return this.createTimeEntry(workspaceId, { start: now.toISOString(), description: original.description, projectId: original.projectId, taskId: original.taskId, tagIds: original.tagIds, billable: original.billable, }); } async getTimeEntriesInRange( workspaceId: string, userId: string, startDate: Date, endDate: Date ): Promise<ClockifyTimeEntry[]> { return this.getTimeEntriesForUser(workspaceId, userId, { start: startDate.toISOString(), end: endDate.toISOString(), }); } async getTodayTimeEntries(workspaceId: string, userId: string): Promise<ClockifyTimeEntry[]> { const today = new Date(); today.setHours(0, 0, 0, 0); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); return this.getTimeEntriesInRange(workspaceId, userId, today, tomorrow); } async getWeekTimeEntries(workspaceId: string, userId: string): Promise<ClockifyTimeEntry[]> { const today = new Date(); const dayOfWeek = today.getDay(); const startOfWeek = new Date(today); startOfWeek.setDate(today.getDate() - dayOfWeek); startOfWeek.setHours(0, 0, 0, 0); const endOfWeek = new Date(startOfWeek); endOfWeek.setDate(startOfWeek.getDate() + 7); return this.getTimeEntriesInRange(workspaceId, userId, startOfWeek, endOfWeek); } async getMonthTimeEntries( workspaceId: string, userId: string, year?: number, month?: number ): Promise<ClockifyTimeEntry[]> { const now = new Date(); const targetYear = year || now.getFullYear(); const targetMonth = month !== undefined ? month : now.getMonth(); const startOfMonth = new Date(targetYear, targetMonth, 1); const endOfMonth = new Date(targetYear, targetMonth + 1, 0, 23, 59, 59, 999); return this.getTimeEntriesInRange(workspaceId, userId, startOfMonth, endOfMonth); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hongkongkiwi/clockify-master-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server