12
13// INST: Add these keys in val env variables
14// NOTE: the image notes don't work at the moment, and if you add a image note,
15// the task is skipped
16
22var add_to_habitify_todoist_project_id = "XXXX"; // INST: Project ID goes here
23var todoist_dict_mapping = { // Note: You can choose to leave this dict empty and it will still work
24 "Image Notes": { // This is for a section that is image notes only for any habit without adding a log
25 "todoist-section-id": "XXXX", // INST: section id for just image notes section goes here
26 "habitify-area-name": "undefined", // keep this value as undefined
27 specialPrompt: "only_image", // keep the value as only_image
28 },
29 "Text Notes": { // This is for a section that is text notes only for any habit without adding a log
30 "habitify-area-name": "undefined", // keep this value as undefined
31 "todoist-section-id": "XXXX", // INST: section id for just image notes section goes here
32 specialPrompt: "only_text", // keep the value as only_text
33 },
115}
116
117async function resizeAndConvertImage(imageBuffer) {
118 try {
119 const image = await Jimp.read(imageBuffer);
120 const resizedImage = await image.resize(800, 800, Jimp.RESIZE_BILINEAR);
121 const jpegBuffer = await resizedImage.quality(80).getBufferAsync(Jimp.MIME_JPEG);
122
123 if (jpegBuffer.length >= 2000000) {
124 console.error("Error: Resized image size should be smaller than 2MB");
125 return null;
126 }
128 return jpegBuffer;
129 } catch (error) {
130 console.error("Error processing image:", error);
131 return null;
132 }
133}
134
135async function downloadImage(url) {
136 try {
137 const response = await fetch(url, {
144 }
145
146 const imageBuffer = await response.buffer();
147 const resizedImageBuffer = await resizeAndConvertImage(imageBuffer);
148
149 return resizedImageBuffer;
150 } catch (error) {
151 console.error("Error downloading or processing image:", error);
152 return null;
153 }
227 let habitSchema;
228
229 if (specialPrompt === "only_text" || specialPrompt === "only_image") {
230 habitSchema = z.object({
231 name: z.enum(habitKeys),
264 prompt += "The habits you can choose from are: " + habitKeys_str + ".\n";
265
266 if (specialPrompt === "only_image" || specialPrompt === "only_text") {
267 prompt +=
268 "You are extracting the name of the habit, the date of the habit (if mentioned, or otherwise an empty string), and any note if it exists about a habit (if mentioned, or otherwise an empty string). Remember, a note is associated with only 1 habit and will say 'note that' or something like that.\n";
365}
366
367async function addImageNote(habit_id, created_at, imageBuffer) {
368 const url = `https://api.habitify.me/notes/addImageNote/${habit_id}?created_at=${encodeURIComponent(created_at)}`;
369 const headers = {
370 Authorization: HABITIFY_API_KEY,
371 "Content-Type": "image/jpeg",
372 };
373
376 method: "POST",
377 headers: headers,
378 body: imageBuffer,
379 });
380 if (!response.ok) {
462 for (const task of tasks) {
463 console.log(task);
464 task.imageComments = null;
465 if (task.commentCount > 0) {
466 const imageComments = [];
467 const todoist_comments = await getCommentsForTask(task.id);
468 for (const comment of todoist_comments) {
469 // console.log(comment);
470 if (comment.attachment && comment.attachment.resourceType === "image") {
471 const imageBuffer = await downloadImage(comment.attachment.image);
472 if (imageBuffer) {
473 imageComments.push(imageBuffer);
474 }
475 }
476 }
477 task.imageComments = imageComments ? imageComments : null;
478 }
479
480 /// START---REMOVE ONCE UPLOAD IS FIXED
481 if (task.imageComments) {
482 continue;
483 }
499 console.log(habits);
500 for (const habit of habits) {
501 if (specialPrompt != "only_image" || specialPrompt != "only_text") {
502 await addLog(
503 habits_list[habitifyAreaName][habit.name].id,
510 await addTextNote(habits_list[habitifyAreaName][habit.name].id, habit.date, habit.note);
511 }
512 if (task.imageComments) {
513 for (const imageComment of task.imageComments) {
514 await addImageNote(
515 habits_list[habitifyAreaName][habit.name].id,
516 habit.date,
517 imageComment,
518 );
519 }