Hi i need to sort out messages that are not read in Gmail. But i can't pull out the body, sender and attachments properties when im adding the 'isUnread'.
var firstThread = GmailApp.getInboxThreads(0,1)[0];
var unread = firstThread.isUnread();
var message = unread.getMessages()[0];
If i do it like this it works, but i do not get the unread messages.
var firstThread = GmailApp.getInboxThreads(0,1)[0];
var message = firstThread.getMessages()[0];
Any tips?
Maybe is just a matter of order, you can try
var firstThread = GmailApp.getInboxThreads(0,1)[0];
var messages = firstThread.getMessages();
var unread = [];
for (var i=0; i<messages.length; i++){
if (messages[i].isUnread()) unread.push(messages[i]);
}
sailens approach works as expected, search is also an easy way to get what you want.
Below 2 small functions to demonstrate:
function getUnreadMessages() {
var unreadThreads = GmailApp.getInboxThreads(0,100);
if(unreadThreads.length==0){Logger.log('no unread messages');return};
var unreads = [];unreads.push('\n\n');
for(var n in unreadThreads){
if(unreadThreads[n].isUnread()){unreads.push(unreadThreads[n].getFirstMessageSubject()+' has '+unreadThreads[n].getMessageCount()+' message(s)\n')};
}
Logger.log(unreads);//shows the unread threads with their subjects and number of messages
}
function searchUnreads() {
var unreadThreads = GmailApp.search('label:unread');
if(unreadThreads.length==0){Logger.log('no unread messages');return};
var unreads = [];unreads.push('\n\n');
for(var n in unreadThreads){
unreads.push(unreadThreads[n].getFirstMessageSubject()+' has '+unreadThreads[n].getMessageCount()+' message(s)\n');
}
Logger.log(unreads);//shows the unread threads with their subjects and number of messages
}
UPDATE :
a version that gets some details from every message in the threads, build in another function for ease of use
function getUnreadMessages() {
var unreadThreads = GmailApp.getInboxThreads(0,100);
if(unreadThreads.length==0){Logger.log('no unread messages');return};
var unreads = [];unreads.push('\n\n');
for(var n in unreadThreads){
if(unreadThreads[n].isUnread()){unreads.push(unreadThreads[n].getFirstMessageSubject()+' has '+unreadThreads[n].getMessages()[n].getDate()
.getMessageCount()+' message(s)\n');getDetails(unreadThreads[n])};
}
Logger.log(unreads);//shows the unread threads with their subjects and number of messages
}
function searchUnreads() {
var unreadThreads = GmailApp.search('label:unread');
if(unreadThreads.length==0){Logger.log('no unread messages');return};
var unreads = [];unreads.push('\n\n');
for(var n in unreadThreads){
unreads.push(unreadThreads[n].getFirstMessageSubject()+' has '+unreadThreads[n].getMessageCount()+' message(s)\n');
}
Logger.log(unreads);//shows the unread threads with their subjects and number of messages
}
function getDetails(thread){
for(var n=0;n<thread.getMessageCount();n++){
Logger.log(thread[n].getMessages()[n].getBody()+' on '+thread[n].getMessages()[n].getDate())
Logger.log(thread[n].getMessages()[n].getAttachments());
}
}
I got it to work and simple as it could be:
function myFunction() {
var firstThread = GmailApp.getInboxThreads(0,1)[0];
var message = firstThread.getMessages()[0];
var unread = message.isUnread();
var sender = message.getFrom();
var body = "Detta mail är ursprungligen skickat från" + " " + sender + '\n' + message.getBody();
var subject = message.getSubject();
var attachment = message.getAttachments();
if (unread == true){
GmailApp.sendEmail("user.name#compay.com", subject, "", {htmlBody: body, attachments: attachment});
}
Related
For months I have used this little script to auto reply to clients but on may 2 it started returning empty values. Did google change something or did I mess something up?
The body and the subject are still returned as normal. However, reply to email-ID is blank.
Below is the relevant code:
var message = GmailApp.getMessagesForThread(label[i]);
var body = message[0].getPlainBody();
// Logger.log(body);
var email = message[0].getReplyTo();
Logger.log(email);
Logger.log(sub);
Thanks for the help guys.
try this
function getMail(){
var myspreadsheet = SpreadsheetApp.openById('*************');
var mysheet = myspreadsheet.getSheets()[0];
//0~99まで
var threads = GmailApp.getInboxThreads(0 , 500);
var messages = GmailApp.getMessagesForThreads(threads);
var froms = [];
var row = mysheet.getLastRow()+1
messages.get
for(var i = 0; i < threads.length; i++)
{
froms.push([messages[i][0].getFrom(),messages[i][0].getSubject()]);
}
mysheet.getRange(mysheet.getLastRow()+1,1,threads.length,2).setValues(froms);
}
I'm getting HTML from a forum url, and parsing the post count of the user from their profile page. I don't know how to write the parsed number into the Google spreadsheet.
It should go account by account in column B till last row and update the column A with count.
The script doesn't give me any errors, but it doesn't set the retrieved value into the spreadsheet.
function msg(message){
Browser.msgBox(message);
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu("Update")
.addItem('Update Table', 'updatePosts')
.addToUi();
}
function getPostCount(profileUrl){
var html = UrlFetchApp.fetch(profileUrl).getContentText();
var sliced = html.slice(0,html.search('Posts Per Day'));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
return postCount;
}
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var accountSheet = spreadSheet.getSheetByName("account-stats");
var statsLastCol = statsSheet.getLastColumn();
var accountCount = accountSheet.getLastRow();
var newValue = 0;
var oldValue = 0;
var totalNewPosts = 0;
for (var i=2; i<=accountCount; i++){
newValue = parseInt(getPostCount(accountSheet.getRange(i, 9).getValue()));
oldValue = parseInt(accountSheet.getRange(i, 7).getValue());
totalNewPosts = totalNewPosts + newValue - oldValue;
accountSheet.getRange(i, 7).setValue(newValue);
statsSheet.getRange(i,statsLastCol).setValue(newValue-todaysValue);
}
if(showAlert==false){
return 0;
}
msg(totalNewPosts+" new post found!");
}
function valinar(needle, haystack){
haystack = haystack[0];
for (var i in haystack){
if(haystack[i]==needle){
return true;
}
}
return false;
}
The is the first time I'm doing something like this and working from an example from other site.
I have one more question. In function getPostCount I send the function profileurl. Where do I declare that ?
Here is how you get the URL out of the spreadsheet:
function getPostCount(profileUrl){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var thisSheet = ss.getSheetByName("List1");
var getNumberOfRows = thisSheet.getLastRow();
var urlProfile = "";
var sliced = "";
var A_Column = "";
var arrayIndex = 0;
var rngA2Bx = thisSheet.getRange(2, 2, getNumberOfRows, 1).getValues();
for (var i = 2; i < getNumberOfRows + 1; i++) { //Start getting urls from row 2
//Logger.log('count i: ' + i);
arrayIndex = i-2;
urlProfile = rngA2Bx[arrayIndex][0];
//Logger.log('urlProfile: ' + urlProfile);
var html = UrlFetchApp.fetch(urlProfile).getContentText();
sliced = html.slice(0,html.search('Posts Per Day'));
var postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
Logger.log('postCount: ' + postCount);
A_Column = thisSheet.getRange(i, 1);
A_Column.setValue(postCount);
};
}
You're missing var in front of one of your variables:
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
That won't work. Need to put var in front. var postCount = ....
In this function:
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
There is no array named arguments anywhere in your code. Where is arguments defined and how is it getting any values put into it?
I have the code below. Basically I have 3 nested parse queries. One is getting a number of "followers" and for each follower I am getting a number of "ideas" and for each idea I would like to get that idea creator's name (a user in the user table).
The first two nested queries work but then when i try to get the name of the user (the creator of the idea), that last nested query DOES NOT execute in order. That query is skipped, and then it is executed later in the code. Why is this happening please?
var iMax = 20;
var jMax = 10;
var IdeaList = new Array();
var IdeaListCounter = 0;
var myuser = Parse.User.current();
var Followers = new Parse.Query("Followers");
Followers.equalTo("Source_User",{__type: "Pointer",className: "_User",objectId: myuser.id});
Followers.find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
var object = results[i];
var Ideas = new Parse.Query("Ideas");
Ideas.equalTo("objectId_User", {__type: "Pointer",className: "_User",objectId: object.get('Destination_User').id});
Ideas.find({
success: function(results2) {
for (i=0;i<iMax;i++) {
IdeaList[i]=new Array();
for (j=0;j<jMax;j++) {
IdeaList[i][j]=0;
}
}
for (var j = 0; j < results2.length; j++) {
var object2 = results2[j];
var ideausername2 = "";
IdeaListCounter++;
var ideausername = new Parse.Query("User");
ideausername.equalTo("objectId",object2.get('objectId_User').id);
ideausername.first({
success: function(ideausernameresult) {
ideausername2 = ideausernameresult.get("name");
}
});
IdeaList[IdeaListCounter,0] = object2.get('objectId_User').id + " " + ideausername2; //sourceuser
IdeaList[IdeaListCounter,1] = object2.get('IdeaText'); //text
IdeaList[IdeaListCounter,2] = object2.get('IdeaImage'); //image
IdeaList[IdeaListCounter,3] = object2.get('IdeaLikes'); //likes
IdeaList[IdeaListCounter,4] = object2.get('IdeaReport'); //reports
Your nested query is asynchronous.
Check out the answer at the following for guidance:
Nested queries using javascript in cloud code (Parse.com)
Background:
I am part of a large family and to save everyone some money at Christmas, we do a Secret Santa of sorts for gift giving. I am writing this script so that this all can be managed via a spreadsheet since our process can be somewhat messy. The rules are:
Each "Santa" is given two names that they must buy gifts for.
Those 2 names can not be the same.
Couples can not give gifts to each other or their children. Children
can not give gifts to their siblings or their parents.
Here is a table with some example data:
The Problem
I believe my issue is occurring because of the following code:
//Remove disallowedNames from currentAvailableNames
for (j=0; j<disallowed.length; j++){
var disallowedName = disallowed[j];
currentAvailableNames.splice(currentAvailableNames.indexOf(disallowed[j]), 1);
}
For some reason, the disallowed name(s) are also being removed from the availableNames array and I have no idea why. The only way I have been able to "fix" it, is by adding in the following code after the recipient has been picked:
//Add Disallowed Names back to Available Names Array
for (k=0; k<disallowed.length; k++){
var disallowedName = disallowed[k];
if (disallowedName.length >0) {
availableNames.push(disallowedName);
}
}
Original Code
function giftAssignments() {
//Get Settings
var ss = SpreadsheetApp.getActiveSpreadsheet();
var settings = ss.getSheetByName("Settings");
var resultsSheet = ss.getSheetByName("Results");
var numOfAssignments = settings.getRange("B2").getValue();
var minPrice = settings.getRange("B3").getValue();
var maxPrice = settings.getRange("B4").getValue();
var firstName = settings.getRange("B5").getValue();
var santasLastRow = settings.getLastRow();
var santasLastCol = settings.getLastColumn();
var santasTotal = santasLastRow - firstName + 1;
var santasAsRange = settings.getRange(firstName,1,(santasLastRow - firstName + 1), santasLastCol).getValues();
//Create Santas Array (santas)
var santas = []
for (var i=0; i<santasAsRange.length; i++) {
var name = santasAsRange[i][0];
var email = santasAsRange[i][1];
var disallowedAsString = santasAsRange[i][2];
disallowedAsString = disallowedAsString.replace(", ",",");
var disallowed = disallowedAsString.split(",");
disallowed.push(name);
var santa = [];
santa[0] = name;
santa[1] = email;
santa[2] = disallowed;
santas.push(santa);
}
//Create Array of Names (availableNames)
var availableNames = [];
for (i=0; i<santas.length; i++) {
var aName = santas[i][0];
availableNames.push(aName);
}
//Assign Recipients
var results = assignRecip(santas, availableNames);
Logger.log("RESULTS = " + results);
}
function assignRecip(santas, names) {
var availableNames = names;
for (i=0; i<santas.length; i++) {
var currentAvailableNames = availableNames;
var name = santas[i][0];
var disallowed = santas[i][2];
Logger.log("Santa = " + name);
Logger.log("availableNames = " + availableNames);
//Remove disallowedNames from currentAvailableNames
for (j=0; j<disallowed.length; j++){
var disallowedName = disallowed[j];
currentAvailableNames.splice(currentAvailableNames.indexOf(disallowed[j]), 1);
}
Logger.log("currentAvailableNames = " + currentAvailableNames);
//Pick Random Ricipient from currentAvailableNames
var recipient = currentAvailableNames[Math.floor(Math.random() * currentAvailableNames.length)];
Logger.log("Recipient = " + recipient);
//Add Recipient to Santa Array
santas[i].push(recipient);
//Add Disallowed Names back to Available Names Array
for (k=0; k<disallowed.length; k++){
var disallowedName = disallowed[k];
if (disallowedName.length >0) {
availableNames.push(disallowedName);
}
}
//Add Recipient to Disallowed Names Array
santas[i][2].push(recipient);
//Remove Recipient from Available Names Array
availableNames.splice(availableNames.indexOf(recipient),1);
Logger.log("availableNames = " + availableNames);
Logger.log(" ");
}
return santas;
}
They're references to the same Array. This code doesn't copy the Array itself. It copies the reference to the Array.
var currentAvailableNames = availableNames;
You can fix it using .slice().
var currentAvailableNames = availableNames.slice();
Now you have two separate Arrays, so direct modifications to currentAvailableNames will not affect availableNames.
Note that this is a shallow clone. If it was an Array of Objects or Arrays, then modifications to the nested Object would still be visible from both Arrays.
I'm building a multiuser sketchpad and having some issues getting and keeping an updated list of all the currently connected users. I'm trying to find the best way to notify all existing clients of a new client, and passing the existing clients to the newly connected one. The reason I'm trying to do this is so when one client draws a line, all the other clients find that client in the list, and add the line coords to the respective array.
Server.js
var sys = require("sys");
var ws = require('websocket-server');
var server = ws.createServer({debug: true});
server.addListener("connection", function(conn) {
// When a message is received, broadcast it too all the clients
// that are currently connected.
conn.send('NEW_SERVER_MESSAGE:Welcome!');
conn.send('USER_CONNECTED:' + conn.id);
conn.addListener("message", function( msg ){
switch(msg) {
case 'GET_ALL_ACTIVE_USERS':
server.manager.forEach(function(con) {
conn.broadcast('USER_CONNECTED:' + con.id);
});
break;
case 'UPDATE_CURSOR':
conn.broadcast( msg + '_' + conn.id );
break;
default:
conn.broadcast( msg );
break;
}
});
conn.addListener('close', function( msg ) {
conn.broadcast('USER_DISCONNECTED:' + conn.id);
});
});
server.addListener("error", function(){
console.log(Array.prototype.join.call(arguments, ", "));
});
server.addListener("listening", function(){
console.log("Listening for connections...");
});
server.addListener("disconnected", function(conn){
console.log("<"+conn.id+"> disconnected.");
});
server.listen(8002);</code>
My JS network code:
sketchPadNet = function (b,s) {
var self = this;
this.host = "ws://localhost:8002/server.js";
this.id = null;
this.users = [];
this.heightOffset = 53;
this.scene = s;
this.connected = b;
var User = function(id) {
this.id = id;
this.nickname = id;
this.lines = [];
this.position = "";
};
this.init = function () {
try {
socket = new WebSocket(self.host);
socket.onopen = function (msg) {
socket.send('GET_ALL_ACTIVE_USERS');
};
socket.onmessage = function (msg) {
var m = msg.data.split(':');
switch(m[0]) {
case 'USER_CONNECTED':
console.log('USER_CONNECTED');
var u = new User(m[1]);
u.lines = [];
u.nickname = u.id;
self.users.push(u);
console.log(self.users.length);
console.log(self.users);
break;
case 'USER_DISCONNECTED':
console.log('USER_DISCONNECTED');
for(var i = 0; i < self.users.length; ++i) {
console.log(self.users[i]);
if(m[1] == self.users[i].id) {
self.users.splice(i, 1);
}
}
break;
case 'DRAW_LINE':
var tmpMsg = m[1].split('_');
var id = tmpMsg[8];
var userIndex = '';
for(var i = 0; i < self.users.length; ++i) {
if(self.users[i].id == id) userIndex = i;
}
var p1 = (self.users[userIndex].lines.length < 1) ? new BLUR.Vertex3(tmpMsg[0], tmpMsg[1], tmpMsg[2]) : self.users[userIndex].lines[self.users[userIndex].lines.length - 1].point2;
var p2 = new BLUR.Vertex3(tmpMsg[3], tmpMsg[4], tmpMsg[5]);
var line = new BLUR.Line3D(p1, p2, tmpMsg[7]);
line.material = tmpMsg[6];
// add the newly created line to the scene.
self.scene.addObject(line);
self.users[userIndex].lines.push(line);
break;
case 'UPDATE_CURSOR':
for(var i = 0; i < self.scene.objects.length; ++i) {
if(self.scene.objects[i].type == 'BLUR.Particle')
self.scene.removeObject(scene.objects[i]);
}
var coords = m[1].split('_');
var id = coords[2];
var userIndex = 0;
for(var i = 0; i < self.users.length; ++i) {
if(self.users[i].id == id)
userIndex = i;
}
self.users[userIndex].position = new BLUR.Vertex3(coords[0], coords[1], 1);
var p = new BLUR.Particle( self.users[userIndex].position, 4 );
p.material = new BLUR.RGBColour(176,23,31,0.3);
self.scene.addObject(p);
break;
case 'RECEIVE_ID':
self.id = m[1];
self.connected.nicknameObj.text = self.id;
console.log(self.id);
break;
break;
}
};
socket.onclose = function (msg) {
// feck!
self.connected.addServerError('Server disconnected, try refreshing.');
};
}
catch (ex) {
console.log('EXCEPTION: ' + ex);
}
};
At the moment, when a new client connected it sends out a message and is added to an array, the the reverse when a client disconnects. For some reason though this isn't staying update? For example when a client draws a line, some of the others report this error:
Uncaught TypeError: Cannot read property 'lines' of undefined
Sorry if i'm being incredibly stupid here, but any help is appreciated!!
Cheers :)
I tried to figure it out by looking at the code but without even a line number on which the error appears, it's pretty hard, anyways.
I suppose this is the problem here:
conn.send('USER_CONNECTED:' + conn.id); // send the connect message to ONE user
conn.broadcast('USER_DISCONNECTED:' + conn.id); // send the disconnect to ALL users
So it seems that you're simply missing a broadcast call when a user connects.
Ok the real issue seems to be in 'DRAW_LINE' on the client side. Are you sure that you are broadcasting the message to all users and not just sending back the message to the client?
The error points to this line in your client code:
var p1 = (self.users[userIndex].lines.length < 1) ? new BLUR.Vertex3(tmpMsg[0], tmpMsg[1], tmpMsg[2]) : self.users[userIndex].lines[self.users[userIndex].lines.length - 1].point2;
Please provide the server code for 'DRAW_LINE'. The issue is definitely cropping up in there and not in any of the others.
Also, self.users[userIndex] is undefined. Maybe that user does not exist?
Why do u need that for loop? Why not just:
if(self.users[id] != undefined) {
var p1 = (self.users[id].lines.length < 1) ? new BLUR.Vertex3(tmpMsg[0], tmpMsg[1], tmpMsg[2]) : self.users[id].lines[self.users[id].lines.length - 1].point2;
}
I'm trying to find the best way to
notify all existing clients of a new
client, and passing the existing
clients to the newly connected one
I would advice you to have a look at socket.io instead. It can do this easily and fail back to other available transports if websockets aren't supported by the browser.
you might want to consider using an existing server that has things like rooms and user lists built in. for comparison, here's a tutorial for a multiuser sketchpad written in javascript that uses Union Server:
http://www.unionplatform.com/?page_id=2762
and here's Union Server's documented protocol, which includes a description of the messaging system for rooms and clients joining/leaving rooms:
http://unionplatform.com/specs/upc/
might give you some ideas.
colin