Skip to content

Commit

Permalink
Fixes because TickTick API Changes (#84)
Browse files Browse the repository at this point in the history
* fix: issue with non en-US date/time representation causing parsing errors
fix: edge case where tasks were not getting closed properly on chekcbox click
closes #64

* fix: issue with non en-US date/time representation causing parsing errors
fix: edge case where tasks were not getting closed properly on checkbox click
update changelog
closes #64

* Fixes due to TickTick API changes
Fix API headers in requests per TickTick protocol change.
Improve first login experience to prevent default folder/project issues
  • Loading branch information
thesamim authored Mar 17, 2024
1 parent d62af84 commit b27b428
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 105 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
## CHANGELOG

### Beta five \[1.0.18\] -- \[1.0.19]

### Beta six \[1.0.20\]

1. Fix API headers in requests per TickTick protocol change.
2. Improve first login experience to prevent default folder/project issues

### Beta five \[1.0.18\] -- \[1.0.19\]

1. TickTickSync is now mobile compatible
2. Remove dependency on ticktick-api-lvt, migrate all API code to TickTickSync source tree
Expand Down
2 changes: 1 addition & 1 deletion dist/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "tickticksync",
"name": "TickTickSync",
"version": "1.0.19",
"version": "1.0.20",
"minAppVersion": "1.0.0",
"description": "Sync TickTick tasks to Obsidian, and Obsidian tasks to TickTick",
"author": "thesamim",
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "tickticksync",
"name": "TickTickSync",
"version": "1.0.19",
"version": "1.0.20",
"minAppVersion": "1.0.0",
"description": "Sync TickTick tasks to Obsidian, and Obsidian tasks to TickTick",
"author": "thesamim",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tickticksync",
"version": "1.0.18",
"version": "1.0.20",
"description": "Sync TickTick tasks to Obsidian, and Obsidian tasks to TickTick",
"main": "main.js",
"scripts": {
Expand Down
31 changes: 25 additions & 6 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,12 @@ async makeRequest(operation: string, url: string, method: string, body: any|unde

let error = '';
try {
const requestOptions = this.createRequestOptions(method, url, body);
let requestOptions = {}
if (operation == "Login" ) {
requestOptions = this.createLoginRequestOptions(url, body);
} else {
requestOptions = this.createRequestOptions(method, url, body);
}
const result = await requestUrl(requestOptions);
//TODO: Assumes that we ALWAYS get a result of some kind. Verify.
if (result.status != 200) {
Expand All @@ -560,15 +565,29 @@ async makeRequest(operation: string, url: string, method: string, body: any|unde
}

}

private createRequestOptions(method: string, url: string, body: JSON | undefined) {
const headers = {
private createLoginRequestOptions(url: string, body: JSON) {
const headers = {
// 'origin': 'http://ticktick.com',
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0',
'x-device': '{"platform":"web","os":"Windows 10","device":"Firefox 117.0","name":"","version":4576,"id":"64f9effe6edff918986b5f71","channel":"website","campaign":"","websocket":""}',
'Cookie': 'AWSALB=WMtutBBo/NJ3/7lRMEGbqSN1hQcnRohspAN70w1r/KaC9MXwTI7CnNZbtjbtlkMlndvxno48Jd63nxVjCWHyyHK+jFtL3fXKLMRqw/clImsemFejFva5AIM9cZ6t;' + ' AWSALBCORS=WMtutBBo/NJ3/7lRMEGbqSN1hQcnRohspAN70w1r/KaC9MXwTI7CnNZbtjbtlkMlndvxno48Jd63nxVjCWHyyHK+jFtL3fXKLMRqw/clImsemFejFva5AIM9cZ6t; ' + `t=${this.token}`
'x-device': '{"platform":"web","os":"Windows 10","device":"Firefox 117.0","name":"","version":4576,"id":"64f9effe6edff918986b5f71","channel":"website","campaign":"","websocket":""}'
};
const options: RequestUrlParam = {
method: "POST",
url: url,
headers: headers,
contentType: 'application/json',
body: body ? JSON.stringify(body) : undefined,
throw: false
};
return options;
}
private createRequestOptions(method: string, url: string, body: JSON | undefined) {
let headers = {
//For the record, the bloody rules keep changin and we might have to the _csrf_token
'Cookie': `t=${this.token}`,
't' : `${this.token}`
};
const options: RequestUrlParam = {
method: method,
url: url,
Expand Down
14 changes: 9 additions & 5 deletions src/cacheOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,15 @@ export class CacheOperation {
// Inbox ID is got on API initialization. Don't have to do it here any more.
const projectGroups = await this.plugin.tickTickRestAPI?.GetProjectGroups();
const projects: IProject[] = await this.plugin.tickTickRestAPI?.GetAllProjects();

//Moving this here because if they have a list named Inbox, bad shit will happen.
let inboxProject = {
id: this.plugin.settings.inboxID,
name: this.plugin.settings.inboxName
};

projects.push(inboxProject);

const duplicates = projects.reduce((acc, obj, index, arr) => {
const duplicateIndex = arr.findIndex(item => item.name === obj.name && item.id !== obj.id);
if (duplicateIndex !== -1 && !acc.includes(obj)) {
Expand All @@ -634,12 +643,7 @@ export class CacheOperation {
}


let inboxProject = {
id: this.plugin.settings.inboxID,
name: this.plugin.settings.inboxName
};

projects.push(inboxProject);

// if (this.plugin.settings.debugMode) {
// if (projectGroups !== undefined && projectGroups !== null) {
Expand Down
71 changes: 41 additions & 30 deletions src/fileOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,38 +185,12 @@ export class FileOperation {
const projectIds = [...new Set(tasks.map(task => task.projectId))];
for (const projectId of projectIds) {
let taskFile = await this.plugin.cacheOperation?.getFilepathForProjectId(projectId);

let file;
if (taskFile) {
var file = this.app.vault.getAbstractFileByPath(taskFile);
file = this.app.vault.getAbstractFileByPath(taskFile);
if (!(file instanceof TFile)) {
//the file doesn't exist. Create it.
//TODO: Deal with Folders and sections in the fullness of time.
const folderPath = this.plugin.settings.TickTickTasksFilePath;
let folder = this.app.vault.getAbstractFileByPath(folderPath)
if (!(folder instanceof TFolder)) {
console.warn(`Folder ${folderPath} does not exit. It will be created`)
folder = await this.app.vault.createFolder(folderPath);
}
new Notice(`Creating new file: ${folder.path}/${taskFile}`);
console.warn(`Creating new file: ${folder.path}/${taskFile}`);
taskFile = `${folder.path}/${taskFile}`;
let whoAdded = `${this.plugin.manifest.name} -- ${this.plugin.manifest.version}`;
try {
file = await this.app.vault.create(taskFile, `== Added by ${whoAdded} == `)
} catch (error) {
console.error("File creation failed: ", error)
if (error.message.includes("File already exists")) {
console.error("Attempting to find existing file")
//this has happened when we've had duplicated lists in TickTick.
//Until they fix it....
file = this.app.vault.getAbstractFileByPath(taskFile);
// if (file instanceof TFile) {
// const projectName = await this.plugin.cacheOperation?.getProjectNameByIdFromCache(projectId);
// // await this.app.vault.append(file, `\n====== Project **${projectName}** is probably duplicated in TickTick Adding tasks from other project here. `)
// }
}
}
}
file = await this.getOrCreateDefaultFile(taskFile);
}
}
let projectTasks = tasks.filter(task => task.projectId === projectId);
//make sure top level tasks are first
Expand All @@ -242,6 +216,43 @@ export class FileOperation {
}


async getOrCreateDefaultFile(taskFile: string) {
let file;
//the file doesn't exist. Create it.
try {
//TODO: Deal with Folders and sections in the fullness of time.
const folderPath = this.plugin.settings.TickTickTasksFilePath;
let folder = this.app.vault.getAbstractFileByPath(folderPath);
if (!(folder instanceof TFolder)) {
console.warn(`Folder ${folderPath} does not exit. It will be created`);
folder = await this.app.vault.createFolder(folderPath);
}
new Notice(`Creating new file: ${folder.path}/${taskFile}`);
console.warn(`Creating new file: ${folder.path}/${taskFile}`);
taskFile = `${folder.path}/${taskFile}`;
let whoAdded = `${this.plugin.manifest.name} -- ${this.plugin.manifest.version}`;
try {
file = await this.app.vault.create(taskFile, `== Added by ${whoAdded} == `);
} catch (error) {
console.error('File creation failed: ', error);
if (error.message.includes('File already exists')) {
console.error('Attempting to find existing file');
//this has happened when we've had duplicated lists in TickTick.
//Until they fix it....
file = this.app.vault.getAbstractFileByPath(taskFile);
// if (file instanceof TFile) {
// const projectName = await this.plugin.cacheOperation?.getProjectNameByIdFromCache(projectId);
// // await this.app.vault.append(file, `\n====== Project **${projectName}** is probably duplicated in TickTick Adding tasks from other project here. `)
// }
}
}
return file;
} catch (error) {
console.error('Error on create file: ', error);
throw new Error(error);
}
}

private async addProjectTasksToFile(file: TFile, tasks: ITask[]): Promise<boolean> {
try {
const content = await this.app.vault.read(file);
Expand Down
Loading

0 comments on commit b27b428

Please sign in to comment.