I'm trying to create an iframe and inject it into the webpage when the webpage is loaded, But when I try to do that the content script is injecting the iframe inside all the iframes on the webpage, I have used the chrome.runtime.onMessage.addListener to be used to toggle the iframe when the user clicks on the extension icon so I'm sending a message from background script to handle this however I'm sending the message only once from the background script but chrome.runtime.onMessage.addListener is getting fired multiple times I'm not sure why
This is what is happening
This is the content script
var iframeContainer = undefined;
window.onload = function () {
injectPopup();
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.message == "togglePopup") {
console.log("message arrived");
var appBody = document.getElementById("app-container");
if (appBody.style.display == "none") {
console.log("posting message");
iframeContainer.contentWindow.postMessage(
JSON.stringify({
user: request.user,
token: request.token,
}),
"*",
[]
);
appBody.style.display = "block";
} else {
appBody.style.display = "none";
}
}
});
};
// window.addEventListener("message", function (e) {
// if (JSON.parse(e.data)) {
// const data = JSON.parse(e.data);
// if (data.message) {
// if (data.message == "toggleApp") {
// var appBody = document.getElementById("app-container");
// appBody.style.display = "none";
// }
// }
// }
// });
function injectPopup() {
console.log("inject popup");
iframeContainer = document.createElement("iframe");
console.log(iframeContainer);
iframeContainer.allowFullscreen = false;
iframeContainer.src = chrome.runtime.getURL("/index.html");
iframeContainer.id = "app-container-iframe";
const appContainer = document.createElement("div");
appContainer.id = "app-container";
appContainer.style.display = "none";
console.log(appContainer);
const resizeHandle = document.createElement("div");
resizeHandle.id = "resize-container-handle";
resizeHandle.classList.add("ui-resizable-handle");
resizeHandle.classList.add("ui-resizable-w");
resizeHandle.innerHTML =
'<div class="resize-handle-horizontal-bar"></div><div class="resize-handle-horizontal-bar"></div><div class="resize-handle-horizontal-bar"></div>';
appContainer.appendChild(resizeHandle);
document.querySelector("body").appendChild(appContainer);
appContainer.appendChild(iframeContainer);
$("#app-container").resizable({
handles: { w: "#resize-container-handle" },
});
}
This is the background script from which I'm sending the message
var userLoggedIn = {};
const openTabs = [];
const apiUrl = "http://localhost:5000";
var popupOpen = false;
var currentWindow = undefined;
window.onload = () => {
popupOpen = false;
};
chrome.storage.local.get("token", function (result) {
userLoggedIn = result.token;
chrome.browserAction.onClicked.addListener(function (tab) {
const width = 500;
const height = 900;
const left = screen.width / 2 - width / 2;
const top = screen.height / 2 - height / 2;
console.log("clicked!");
if (!userLoggedIn) {
if (currentWindow == undefined) {
chrome.windows.create(
{
url: "/html/auth.html",
width: width,
height: height,
left: left,
top: top,
focused: true,
},
(window) => {
currentWindow = window;
chrome.windows.onRemoved.addListener(function (id) {
if (currentWindow.id == id) {
currentWindow = undefined;
}
});
}
);
}
} else {
console.log("hi!");
chrome.windows.getCurrent((w) => {
chrome.tabs.query(
{
active: true,
currentWindow: true,
},
function (tabs) {
const userData = parseJwt(userLoggedIn);
console.log("sending message");
chrome.tabs.sendMessage(tabs[0].id, {
message: "togglePopup",
user: userData,
token: userLoggedIn,
});
}
);
});
}
});
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.message === "login") {
loginUser(request.payload)
.then(function (res) {
if (res.ok) {
return res.json();
} else {
sendResponse({
message: "error",
});
}
})
.then(function (data) {
chrome.storage.local.set({ token: data.token }, function (result) {
chrome.windows.remove(currentWindow.id);
const userData = parseJwt(data.token);
userLoggedIn = data.token;
chrome.tabs.query(
{
active: true,
currentWindow: true,
},
function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "togglePopup",
payload: {
user: userData,
token: userLoggedIn,
},
});
}
);
sendResponse({ message: "success" });
});
})
.catch(function (err) {
console.log(err);
});
return true;
} else if (request.message === "register") {
registerUser(request.payload)
.then(function (res) {
if (res.ok) {
return res.json();
} else {
sendResponse({
message: "error",
});
}
})
.then(function (data) {
console.log(data);
sendResponse({ message: "success" });
})
.catch(function (err) {
console.log(err);
});
} else if (request.message === "logout") {
} else if (request.message === "userStatus") {
} else if (request.message === "closePopup") {
const index = getIndexOfTab(sender.tab.id, openTabs);
openTabs[index].popupOpen = false;
}
});
});
chrome.tabs.sendMessage sends the message to all frames of the tab per the documentation.
You can limit it to the main page via frameId:
chrome.tabs.sendMessage(tabId, {foo: 'bar'}, {frameId: 0});
Related
Currently working on a 1:1 live chat messenger. when i send a message its shows up at the bottom of chat where i want it to, but upon page refresh it returns to the top of the messenger. How do i set it so newest message is always at the bottom? heres some code i believe the problem is in setActiveChat or or addMessageToConversation.
const sendMessage = (data, body) => {
socket.emit("new-message", {
message: data.message,
recipientId: body.recipientId,
sender: data.sender,
});
};
const postMessage = async (body) => {
try {
const data = await saveMessage(body);
if (!body.conversationId) {
addNewConvo(body.recipientId, data.message);
} else {
addMessageToConversation(data);
}
sendMessage(data, body);
} catch (error) {
console.error(error);
}
};
const addNewConvo = useCallback(
(recipientId, message) => {
setConversations(previousState => previousState.map(convo => {
if (convo.otherUser.id === recipientId) {
convo.messages.push(message)
convo.latestMessageText = message.text;
convo.id = message.conversationId;
return convo
}
return convo
}))
},
[setConversations],
);
const addMessageToConversation = useCallback(
(data) => {
// if sender isn't null, that means the message needs to be put in a brand new convo
const { message, sender = null } = data;
if (sender !== null) {
const newConvo = {
id: message.conversationId,
otherUser: sender,
messages: [message],
};
newConvo.latestMessageText = message.text;
setConversations((prev) => [newConvo, ...prev]);
}
conversations.forEach((convo) => {
if (convo.id === message.conversationId) {
const convoCopy = { ...convo };
convoCopy.messages.push(message);
convoCopy.latestMessageText = message.text;
return convoCopy;
} else {
return convo;
}
});
setConversations([...conversations]);
},
[setConversations, conversations],
);
const setActiveChat = useCallback((username) => {
setActiveConversation(username);
}, []);
so i have my webRTC python server that streams audio and video to the browser via js in video and audio tag form
Now what can I do to record this stream on frontend I'm asking because i my current solution based solely on python and openCV it is to slow for modern era so Im re writing my whole project with different approach and now i'm stuck
html
Start
Stop
<div id="media">
<audio id="audio" autoplay="true"></audio>
<video id="video" autoplay="true" playsinline="true"></video>
</div>
js
var pc = null;
var dc = null, dcInterval = null;
function createPeerConnection() {
var config = {
sdpSemantics: 'unified-plan'
};
pc = new RTCPeerConnection(config);
pc.addEventListener('track', function(evt) {
if (evt.track.kind == 'video')
document.getElementById('video').srcObject = evt.streams[0];
else
document.getElementById('audio').srcObject = evt.streams[0];
});
return pc;
}
function negotiate() {
return pc.createOffer().then(function(offer) {
return pc.setLocalDescription(offer);
}).then(function() {
return new Promise(function(resolve) {
if (pc.iceGatheringState === 'complete') {
resolve();
} else {
function checkState() {
if (pc.iceGatheringState === 'complete') {
pc.removeEventListener('icegatheringstatechange', checkState);
resolve();
}
}
pc.addEventListener('icegatheringstatechange', checkState);
}
});
}).then(function() {
var offer = pc.localDescription;
return fetch('/offer', {
body: JSON.stringify({
sdp: offer.sdp,
type: offer.type,
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
});
}).then(function(response) {
return response.json();
}).then(function(answer) {
return pc.setRemoteDescription(answer);
}).catch(function(e) {
alert(e);
});
}
function start() {
document.getElementById('start').style.display = 'none';
pc = createPeerConnection();
var constraints = {
audio: document.getElementById('use-audio').checked,
video: false
};
if (document.getElementById('use-video').checked) {
var resolution = document.getElementById('video-resolution').value;
if (resolution) {
resolution = resolution.split('x');
constraints.video = {
width: parseInt(resolution[0], 0),
height: parseInt(resolution[1], 0)
};
} else {
constraints.video = true;
}
}
if (constraints.audio || constraints.video) {
if (constraints.video) {
document.getElementById('media').style.display = 'block';
}
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
stream.getTracks().forEach(function(track) {
pc.addTrack(track, stream);
});
return negotiate();
}, function(err) {
alert('Could not acquire media: ' + err);
});
} else {
negotiate();
}
document.getElementById('stop').style.display = 'inline-block';
}
function stop() {
document.getElementById('stop').style.display = 'none';
if (dc) {
dc.close();
}
if (pc.getTransceivers) {
pc.getTransceivers().forEach(function(transceiver) {
if (transceiver.stop) {
transceiver.stop();
}
});
}
pc.getSenders().forEach(function(sender) {
sender.track.stop();
});
setTimeout(function() {
pc.close();
}, 500);
}
I have written three files which are: home-flatfull.jsp, settings-social-prefs.html and
google-js-api-wrapper.js files.
In home-flatfull.jsp file, I have written as below:
head.js('jscore/lib/base64.js', 'jscore/lib/google-js-api.js', 'jscore/lib/google-js-api-wrapper.js', function () {
var config = {
apiKey: 'AIzaSyCa52K8J68kr5b4S7Afu1FQzeleCfvzOFs',
clientId: '492662354647-877atvgj1a0pu82nrutsm50rcmg0lufh.apps.googleusercontent.com',
discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"],
scopes: 'https://www.googleapis.com/auth/gmail.readonly',
listener: function(response){
console.log(' Check google ');
console.log(response);
}
};
googleJSAPI = GoogleJSAPI.getInstance(config);
});
In settings-social-prefs.html file I have defined as below:
<a onclick="googleJSAPI.signIn()" class="btn btn-sm btn-default">
{{agile_lng_translate 'prefs-email' 'enable'}}
</a>
In google-js-api-wrapper.js file, I have defined as below:
class GoogleJSAPI {
emailRegx = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
instance;
isActive = false;
constructor(config) {
console.log(' google code loaded ');
gapi.load('client:auth2', () => {
gapi.client.init({
apiKey: config.apiKey,
clientId: config.clientId,
discoveryDocs: config.discoveryDocs,
scope: config.scopes
}).then(() => {
this.isActive = true;
console.log(' config loaded ');
gapi.auth2.getAuthInstance().isSignedIn.listen(config.listener);
}, (error) => {
this.isActive = false;
console.log(JSON.stringify(error, null, 2));
});
});
}
static getInstance(config) {
if (!this.instance) {
this.instance = new GoogleJSAPI(config);
}
return this.instance;
}
isActive() {
return this.isActive;
}
isUserLoggedIn() {
return gapi.auth2.getAuthInstance().isSignedIn.get();
}
signIn = () => {
gapi.auth2.getAuthInstance().signIn();
}
signOut() {
gapi.auth2.getAuthInstance().signOut();
}
getSorted(a, b) {
return new Date(b.date).getTime() - new Date(a.date).getTime();
}
getMailList(queryObject) {
return new Promise((resolve, reject) => {
gapi.client.gmail.users.messages.list(queryObject).then(function (response) {
resolve(response.result);
});
});
}
getMailContentById(id) {
return new Promise((resolve, reject) => {
gapi.client.gmail.users.messages.get({
'userId': 'me', 'id': id
}).then((response) => {
let message = {};
let headers = response.result.payload.headers;
headers.forEach((header) => {
if (header.name === "From") {
message['from'] = header.value;
} else if (header.name === "Subject") {
message['subject'] = header.value;
} else if (header.name === "To") {
message['to'] = theader.value;
} else if (header.name === "Date") {
message['date'] = header.value;
} else if (header.name === "Cc") {
message['cc'] = header.value;
}
});
try {
if (response.result.payload) {
let body = "";
if (response.result.payload.body.size > 0) {
body = response.result.payload.body.data;
} else {
let bodyParts = response.result.payload.parts;
bodyParts.forEach((part, index) => {
if (part.type = "text/html") {
//console.log(index);
body = part.body.data;
return;
}
});
}
message['message'] = Base64.decode(body);
// console.log(message['body']);
}
} catch (e) {
//console.log(index);
//console.log(response.result);
//console.log(e);
}
resolve(message);
});
});
}
getInboxMailsWithContent(nextPageToken, fromEmail) {
var qData = '';
var queryObject = {
'userId': 'me',
'labelIds': ['INBOX']
};
if (nextPageToken) {
queryObject['pageToken'] = nextPageToken;
}
if (fromEmail) {
qData += 'from:' + fromEmail;
}
queryObject['q'] = qData;
return new Promise((resolve, reject) => {
gapi.client.gmail.users.messages.list(queryObject).then((response) => {
let resultObject = {
nextPageToken: response.result.nextPageToken
};
let messages = new Array();
let rawMessages = response.result.messages;
rawMessages.forEach((rawMessage, index) => {
gapi.client.gmail.users.messages.get({
'userId': 'me', 'id': rawMessage.id
}).then((response) => {
let message = {
id: rawMessage.id
};
let headers = response.result.payload.headers;
headers.forEach((header) => {
if (header.name === "From") {
message['from'] = header.value;
} else if (header.name === "Subject") {
message['subject'] = header.value;
} else if (header.name === "To") {
message['to'] = header.value;
} else if (header.name === "Date") {
message['date'] = header.value;
} else if (header.name === "Cc") {
message['cc'] = header.value;
}
});
try {
if (response.result.payload) {
let body = "";
if (response.result.payload.body.size > 0) {
body = response.result.payload.body.data;
} else {
let bodyParts = response.result.payload.parts;
bodyParts.forEach((part, index) => {
if (part.type = "text/html") {
f //console.log(index);
body = part.body.data;
return;
}
});
}
message['message'] = Base64.decode(body);
// console.log(message['body']);
}
} catch (e) {
//console.log(index);
//console.log(response.result);
//console.log(e);
}
messages[index] = message;
});
});
// resultObject.messages = messages.sort(this.getSorted);
resultObject.messages = messages;
resolve(resultObject);
});
});
}
}
function getInboxMailsWithContent(nextPageToken, fromEmail, callback) {
googleJSAPI.getInboxMailsWithContent(nextPageToken, fromEmail).then((response) => {
setTimeout(() => {
if (callback && typeof (callback) == "function") {
callback(response);
}
}, 3000);
});
}
When I clicked on enable button in settings-social-prefs.html file, I am just getting the gmail login page and gmail password page once I have provided gmail username and password, I got the consent screen which asks to allow access to user's email then I am getting the blank screen without getting the Gmail Read-Only mails of a specified user who has logged in. Can you please help me on this to get Gmail Read-Only mails when I click on enable button.
you may turn off two factor authentication (if on) and also "allow low secure apps to connect" in google my account settings
Ps: Displaying API in public should be avoided :-)
Okay so with this code I am able to get the actual mail content which comes by Email but what I want is I want to get message and attachment too. what can be done in order to list out attachments and later on giving option to download the attachments gmail api.
var ifrm = document.getElementById("iframe").contentWindow.document;
ifrm.body.innerHTML = getMessageBody(message.payload);
};
let getMessageBody = (message) => {
var encodedBody = "";
if (typeof message.parts === "undefined") {
encodedBody = message.body.data;
} else {
encodedBody = getHTMLPart(message.parts);
}
return Base64.decode(encodedBody);
};
let getHTMLPart = (arr) => {
for (var x = 0; x <= arr.length; x++) {
if (typeof arr[x].parts === "undefined") {
if (arr[x].mimeType === "text/html") {
return arr[x].body.data;
}
} else {
return getHTMLPart(arr[x].parts);
}
}
return "";
};
Gmail API when I click on message.
getOneMessage = (messageId) => {
return window.gapi.client.gmail.users.messages
.get({
userId: "me",
id: messageId,
})
.then(
(response) => {
this.setState({
message: response.result,
});
},
(err) => {
console.error("getMessage error", err);
}
);
};
handleMessageClick = (e) => {
const messageId = e.currentTarget.getAttribute("id");
this.getOneMessage(messageId);
Solution
You are using the Users.messages: get endpoint. This is fine to retrieve the message body, but to retrieve attachments you will have to use the Users.messages.attachments: get. Here you can find a link to the documentation.
Proposed code editing:
getAttachments = (message, callback) => {
var parts = message.payload.parts;
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
if (part.filename && part.filename.length > 0) {
var attachId = part.body.attachmentId;
var request = gapi.client.gmail.users.messages.attachments.get({
'id': attachId,
'messageId': message.id,
'userId': userId
});
request.execute(function(attachment) {
callback(part.filename, part.mimeType, attachment);
});
}
}
}
getOneMessage = (messageId) => {
return window.gapi.client.gmail.users.messages
.get({
userId: "me",
id: messageId,
})
.then(
(response) => {
this.setState({
message: response.result,
});
// Get the attachment and do something with it
getAttachments(response.result, callback);
},
(err) => {
console.error("getMessage error", err);
}
);
};
handleMessageClick = (e) => {
const messageId = e.currentTarget.getAttribute("id");
this.getOneMessage(messageId);
Reference
Users.messages.attachments
Trying to code in Javascript on AWS Lambda. The code is meant for Alexa to go to a URL and stream the audio on there using the AudioPlayer.
Can't figure out what I am missing in this code or what is wrong with it and I get this error through the log.
Code:
'use strict';
var alexa = require('alexa-sdk');
var APP_ID = "amzn1.ask.skill.b5c95058-7134-4044-9e77-a4279e0adaf7";
var PAUSE_MESSAGE = "paused!";
var RESUME_MESSAGE = "resumed!";
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.APP_ID = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
var handlers = {
'play': function(audioURL, offsetInMilliseconds) {
var response = {
version: "1.0",
response: {
shouldEndSession: true,
directives: [{
type: "AudioPlayer.Play",
playBehavior: "REPLACE_ALL",
audioItem: {
stream: {
url: 'https://feeds.soundcloud.com/stream/275202399-amazon-web-services-306355661-amazon-web-services.mp3',
offsetInMilliseconds: 10
}
}
}]
}
}
this.context.succeed(response);
},
'AMAZON.PauseIntent': function() {
this.emit(':tell', PAUSE_MESSAGE);
},
'AMAZON.ResumeIntent': function() {
this.emit(':tell', RESUME_MESSAGE);
}
};
I ended up changing my code.
Code:
var lastPlayedByUser = {};
var streamURL = "http://cpdc101-lh.akamaihd.net/i/ISNCPDCMB1_1#314337/master.m3u8";
exports.handler = function(event, context) {
var player = new Player(event, context);
player.handle();
};
var Player = function (event, context) {
this.event = event;
this.context = context;
};
Player.prototype.handle = function () {
var requestType = this.event.request.type;
var userId = this.event.context ? this.event.context.System.user.userId : this.event.session.user.userId;
if (requestType === "LaunchRequest") {
this.play(streamURL, 0);
} else if (requestType === "IntentRequest") {
var intent = this.event.request.intent;
if (intent.name === "Play") {
this.play(streamURL, 0);
} else if (intent.name === "AMAZON.PauseIntent") {
this.stop();
} else if (intent.name === "AMAZON.ResumeIntent") {
var lastPlayed = this.loadLastPlayed(userId);
var offsetInMilliseconds = 0;
if (lastPlayed !== null) {
offsetInMilliseconds = lastPlayed.request.offsetInMilliseconds;
}
this.play(streamURL, offsetInMilliseconds);
}
} else if (requestType === "AudioPlayer.PlaybackStopped") {
this.saveLastPlayed(userId, this.event);
this.context.succeed(true);
}
};
Player.prototype.play = function (audioURL, offsetInMilliseconds) {
var response = {
version: "1.0",
response: {
shouldEndSession: true,
directives: [
{
type: "AudioPlayer.Play",
playBehavior: "REPLACE_ALL",
audioItem: {
stream: {
url: audioURL,
token: "0",
expectedPreviousToken: null,
offsetInMilliseconds: offsetInMilliseconds
}
}
}
]
}
};
this.context.succeed(response);
};
Player.prototype.stop = function () {
var response = {
version: "1.0",
response: {
shouldEndSession: true,
directives: [
{
type: "AudioPlayer.Stop"
}
]
}
};
this.context.succeed(response);
};
Player.prototype.saveLastPlayed = function (userId, lastPlayed) {
lastPlayedByUser[userId] = lastPlayed;
};
Player.prototype.loadLastPlayed = function (userId) {
var lastPlayed = null;
if (userId in lastPlayedByUser) {
lastPlayed = lastPlayedByUser[userId];
}
return lastPlayed;
};