commit
5cb60b8f99
12 changed files with 382 additions and 115 deletions
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
<h2>Version 3.2.0 - ??/??/2025</h2>
|
<h2>Version 3.2.0 - ??/??/2025</h2>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>Added an option to automatically tag incoming emails [<a href="https://github.com/micz/ThunderAI/issues/237">#237</a>].</li>
|
||||||
|
<li>Added the <i>{%thunderai_def_sign%}</i> placeholder to get the default signature as defined in the options [<a href="https://github.com/micz/ThunderAI/issues/248">#248</a>].</li>
|
||||||
|
<li>Added the <i>{%thunderai_def_lang%}</i> placeholder to get the default language as defined in the options [<a href="https://github.com/micz/ThunderAI/issues/248">#248</a>].</li>
|
||||||
|
<li>Various minor improvements.</li>
|
||||||
<li>...</li>
|
<li>...</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2>Version 3.1.2 - 29/01/2025</h2>
|
<h2>Version 3.1.2 - 29/01/2025</h2>
|
||||||
|
|
|
||||||
|
|
@ -1018,5 +1018,37 @@
|
||||||
"sparks_not_installed": {
|
"sparks_not_installed": {
|
||||||
"message": "ThunderAI Sparks not installed!",
|
"message": "ThunderAI Sparks not installed!",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_add_tags_auto": {
|
||||||
|
"message": "Add tags automatically",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_add_tags_auto_Info": {
|
||||||
|
"message": "If checked, the AI will automatically add tags to newly received emails.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_add_tags_auto_force_existing": {
|
||||||
|
"message": "Force existing tags when autotagging",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_add_tags_auto_force_existing_Info": {
|
||||||
|
"message": "If checked, the AI will add only existing tags to newly received emails, and won't create new tags.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_add_tags_auto_only_inbox": {
|
||||||
|
"message": "Only add tags to inbox emails",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_add_tags_auto_only_inbox_Info": {
|
||||||
|
"message": "If checked, the AI will only add tags to emails received in the inbox folder.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"placeholder_thunderai_def_sign": {
|
||||||
|
"message": "Default signature as defined in ThunderAI options.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"thunderai_def_lang": {
|
||||||
|
"message": "Default language as defined in ThunderAI options.",
|
||||||
|
"description": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
100
js/mzta-menus.js
100
js/mzta-menus.js
|
|
@ -19,7 +19,8 @@
|
||||||
// Some original methods are derived from https://github.com/ali-raheem/Aify/blob/cfadf52f576b7be3720b5b73af7c8d3129c054da/plugin/html/actions.js
|
// Some original methods are derived from https://github.com/ali-raheem/Aify/blob/cfadf52f576b7be3720b5b73af7c8d3129c054da/plugin/html/actions.js
|
||||||
|
|
||||||
import { getPrompts } from './mzta-prompts.js';
|
import { getPrompts } from './mzta-prompts.js';
|
||||||
import { getLanguageDisplayName, getMenuContextCompose, getMenuContextDisplay, i18nConditionalGet, getMailSubject, getTagsList, transformTagsLabels } from './mzta-utils.js'
|
import { getLanguageDisplayName, getMenuContextCompose, getMenuContextDisplay, i18nConditionalGet, getMailSubject, getTagsList } from './mzta-utils.js'
|
||||||
|
import { taPromptUtils } from './mzta-utils-prompt.js';
|
||||||
import { taLogger } from './mzta-logger.js';
|
import { taLogger } from './mzta-logger.js';
|
||||||
import { placeholdersUtils } from './mzta-placeholders.js';
|
import { placeholdersUtils } from './mzta-placeholders.js';
|
||||||
import { mzta_specialCommand } from './mzta-special-commands.js';
|
import { mzta_specialCommand } from './mzta-special-commands.js';
|
||||||
|
|
@ -106,18 +107,8 @@ export class mzta_Menus {
|
||||||
only_typed_text = msg_text.only_typed_text.replace(/\s+/g, ' ').trim();
|
only_typed_text = msg_text.only_typed_text.replace(/\s+/g, ' ').trim();
|
||||||
//open chatgpt window
|
//open chatgpt window
|
||||||
//console.log("Click menu item...");
|
//console.log("Click menu item...");
|
||||||
let chatgpt_lang = '';
|
let chatgpt_lang = taPromptUtils.getDefaultLang(curr_prompt);
|
||||||
if(String(curr_prompt.define_response_lang) == "1"){
|
|
||||||
let prefs = await browser.storage.sync.get({default_chatgpt_lang: ''});
|
|
||||||
chatgpt_lang = prefs.default_chatgpt_lang;
|
|
||||||
//console.log(" >>>>>>>>>>>> chatgpt_lang: " + chatgpt_lang);
|
|
||||||
if(chatgpt_lang === ''){
|
|
||||||
chatgpt_lang = browser.i18n.getMessage("reply_same_lang");
|
|
||||||
}else{
|
|
||||||
chatgpt_lang = browser.i18n.getMessage("prompt_lang") + " " + chatgpt_lang + ".";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let fullPrompt = '';
|
let fullPrompt = '';
|
||||||
let tags_full_list = await getTagsList();
|
let tags_full_list = await getTagsList();
|
||||||
|
|
||||||
|
|
@ -137,65 +128,7 @@ export class mzta_Menus {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!placeholdersUtils.hasPlaceholder(curr_prompt.text)){
|
fullPrompt = await taPromptUtils.preparePrompt(curr_prompt, curr_message, chatgpt_lang, selection_text, body_text, await getMailSubject(tabs[0]), msg_text, only_typed_text, tags_full_list);
|
||||||
// no placeholders, do as usual
|
|
||||||
fullPrompt = curr_prompt.text + (String(curr_prompt.need_signature) == "1" ? " " + await this.getDefaultSignature():"") + " " + chatgpt_lang + " \"" + (selection_text=='' ? body_text : selection_text) + "\" ";
|
|
||||||
}else{
|
|
||||||
// we have at least a placeholder, do the magic!
|
|
||||||
let currPHs = await placeholdersUtils.extractPlaceholders(curr_prompt.text);
|
|
||||||
// console.log(">>>>>>>>>> currPHs: " + JSON.stringify(currPHs));
|
|
||||||
let finalSubs = {};
|
|
||||||
for(let currPH of currPHs){
|
|
||||||
switch(currPH.id){
|
|
||||||
case 'mail_text_body':
|
|
||||||
finalSubs['mail_text_body'] = body_text;
|
|
||||||
break;
|
|
||||||
case 'mail_html_body':
|
|
||||||
finalSubs['mail_html_body'] = msg_text.html;
|
|
||||||
break;
|
|
||||||
case 'mail_typed_text':
|
|
||||||
finalSubs['mail_typed_text'] = only_typed_text;
|
|
||||||
break;
|
|
||||||
case 'mail_subject':
|
|
||||||
let mail_subject = await getMailSubject(tabs[0]);
|
|
||||||
finalSubs['mail_subject'] = mail_subject;
|
|
||||||
break;
|
|
||||||
case 'selected_text':
|
|
||||||
finalSubs['selected_text'] = selection_text;
|
|
||||||
break;
|
|
||||||
case 'author':
|
|
||||||
finalSubs['author'] = curr_message.author;
|
|
||||||
break;
|
|
||||||
case 'recipients':
|
|
||||||
finalSubs['recipients'] = curr_message.recipients.join(", ");
|
|
||||||
break;
|
|
||||||
case 'cc_list':
|
|
||||||
finalSubs['cc_list'] = curr_message.ccList.join(", ");
|
|
||||||
break;
|
|
||||||
case 'junk_score':
|
|
||||||
finalSubs['junk_score'] = curr_message.junkScore;
|
|
||||||
break;
|
|
||||||
case 'mail_datetime':
|
|
||||||
finalSubs['mail_datetime'] = curr_message.date;
|
|
||||||
break;
|
|
||||||
case 'current_datetime':
|
|
||||||
finalSubs['current_datetime'] = new Date().toString();
|
|
||||||
break;
|
|
||||||
case 'tags_current_email':
|
|
||||||
let tags_current_email_array = await transformTagsLabels(curr_message.tags, tags_full_list[1]);
|
|
||||||
finalSubs['tags_current_email'] = tags_current_email_array.join(", ");
|
|
||||||
break;
|
|
||||||
case 'tags_full_list':
|
|
||||||
finalSubs['tags_full_list'] = tags_full_list[0];
|
|
||||||
break;
|
|
||||||
default: // TODO Manage custom placeholders https://github.com/micz/ThunderAI/issues/156
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// console.log(">>>>>>>>>> finalSubs: " + JSON.stringify(finalSubs));
|
|
||||||
let prefs_ph = await browser.storage.sync.get({placeholders_use_default_value: false});
|
|
||||||
fullPrompt = (placeholdersUtils.replacePlaceholders(curr_prompt.text, finalSubs, prefs_ph.placeholders_use_default_value, true) + (String(curr_prompt.need_signature) == "1" ? " " + await this.getDefaultSignature():"") + " " + chatgpt_lang).trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(curr_prompt.id){
|
switch(curr_prompt.id){
|
||||||
case 'prompt_translate_this':
|
case 'prompt_translate_this':
|
||||||
|
|
@ -220,26 +153,20 @@ export class mzta_Menus {
|
||||||
switch(curr_prompt.id){
|
switch(curr_prompt.id){
|
||||||
case 'prompt_add_tags': { // Add tags to the email
|
case 'prompt_add_tags': { // Add tags to the email
|
||||||
let tags_current_email = '';
|
let tags_current_email = '';
|
||||||
let prefs_at = await browser.storage.sync.get({add_tags_maxnum: 3, connection_type: '', add_tags_force_lang: true, default_chatgpt_lang: ''});
|
let prefs_at = await browser.storage.sync.get({add_tags_maxnum: 3, connection_type: '', add_tags_force_lang: true, default_chatgpt_lang: '', do_debug: false});
|
||||||
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
||||||
console.error("[ThunderAI | AddTags] Invalid connection type: " + prefs_at.connection_type);
|
console.error("[ThunderAI | AddTags] Invalid connection type: " + prefs_at.connection_type);
|
||||||
return {ok:'0'};
|
return {ok:'0'};
|
||||||
}
|
}
|
||||||
let add_tags_maxnum = prefs_at.add_tags_maxnum;
|
fullPrompt = taPromptUtils.finalizePrompt_add_tags(fullPrompt, prefs_at.add_tags_maxnum, prefs_at.add_tags_force_lang, prefs_at.default_chatgpt_lang);
|
||||||
if(add_tags_maxnum > 0){
|
|
||||||
fullPrompt += " " + browser.i18n.getMessage("prompt_add_tags_maxnum") + " " + add_tags_maxnum +".";
|
|
||||||
}
|
|
||||||
if(prefs_at.add_tags_force_lang && prefs_at.default_chatgpt_lang !== ''){
|
|
||||||
fullPrompt += " " + browser.i18n.getMessage("prompt_add_tags_force_lang") + " " + prefs_at.default_chatgpt_lang + ".";
|
|
||||||
}
|
|
||||||
this.logger.log("fullPrompt: " + fullPrompt);
|
this.logger.log("fullPrompt: " + fullPrompt);
|
||||||
// TODO: use the current API, abort if using chatgpt web
|
// TODO: use the current API, abort if using chatgpt web
|
||||||
// COMMENTED TO DO TESTS
|
// COMMENTED TO DO TESTS
|
||||||
// tags_current_email = "recipients, TEST, home, work, CAR, light";
|
// tags_current_email = "recipients, TEST, home, work, CAR, light";
|
||||||
let cmd_addTags = new mzta_specialCommand(fullPrompt,prefs_at.connection_type,true);
|
let cmd_addTags = new mzta_specialCommand(fullPrompt,prefs_at.connection_type,prefs_at.do_debug);
|
||||||
await cmd_addTags.initWorker();
|
await cmd_addTags.initWorker();
|
||||||
try{
|
try{
|
||||||
tags_current_email = await cmd_addTags.sendPrompt();
|
tags_current_email = (await cmd_addTags.sendPrompt()).trim();
|
||||||
// console.log(">>>>>>>>>>> tags_current_email: " + tags_current_email);
|
// console.log(">>>>>>>>>>> tags_current_email: " + tags_current_email);
|
||||||
}catch(err){
|
}catch(err){
|
||||||
console.error("[ThunderAI] Error getting tags: ", err);
|
console.error("[ThunderAI] Error getting tags: ", err);
|
||||||
|
|
@ -306,15 +233,6 @@ export class mzta_Menus {
|
||||||
this.rootMenu.push(curr_menu_entry);
|
this.rootMenu.push(curr_menu_entry);
|
||||||
};
|
};
|
||||||
|
|
||||||
async getDefaultSignature(){
|
|
||||||
let prefs = await browser.storage.sync.get({default_sign_name: ''});
|
|
||||||
if(prefs.default_sign_name===''){
|
|
||||||
return '';
|
|
||||||
}else{
|
|
||||||
return browser.i18n.getMessage("sign_msg_as") + " " + prefs.default_sign_name + ".";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loadShortcutMenu() {
|
loadShortcutMenu() {
|
||||||
this.shortcutMenu = [];
|
this.shortcutMenu = [];
|
||||||
this.allPrompts.forEach((prompt) => {
|
this.allPrompts.forEach((prompt) => {
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,20 @@ const defaultPlaceholders = [
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'thunderai_def_sign',
|
||||||
|
name: "__MSG_placeholder_thunderai_def_sign__",
|
||||||
|
default_value: "",
|
||||||
|
type: 0,
|
||||||
|
is_default: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'thunderai_def_lang',
|
||||||
|
name: "__MSG_placeholder_thunderai_def_lang__",
|
||||||
|
default_value: "",
|
||||||
|
type: 0,
|
||||||
|
is_default: "1",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -246,4 +260,64 @@ export const placeholdersUtils = {
|
||||||
return regex.test(text);
|
return regex.test(text);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getPlaceholdersValues(prompt_text, curr_message, mail_subject, body_text, msg_text, only_typed_text, selection_text, tags_full_list) {
|
||||||
|
let currPHs = await placeholdersUtils.extractPlaceholders(prompt_text);
|
||||||
|
// console.log(">>>>>>>>>> currPHs: " + JSON.stringify(currPHs));
|
||||||
|
let finalSubs = {};
|
||||||
|
for(let currPH of currPHs){
|
||||||
|
switch(currPH.id){
|
||||||
|
case 'mail_text_body':
|
||||||
|
finalSubs['mail_text_body'] = body_text;
|
||||||
|
break;
|
||||||
|
case 'mail_html_body':
|
||||||
|
finalSubs['mail_html_body'] = msg_text.html;
|
||||||
|
break;
|
||||||
|
case 'mail_typed_text':
|
||||||
|
finalSubs['mail_typed_text'] = only_typed_text;
|
||||||
|
break;
|
||||||
|
case 'mail_subject':
|
||||||
|
finalSubs['mail_subject'] = mail_subject;
|
||||||
|
break;
|
||||||
|
case 'selected_text':
|
||||||
|
finalSubs['selected_text'] = selection_text;
|
||||||
|
break;
|
||||||
|
case 'author':
|
||||||
|
finalSubs['author'] = curr_message.author;
|
||||||
|
break;
|
||||||
|
case 'recipients':
|
||||||
|
finalSubs['recipients'] = curr_message.recipients.join(", ");
|
||||||
|
break;
|
||||||
|
case 'cc_list':
|
||||||
|
finalSubs['cc_list'] = curr_message.ccList.join(", ");
|
||||||
|
break;
|
||||||
|
case 'junk_score':
|
||||||
|
finalSubs['junk_score'] = curr_message.junkScore;
|
||||||
|
break;
|
||||||
|
case 'mail_datetime':
|
||||||
|
finalSubs['mail_datetime'] = curr_message.date;
|
||||||
|
break;
|
||||||
|
case 'current_datetime':
|
||||||
|
finalSubs['current_datetime'] = new Date().toString();
|
||||||
|
break;
|
||||||
|
case 'tags_current_email':
|
||||||
|
let tags_current_email_array = await transformTagsLabels(curr_message.tags, tags_full_list[1]);
|
||||||
|
finalSubs['tags_current_email'] = tags_current_email_array.join(", ");
|
||||||
|
break;
|
||||||
|
case 'tags_full_list':
|
||||||
|
finalSubs['tags_full_list'] = tags_full_list[0];
|
||||||
|
break;
|
||||||
|
case 'thunderai_def_sign':
|
||||||
|
let prefs_def_sign = await browser.storage.sync.get({default_sign_name: ''});
|
||||||
|
finalSubs['thunderai_def_sign'] = prefs_def_sign.default_sign_name;
|
||||||
|
break;
|
||||||
|
case 'thunderai_def_lang':
|
||||||
|
let prefs_def_lang = await browser.storage.sync.get({default_chatgpt_lang: ''});
|
||||||
|
finalSubs['thunderai_def_lang'] = prefs_def_lang.default_chatgpt_lang;
|
||||||
|
break;
|
||||||
|
default: // TODO Manage custom placeholders https://github.com/micz/ThunderAI/issues/156
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
74
js/mzta-utils-prompt.js
Normal file
74
js/mzta-utils-prompt.js
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
||||||
|
* Copyright (C) 2024 - 2025 Mic (m@micz.it)
|
||||||
|
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { placeholdersUtils } from './mzta-placeholders.js';
|
||||||
|
|
||||||
|
export const taPromptUtils = {
|
||||||
|
|
||||||
|
async getDefaultSignature(){
|
||||||
|
let prefs = await browser.storage.sync.get({default_sign_name: ''});
|
||||||
|
if(prefs.default_sign_name===''){
|
||||||
|
return '';
|
||||||
|
}else{
|
||||||
|
return browser.i18n.getMessage("sign_msg_as") + " " + prefs.default_sign_name + ".";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async preparePrompt(curr_prompt, curr_message, chatgpt_lang, selection_text, body_text, subject_text, msg_text, only_typed_text, tags_full_list){
|
||||||
|
let fullPrompt = '';
|
||||||
|
|
||||||
|
if(!placeholdersUtils.hasPlaceholder(curr_prompt.text)){
|
||||||
|
// no placeholders, do as usual
|
||||||
|
fullPrompt = curr_prompt.text + (String(curr_prompt.need_signature) == "1" ? " " + await taPromptUtils.getDefaultSignature():"") + " " + chatgpt_lang + " \"" + (selection_text=='' ? body_text : selection_text) + "\" ";
|
||||||
|
}else{
|
||||||
|
// we have at least a placeholder, do the magic!
|
||||||
|
let finalSubs = placeholdersUtils.getPlaceholdersValues(curr_prompt.text, curr_message, subject_text, body_text, msg_text, only_typed_text, selection_text, tags_full_list);
|
||||||
|
// console.log(">>>>>>>>>> finalSubs: " + JSON.stringify(finalSubs));
|
||||||
|
let prefs_ph = await browser.storage.sync.get({placeholders_use_default_value: false});
|
||||||
|
fullPrompt = (placeholdersUtils.replacePlaceholders(curr_prompt.text, finalSubs, prefs_ph.placeholders_use_default_value, true) + (String(curr_prompt.need_signature) == "1" ? " " + await taPromptUtils.getDefaultSignature():"") + " " + chatgpt_lang).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullPrompt;
|
||||||
|
},
|
||||||
|
|
||||||
|
finalizePrompt_add_tags(fullPrompt, add_tags_maxnum, add_tags_force_lang, default_chatgpt_lang){
|
||||||
|
if(add_tags_maxnum > 0){
|
||||||
|
fullPrompt += " " + browser.i18n.getMessage("prompt_add_tags_maxnum") + " " + add_tags_maxnum +".";
|
||||||
|
}
|
||||||
|
if(add_tags_force_lang && default_chatgpt_lang !== ''){
|
||||||
|
fullPrompt += " " + browser.i18n.getMessage("prompt_add_tags_force_lang") + " " + default_chatgpt_lang + ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullPrompt;
|
||||||
|
},
|
||||||
|
|
||||||
|
async getDefaultLang(curr_prompt){
|
||||||
|
let chatgpt_lang = '';
|
||||||
|
if(String(curr_prompt.define_response_lang) == "1"){
|
||||||
|
let prefs = await browser.storage.sync.get({default_chatgpt_lang: ''});
|
||||||
|
chatgpt_lang = prefs.default_chatgpt_lang;
|
||||||
|
if(chatgpt_lang === ''){
|
||||||
|
chatgpt_lang = browser.i18n.getMessage("reply_same_lang");
|
||||||
|
}else{
|
||||||
|
chatgpt_lang = browser.i18n.getMessage("prompt_lang") + " " + chatgpt_lang + ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatgpt_lang;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -83,6 +83,29 @@ export async function getMailSubject(tab){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getMailBody(fullMessage){
|
||||||
|
let text = '';
|
||||||
|
let html = '';
|
||||||
|
|
||||||
|
if (fullMessage.contentType.trim().toLowerCase() === "text/plain") {
|
||||||
|
text = fullMessage.body;
|
||||||
|
}
|
||||||
|
if (fullMessage.contentType.trim().toLowerCase() === "text/html") {
|
||||||
|
html = fullMessage.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let part of fullMessage.parts) {
|
||||||
|
if (part.contentType.trim().toLowerCase() === "text/plain") {
|
||||||
|
text = part.body;
|
||||||
|
}
|
||||||
|
if (part.contentType.trim().toLowerCase() === "text/html") {
|
||||||
|
html = part.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {text, html};
|
||||||
|
}
|
||||||
|
|
||||||
export async function reloadBody(tabId){
|
export async function reloadBody(tabId){
|
||||||
let composeDetails = await messenger.compose.getComposeDetails(tabId);
|
let composeDetails = await messenger.compose.getComposeDetails(tabId);
|
||||||
let originalHtmlBody = composeDetails.body + " ";
|
let originalHtmlBody = composeDetails.body + " ";
|
||||||
|
|
@ -403,3 +426,17 @@ export async function migrateDefaultPromptsPropStorage(){
|
||||||
await browser.storage.sync.remove("_default_prompts_properties");
|
await browser.storage.sync.remove("_default_prompts_properties");
|
||||||
// console.log("migrateDefaultPromptsPropStorage: migrated default prompts properties from storage.sync to storage.local");
|
// console.log("migrateDefaultPromptsPropStorage: migrated default prompts properties from storage.sync to storage.local");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function* getMessages(list) {
|
||||||
|
let page = await list;
|
||||||
|
for (let message of page.messages) {
|
||||||
|
yield message;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (page.id) {
|
||||||
|
page = await messenger.messages.continueList(page.id);
|
||||||
|
for (let message of page.messages) {
|
||||||
|
yield message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,9 @@ import { mzta_script } from './js/mzta-chatgpt.js';
|
||||||
import { prefs_default } from './options/mzta-options-default.js';
|
import { prefs_default } from './options/mzta-options-default.js';
|
||||||
import { mzta_Menus } from './js/mzta-menus.js';
|
import { mzta_Menus } from './js/mzta-menus.js';
|
||||||
import { taLogger } from './js/mzta-logger.js';
|
import { taLogger } from './js/mzta-logger.js';
|
||||||
import { getCurrentIdentity, getOriginalBody, replaceBody, setBody, i18nConditionalGet, generateCallID, migrateCustomPromptsStorage, migrateDefaultPromptsPropStorage, getGPTWebModelString, getTagsList, createTag, assignTagsToMessage, checkIfTagExists, getActiveSpecialPromptsIDs, checkSparksPresence } from './js/mzta-utils.js';
|
import { getCurrentIdentity, getOriginalBody, replaceBody, setBody, i18nConditionalGet, generateCallID, migrateCustomPromptsStorage, migrateDefaultPromptsPropStorage, getGPTWebModelString, getTagsList, createTag, assignTagsToMessage, checkIfTagExists, getActiveSpecialPromptsIDs, checkSparksPresence, getMessages, getMailBody } from './js/mzta-utils.js';
|
||||||
|
import { taPromptUtils } from './js/mzta-utils-prompt.js';
|
||||||
|
import { mzta_specialCommand } from './js/mzta-special-commands.js';
|
||||||
|
|
||||||
await migrateCustomPromptsStorage();
|
await migrateCustomPromptsStorage();
|
||||||
await migrateDefaultPromptsPropStorage();
|
await migrateDefaultPromptsPropStorage();
|
||||||
|
|
@ -28,7 +30,9 @@ await migrateDefaultPromptsPropStorage();
|
||||||
var original_html = '';
|
var original_html = '';
|
||||||
var modified_html = '';
|
var modified_html = '';
|
||||||
|
|
||||||
let prefs_init = await browser.storage.sync.get({do_debug: false, add_tags: true, get_calendar_event: true, connection_type: 'chatgpt_web'});
|
let prefs_init = {};
|
||||||
|
await reload_pref_init();
|
||||||
|
|
||||||
let taLog = new taLogger("mzta-background",prefs_init.do_debug);
|
let taLog = new taLogger("mzta-background",prefs_init.do_debug);
|
||||||
|
|
||||||
let special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, await doGetCalendarEvent(prefs_init.get_calendar_event), (prefs_init.connection_type === "chatgpt_web"));
|
let special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, await doGetCalendarEvent(prefs_init.get_calendar_event), (prefs_init.connection_type === "chatgpt_web"));
|
||||||
|
|
@ -134,6 +138,24 @@ async function _reload_menus() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function _assign_tags(_data, create_new_tags = true) {
|
||||||
|
let all_tags_list = await getTagsList();
|
||||||
|
all_tags_list = all_tags_list[1];
|
||||||
|
// console.log(">>>>>>>>>>>>>>> all_tags_list: " + JSON.stringify(all_tags_list));
|
||||||
|
taLog.log("assign_tags data: " + JSON.stringify(_data));
|
||||||
|
let new_tags = [];
|
||||||
|
for (const tag of _data.tags) {
|
||||||
|
// console.log(">>>>>>>>>>>>>>> tag: " + tag);
|
||||||
|
if (create_new_tags && !checkIfTagExists(tag, all_tags_list)) {
|
||||||
|
taLog.log("Creating tag: " + tag);
|
||||||
|
await createTag(tag);
|
||||||
|
}
|
||||||
|
new_tags.push(tag);
|
||||||
|
}
|
||||||
|
await assignTagsToMessage(_data.messageId, new_tags);
|
||||||
|
taLog.log("Assigned tags: " + JSON.stringify(new_tags));
|
||||||
|
}
|
||||||
|
|
||||||
messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
// Check what type of message we have received and invoke the appropriate
|
// Check what type of message we have received and invoke the appropriate
|
||||||
// handler function.
|
// handler function.
|
||||||
|
|
@ -240,24 +262,7 @@ messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
return _popup_menu_ready();
|
return _popup_menu_ready();
|
||||||
break;
|
break;
|
||||||
case 'assign_tags':
|
case 'assign_tags':
|
||||||
async function _assign_tags() {
|
return _assign_tags(message);
|
||||||
let all_tags_list = await getTagsList();
|
|
||||||
all_tags_list = all_tags_list[1];
|
|
||||||
// console.log(">>>>>>>>>>>>>>> all_tags_list: " + JSON.stringify(all_tags_list));
|
|
||||||
taLog.log("assign_tags data: " + JSON.stringify(message));
|
|
||||||
let new_tags = [];
|
|
||||||
for (const tag of message.tags) {
|
|
||||||
// console.log(">>>>>>>>>>>>>>> tag: " + tag);
|
|
||||||
if (!checkIfTagExists(tag, all_tags_list)) {
|
|
||||||
taLog.log("Creating tag: " + tag);
|
|
||||||
await createTag(tag);
|
|
||||||
}
|
|
||||||
new_tags.push(tag);
|
|
||||||
}
|
|
||||||
await assignTagsToMessage(message.messageId, new_tags);
|
|
||||||
taLog.log("Assigned tags: " + JSON.stringify(new_tags));
|
|
||||||
}
|
|
||||||
return _assign_tags();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -596,7 +601,7 @@ async function doGetCalendarEvent(get_calendar_event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reload_pref_init(){
|
async function reload_pref_init(){
|
||||||
prefs_init = await browser.storage.sync.get({do_debug: false, add_tags: true, get_calendar_event: true, connection_type: 'chatgpt_web'});
|
prefs_init = await browser.storage.sync.get({do_debug: false, add_tags: true, get_calendar_event: true, connection_type: 'chatgpt_web', add_tags_auto: false, add_tags_auto_force_existing: false, add_tags_auto_only_inbox: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -639,7 +644,85 @@ function setupStorageChangeListener() {
|
||||||
// Call the function to set up the listener
|
// Call the function to set up the listener
|
||||||
setupStorageChangeListener();
|
setupStorageChangeListener();
|
||||||
|
|
||||||
|
|
||||||
// Menus handling
|
// Menus handling
|
||||||
const menus = new mzta_Menus(openChatGPT, prefs_init.do_debug);
|
const menus = new mzta_Menus(openChatGPT, prefs_init.do_debug);
|
||||||
menus.loadMenus(special_prompts_ids);
|
menus.loadMenus(special_prompts_ids);
|
||||||
|
|
||||||
|
|
||||||
|
// Listening for new received emails
|
||||||
|
const newEmailListener = (folder, messagesList) => {
|
||||||
|
taLog.log("New mail received");
|
||||||
|
taLog.log(`Folder: ${folder.name}`);
|
||||||
|
|
||||||
|
async function _newEmailListener(){
|
||||||
|
let messages = getMessages(messagesList);
|
||||||
|
|
||||||
|
for await (let message of messages) {
|
||||||
|
let fullMessage = await browser.messages.getFull(message.id);
|
||||||
|
|
||||||
|
taLog.log(`From: ${fullMessage.headers.from}`);
|
||||||
|
taLog.log(`Subject: ${fullMessage.headers.subject}`);
|
||||||
|
taLog.log(`Name: ${fullMessage.name}`);
|
||||||
|
taLog.log(`Body: ${fullMessage.body}`);
|
||||||
|
taLog.log(`contentType: [${fullMessage.contentType}]`);
|
||||||
|
taLog.log(`fullMessage.parts.length: ${fullMessage.parts.length}`);
|
||||||
|
|
||||||
|
if (fullMessage.parts.length > 0) {
|
||||||
|
for (let part of fullMessage.parts) {
|
||||||
|
taLog.log(`From: ${part.headers.from}`);
|
||||||
|
taLog.log(`Subject: ${part.headers.subject}`);
|
||||||
|
taLog.log(`Name: ${part.name}`);
|
||||||
|
taLog.log(`Body: ${part.body}`);
|
||||||
|
taLog.log(`contentType: [${part.contentType}]`);
|
||||||
|
taLog.log('contentType JSON: '+JSON.stringify(part.contentType));
|
||||||
|
if (part.contentType.trim().toLowerCase() === "text/plain") {
|
||||||
|
taLog.log("Body (text/plain):" + part.body);
|
||||||
|
// return part.body;
|
||||||
|
}
|
||||||
|
if (part.contentType.trim().toLowerCase() === "text/html") {
|
||||||
|
taLog.log("Body (text/html):" + part.body);
|
||||||
|
// return part.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let specialFullPrompt = '';
|
||||||
|
let curr_fullMessage = null;
|
||||||
|
|
||||||
|
// if some auto feature is active prepare some data
|
||||||
|
// this will be used when will be implemented the spam filter (https://github.com/micz/ThunderAI/issues/231)
|
||||||
|
// or the auto translator https://github.com/micz/ThunderAI/issues/247
|
||||||
|
if(prefs_init.add_tags_auto){
|
||||||
|
curr_fullMessage = await browser.messages.getFull(message.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto add_tags
|
||||||
|
if(prefs_init.add_tags_auto){
|
||||||
|
let curr_prompt_add_tags = menus.allPrompts.find(p => p.id === 'prompt_add_tags');
|
||||||
|
let chatgpt_lang = taPromptUtils.getDefaultLang(curr_prompt_add_tags);
|
||||||
|
let msg_text = await getMailBody(curr_fullMessage);
|
||||||
|
let body_text = msg_text.text.replace(/\s+/g, ' ').trim();
|
||||||
|
let tags_full_list = await getTagsList();
|
||||||
|
specialFullPrompt = await taPromptUtils.preparePrompt(curr_prompt_add_tags, message, chatgpt_lang, /*selection_text*/ '', body_text, curr_fullMessage.headers.subject, msg_text, /*only_typed_text*/ '', tags_full_list);
|
||||||
|
let prefs_aat = await browser.storage.sync.get({add_tags_maxnum: 3, connection_type: '', add_tags_force_lang: true, default_chatgpt_lang: '', add_tags_auto_force_existing: false});
|
||||||
|
specialFullPrompt = taPromptUtils.finalizePrompt_add_tags(specialFullPrompt, prefs_aat.add_tags_maxnum, prefs_aat.add_tags_force_lang, prefs_aat.default_chatgpt_lang);
|
||||||
|
taLog.log("Special prompt: " + specialFullPrompt);
|
||||||
|
let cmd_addTags = new mzta_specialCommand(specialFullPrompt,prefs_aat.connection_type,prefs_init.do_debug);
|
||||||
|
await cmd_addTags.initWorker();
|
||||||
|
let tags_current_email = '';
|
||||||
|
try{
|
||||||
|
tags_current_email = (await cmd_addTags.sendPrompt()).trim();
|
||||||
|
}catch(err){
|
||||||
|
console.error("[ThunderAI | Auto add_tags] Error getting tags: ", err);
|
||||||
|
}
|
||||||
|
taLog.log("tags_current_email: " + tags_current_email);
|
||||||
|
let _data = {messageId: message.id, tags: tags_current_email.split(/,\s*/)};
|
||||||
|
_assign_tags(_data, !prefs_aat.add_tags_auto_force_existing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _newEmailListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.messages.onNewMailReceived.addListener(newEmailListener, !prefs_init.add_tags_auto_only_inbox);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ export const prefs_default = {
|
||||||
chatgpt_win_height: 800,
|
chatgpt_win_height: 800,
|
||||||
chatgpt_win_width: 700,
|
chatgpt_win_width: 700,
|
||||||
default_chatgpt_lang: '',
|
default_chatgpt_lang: '',
|
||||||
|
default_sign_name: '',
|
||||||
connection_type: 'chatgpt_web', //Other values: 'chatgpt_api', 'ollama_api', 'openai_comp_api', 'google_gemini_api'
|
connection_type: 'chatgpt_web', //Other values: 'chatgpt_api', 'ollama_api', 'openai_comp_api', 'google_gemini_api'
|
||||||
chatgpt_web_model: '',
|
chatgpt_web_model: '',
|
||||||
chatgpt_web_tempchat: false,
|
chatgpt_web_tempchat: false,
|
||||||
|
|
@ -46,5 +47,8 @@ export const prefs_default = {
|
||||||
add_tags_hide_exclusions: false,
|
add_tags_hide_exclusions: false,
|
||||||
add_tags_first_uppercase: true,
|
add_tags_first_uppercase: true,
|
||||||
add_tags_force_lang: true,
|
add_tags_force_lang: true,
|
||||||
|
add_tags_auto: false,
|
||||||
|
add_tags_auto_force_existing: false,
|
||||||
|
add_tags_auto_only_inbox: true,
|
||||||
get_calendar_event: true,
|
get_calendar_event: true,
|
||||||
}
|
}
|
||||||
|
|
@ -9,6 +9,10 @@
|
||||||
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
||||||
<h2>Version 3.2.0 - ??/??/2025</h2>
|
<h2>Version 3.2.0 - ??/??/2025</h2>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>Added an option to automatically tag incoming emails [<a href="https://github.com/micz/ThunderAI/issues/237">#237</a>].</li>
|
||||||
|
<li>Added the <i>{%thunderai_def_sign%}</i> placeholder to get the default signature as defined in the options [<a href="https://github.com/micz/ThunderAI/issues/248">#248</a>].</li>
|
||||||
|
<li>Added the <i>{%thunderai_def_lang%}</i> placeholder to get the default language as defined in the options [<a href="https://github.com/micz/ThunderAI/issues/248">#248</a>].</li>
|
||||||
|
<li>Various minor improvements.</li>
|
||||||
<li>...</li>
|
<li>...</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2>Version 3.1.2 - 29/01/2025</h2>
|
<h2>Version 3.1.2 - 29/01/2025</h2>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addtags_info_additional_statements{
|
#addtags_info_additional_statements, #add_tags_auto_force_existing_tr, #add_tags_auto_only_inbox_tr{
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,33 @@
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class="add_tags_tr">
|
||||||
|
<td><span>__MSG_prefs_OptionText_add_tags_auto__</span></td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="add_tags_auto" name="add_tags_auto" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_add_tags_auto_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="add_tags_tr" id="add_tags_auto_force_existing_tr">
|
||||||
|
<td><span>__MSG_prefs_OptionText_add_tags_auto_force_existing__</span></td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="add_tags_auto_force_existing" name="add_tags_auto_force_existing" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_add_tags_auto_force_existing_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="add_tags_tr" id="add_tags_auto_only_inbox_tr">
|
||||||
|
<td><span>__MSG_prefs_OptionText_add_tags_auto_only_inbox__</span></td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="add_tags_auto_only_inbox" name="add_tags_auto_only_inbox" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_add_tags_auto_only_inbox_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div id="addtags_prompt_container">
|
<div id="addtags_prompt_container">
|
||||||
<span class="section_title">__MSG_AddTags_prompt_text_title__</span><span id="addtags_prompt_unsaved" class="unsaved hidden"> __MSG_customPrompts_unsaved_changes__</span>
|
<span class="section_title">__MSG_AddTags_prompt_text_title__</span><span id="addtags_prompt_unsaved" class="unsaved hidden"> __MSG_customPrompts_unsaved_changes__</span>
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,16 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let add_tags_auto_el = document.getElementById('add_tags_auto');
|
||||||
|
let add_tags_auto_force_existing_tr = document.getElementById('add_tags_auto_force_existing_tr');
|
||||||
|
let add_tags_auto_only_inbox_tr = document.getElementById('add_tags_auto_only_inbox_tr');
|
||||||
|
add_tags_auto_el.addEventListener('click', (event) => {
|
||||||
|
add_tags_auto_force_existing_tr.style.display = event.target.checked ? 'table-row' : 'none';
|
||||||
|
add_tags_auto_only_inbox_tr.style.display = event.target.checked ? 'table-row' : 'none';
|
||||||
|
});
|
||||||
|
add_tags_auto_force_existing_tr.style.display = add_tags_auto_el.checked ? 'table-row' : 'none';
|
||||||
|
add_tags_auto_only_inbox_tr.style.display = add_tags_auto_el.checked ? 'table-row' : 'none';
|
||||||
|
|
||||||
addtags_reset_btn.addEventListener('click', () => {
|
addtags_reset_btn.addEventListener('click', () => {
|
||||||
addtags_textarea.value = browser.i18n.getMessage('prompt_add_tags_full_text');
|
addtags_textarea.value = browser.i18n.getMessage('prompt_add_tags_full_text');
|
||||||
addtags_reset_btn.disabled = true;
|
addtags_reset_btn.disabled = true;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue