Search code examples
javascriptgoogle-chrome-extensioninbox

Chrome Gmail extension does not work in certain circumstances. Why?


I'm working on a Chrome extension. When a local PDF file is opened in Chrome, by clicking on the extension icon, it opens a new tab with gmail.com (and compose view) and attaches the opened file to a new email.

With a "normal" Gmail account, it works fine. The problem is, if I use an account with alias senders (e.g. personal and business), the attaching doesn't always happen. Sometimes it attaches the file, sometimes doesn't. If it failes the following error message appers in console: www.inboxsdk.com/build/platform-implementation.js:18 Error logged: Error: Failed to find dropzone

What is wrong with the code?

app.js

var content = {
init() {
    //this is gmail page
    InboxSDK.load(2, 'sdk_Add-Attachment_df7347fce8').then((sdk) => {
        chrome.runtime.sendMessage({
            message: "getFile",
        }, (response) => {
            if (response.file != 'No File Found') {
                sdk.Compose.registerComposeViewHandler((composeView) => {
                    chrome.runtime.sendMessage({
                        message: "getFile",
                    }, (response) => {
                        console.log("uploaded file", response.file);
                        if (response.file != 'No File Found') {
                            var fileData = content.base64ToArrayBuffer(response.file);
                            var file = new File([fileData], response.fileName, {
                                type: response.fileType
                            });
                            composeView.attachFiles([file]);
                            chrome.runtime.sendMessage({
                                message: "deleteFile",
                            });
                        }
                    });
                });
                sdk.Compose.openNewComposeView().then((composeView) => {
                    console.log("composeView is", composeView);
                });
            } else {
                console.log("No file to add");
            }
        });
    });
},
base64ToArrayBuffer(base64) {
    var binaryString = window.atob(base64);
    var binaryLen = binaryString.length;
    var bytes = new Uint8Array(binaryLen);
    for (var i = 0; i < binaryLen; i++) {
        var ascii = binaryString.charCodeAt(i);
        bytes[i] = ascii;
    }
    return bytes;
}
};
$(document).ready(() => {
    content.init();
})

background.js:

chrome.browserAction.onClicked.addListener(function(tab) {
if (tab.url.indexOf("file://") != -1) {
    //this is file page
    localStorage.setItem('FileUrl', tab.url);
    console.log('Saved file to be attached', tab.url);
    window.open('https://mail.google.com');
} else {
    alert("Please open tab with url beginning with file:// and try again.");
}
});

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.message == "getFile") {
        var request = new XMLHttpRequest();
        var fileUrl = localStorage.getItem('FileUrl');
        if (fileUrl != 'undefined' && fileUrl != null) {
            var fileName = fileUrl.split('/').pop();
            request.open('GET', fileUrl, true);
            request.responseType = 'blob';
            request.onload = function() {
                var reader = new FileReader();
                reader.readAsDataURL(request.response);
                reader.onload = function(e) {
                    console.log('DataURL:', e.target.result);
                    const byteString = atob(e.target.result.split('base64,')[1]);
                    const ab = new ArrayBuffer(byteString.length);
                    const ia = new Uint8Array(ab);
                    for (let i = 0; i < byteString.length; i += 1) {
                        ia[i] = byteString.charCodeAt(i);
                    }
                    const newBlob = new Blob([ab], {
                        type: 'application/pdf'
                    });
                    sendResponse({
                        file: e.target.result.split('base64,')[1],
                        fileName: fileName,
                        fileType: 'application/pdf'
                    });
                };
            };
            request.send();
        } else {
            sendResponse({
                file: 'No File Found'
            });
        }
        return true;
    } else if (request.message == "deleteFile") {
        localStorage.removeItem('FileUrl');
        return true;
    }
});

Solution

  • Instead of composeView.attachFiles([file]) use this:

    composeView.getBodyElement().focus();
    setTimeout(function() {composeView.attachFiles([file])}, 1000);
    

    Or, alternatively:

    composeView.attachInlineFiles([file]);