highlight matched content of gmail message

The use case of my application is to fetch the list of topics from an api and parse the content
form the currently opened gmail messages. I have fetched the topics from my own api and also
parsed the content from the currently opened gmail messages using gmail api by querying to
following api

https://www.googleapis.com/gmail/v1/users/userId/messages/id

This would give the all the content that is in gmail messages in string format. I used
the indexOf to match up to 6 topics but could not highlight in the gmail messages.

How do i now highlight and make it hyperlink?

Here is what I have done

function fetchTopics() {
    console.log('fetchTopics started');
    chrome.storage.sync.get(['user_token', 'gmail_token'], function(result) {
        const decoded = JSON.parse(atob(result.user_token));
        const access_token = decoded['access-token'];
        const gmail_token = result.gmail_token;
        const email = decoded['uid'];
        const headers = new Headers();
        headers.append('Access-Token', access_token);
        headers.append('Client', decoded['client']);
        headers.append('uid', email);
        headers.append('Expiry', decoded['expiry']);
        headers.append('Token-Type', decoded['token-type']);
        const apiUrl = `https://db7aa429.ngrok.io/useful_topics`;
        fetch(apiUrl, {
            method: 'GET',
            headers
        })
            .then(function(response) {
                return response.json();
            })
            .then(function(data) {
                console.log('data', data);
                window.chrome.storage.sync.set(
                    { user_topics: data.topics },
                    function() {
                        searchPage(data, gmail_token);
                    }
                );
            });
    });
}

function searchPage(topic, token) {
    // sample https://www.googleapis.com/gmail/v1/users/userId/messages/id
    const userId = '[email protected]';
    const messageId = location.hash.split('/')[1];
    console.log('messageId', messageId);
    const apiUrl = `https://www.googleapis.com/gmail/v1/users/${userId}/messages/${messageId}`;
    const headers = new Headers();
    headers.append('Authorization', `Bearer ${token}`);
    fetch(apiUrl, {
        method: 'GET',
        headers
    })
        .then(function(response) {
            return response.json();
        })
        .then(function(data) {
            highlight(topic, data);
        });
}

function highlight(topics, data) {
    let contents = '';
    switch (data.payload.mimeType) {
        case 'text/html':
            contents = data.payload.body.data;
            break;
        case 'multipart/alternative':
            contents =
                data.payload.parts &&
                (data.payload.parts[0].body.data || data.payload.parts[1].body.data);
            break;
        default:
            contents =
                data.payload.body.data ||
                (data.payload.parts &&
                    (data.payload.parts[0].body.data || data.payload.parts[1].body.data));
            break;
    }
    const decodeContent = atob(contents.replace(/-/g, '+').replace(/_/g, '/'));
    let found = 0;
    for (var key in topics.topics) {
        console.log('key', key);
        if (topics.topics.hasOwnProperty(key)) {
            if (decodeContent.indexOf(key) >= 0) {
                found += 1;
                if (found <= 6) {
                    console.log('key', key, found);
          // how do i highlight and make the matced content hyperlink
                } else {
                    return;
                }
            }
        }
    }
}

// Run when the whole document loads
$(window).bind('load', function() {
    const emailDOM = document.getElementsByClassName('gb_Db');
    if (emailDOM) {
        window.chrome.storage.sync.set(
            { user_email: emailDOM[0].innerText },
            function() {}
        );
    }
    document.addEventListener('click', init);
});

// Run on every hash change (when opening new mail)
$(window).on('hashchange', function() {
    console.log('location', location.hash.split('/'));
    if (location.hash.split('/')[1]) {
        window.chrome.storage.sync.get(['user_topics'], function(result) {
            if (!result.user_topics) {
                fetchTopics();
            } else {
                topics['topics'] = result.user_topics;
                chrome.storage.sync.get(['gmail_token'], function(result) {
                    if (result.gmail_token) {
                        searchPage(topics, result.gmail_token);
                    }
                });
            }
        });
    }
});

“view_thread” event of Gmail.js of Kartik Talwar not working

I am working on chrome extension. In which I am currently using the following event:

gmail.observe.on('view_thread', function(obj) {
  console.log('conversation thread opened', obj); // gmail.dom.thread object
});

Previously it is working fine. But due to some reasons recently it stopped working (might be some UI changes made by Gmail)

Here is the reference for gmail.js that I am using: https://github.com/KartikTalwar/gmail.js

Please help me how to correct this.

highlight max 6 word from gmail messages

The use case of my extension is when the user opens up the Gmail, fire an API call and fetch the list of topics(the topics can be more than 500). Then when the user opens up the message, if from that fetched topics any max 6 words match with the word in the opened message, it should be highlighted.

For example

If the fetched topic has following topics

topics: {
  hello: 10,
  how: 1,
  mandy: 12,
  google: 90,
  extension: 13,
  local: 20
}

And I have a Gmail message as following

hello, my name is mandy. I work at google. 

then the word hello, mandy and google should get highlighted because, those word from the message matched with the topics object.

For now, I could fetch the topic object and pass that topic object to the function searchPage but does not know the way to match.

Here is what I have done till now

function fetchTopics() {
    const apiUrl = `https://baseurl.ngrok.io/useful_topics`;
    chrome.storage.sync.get(['user_token'], function(result) {
        const decoded = JSON.parse(atob(result.user_token));
        const access_token = decoded['access-token'];
        const headers = new Headers();
        headers.append('Access-Token', access_token);
        fetch(apiUrl, {
            method: 'GET',
            headers
        })
            .then(function(response) {
                return response.json();
            })
            .then(function(data) {
                searchPage(data);
                // for (var key in data) {
                //  if (data.hasOwnProperty(key)) {
                //      searchPage(key);
                //  }
                // }
            });
    });
}


function searchPage(topicObj) {
  console.log('topicObj', topicObj);
  // read all the words in the currently opened gmail messages and highlight any max 
  // 6 words in the message if there is a match 
}

I will have topicObj in following format(hashmap structure)

topics: {
  hostname: 4,
  cto: 19,
  maharjan: 45,
  aws: 382,
  axosoft: 66,
  its: 26,
  repo: 15,
  anurag: 585,
  unsubscribe: 65,
  bitbucket: 313,
  having: 28,
  devops: 414,
}

Retrieve Gmail access_token

I need to find the google access_token that is sent to the browser after user logs in to GMail. It should be somewhere among cookies or in a browser local storage.

The problem is that the
chrome.identity.launchWebAuthFlow({url: authURL, interactive: true}, cb)
wants from the user to choose the account again even when he is already logged in to GMail.

What I really want is something similar to Microsoft Outlook Office.context.mailbox.getCallbackTokenAsync that allows to the logged user using Microsoft REST API without authenticating again.

“Error: Invocation of form set() doesn’t match definition set(object items, optional function callback)”

i have a gmail extension which uses ,
chrome.storage.local.set methods in content script.
it works well for extension, but when extension off and the on or extension not uses for a long time and then uses , it shows an error like

“Error: Invocation of form set() doesn’t match definition set(object items, optional function callback)”

when the page reloads it again works well. I need a solution to work this without page reload

Edit: i added the below code in background.js asper @wOxxOm, but it still shows the same error

var manifest = chrome.app.getDetails();
chrome.windows.getAll({populate:true},function(windows){
  windows.forEach(function(window){
    window.tabs.forEach(function(tab){
        var url = tab.url; 
        if(url.indexOf('https://mail.google.com') > -1){ 
             var  scripts= manifest.content_scripts[0].js;  
             s = scripts.length;  
            for(var k = 0 ; k < s; k++ ) {  
              chrome.tabs.executeScript(tab.id, {
                file: scripts[k]
              });
            }
        }

    });
  });
});

also the listner in content script

    chrome.extension.onMessage.addListener(
    function doListen(request){
        chrome.extension.onRequest.removeListener(doListen);
        if (request.data && request.types && request.types =='MESSAGE_COMPOSE') {
            window.postMessage({ type: "MESSAGE_COMPOSE",email:request.data}, "*");
        }
    }
);

find owner’s gmail address

Before coming to the problem, the use case of my extension is to redirect to my web application with the selected content on gmail. For this, the gmail address of the loaded gmail should match with the email address that is registered for using my web application. For example, if i have signup the web app with gmail address – [email protected] and now if i open the gmail with the same gmail address i.e [email protected] then the user should be allowed to use extension but if i opened the gmail of [email protected] then i should not able to use the extension because the opened gmail account’s email address does not match with the email registered in web app.

I have created a login in the popup.js for authentication and it works but I have no idea on how to get the owner’s email address of that opened gmail so i can match if logged in account has the same email address or not. How can i do this so? Can anyone guide me on this, please?

How to Block Image Loading in GMAILS Chrome Extension?

In my simple gmail chrome extension – I want to prevent loading of image in a sent mail.

Inside chrome.webRequest.onBeforeRequest.addListener is working when I include

urls: [ "*://*.googleusercontent.com/*" ]

in the urls array. But this will fire for all the images I only want to fire for this pattern "*://*/#https://mysite/*",

But it is not firing at all – If I include googleusercontent url it is working with details.url in this format –

https://ci6.googleusercontent.com/proxy/IB4W2KvisZjL2rgC....#https://mysite/*

MANIFEST

"permissions": [
    "webRequest",
    "webRequestBlocking",
    "*://*.googleusercontent.com/*",
    "*://*/#https://track1/*",
    "*://*.googleusercontent.com/*/://track1/*"
],

and in the background script

chrome.webRequest.onBeforeRequest.addListener(
        function(details) {
            console.log(details);    
        }, {
        urls: [
            "*://*/#https://track1/*",
        ]
       }, ['blocking']
 );

I think issue is with patter matching but I am not able to understand which is the right pattern to use

window.GLOBALS[17] is null in the new Gmail UI while it is present for the old Gmail UI

I have a Chrome extension which uses a library called gmail.js which is sort of dependent on the window.GLOBALS[17] object from the Gmail window however in the new UI of gmail, Gmail seems to have removed the GLOBALS[17] which is equal to null now, Now I have no way to access the data that was present inside the GLOBALS[17] object, I have searched, looked and tried everything but do not seem to have an alternative to GLOBALS[17] object

The GLOBALS[17] is still available on the old Gmail UI

When seen in old Gmail UI

And is null in new Gmail UI

Wheen seen from new Gmail UI

Without this I cannot know vital information like whether the email is in conversation view and so on

Why was this removed? Is there an alternative?

How to programmatically detect new Gmail UI?

Google released new UI for Gmail which can be activated from ‘Settings’ -> ‘Try the new Gmail’.

The question: is there a way to programmatically check that new Gmail UI is activated in a web browser from Chrome extension?

Gmail Chrome extensions: get PDF with email body

I have build a chrome extension that sends the attachments of an email to a web service.

I use the gmail-js module to access the email information and the binaries of the attachments.

Now I have to get a PDF with the full conversation and send to another web service.

How can I get the binary of the print version of the full email threads with this module (or another)?