I am trying to create a filter for every people's email in a group. However, sometimes the a person's email can changes like adding new email or change to another mail email. That means I have to update the filter accordingly. I tried to create filter with ID that with the person's name. So I can retrieve that filter to modify it. However, it seems that the Gmail filter's ID are created automatically.
var filter = Gmail.newFilter()
var email = 'something#some.com'
filter.id = 'person'
filter.criteria = Gmail.newFilterCriteria()
filter.criteria.query = email
filter.action = Gmail.newFilterAction()
filter.action.addLabelIds = ['Label_1']
Gmail.Users.Settings.Filters.create(filter, 'me')
When I get back the filter, it will say that it cannot be found
var filter2 = Gmail.Users.Settings.Filters.get('me', 'person')
This will return Not Found error even I can see the filter in setting in my Gmail. The actually ID for the filter I created above is ANe1Bmgel8OKlEXD-uArX77ISk35Lph1MbWWjA.
My question is what's the good way to manager filters through changes, keep them updated?
Instead of:
Gmail.Users.Settings.Filters.create(filter, 'me');
Try:
var filterProps = Gmail.Users.Settings.Filters.create(filter, 'me');
var filterId = filterProps.id;
Per the API documentation for creating a filter,
If successful, this method returns a Users.settings.filters resource in the response body.
The code above worked for me in a similar situation. To keep track of the filterId outside of Gmail, you could then tie the person's name to the id via the property service:
PropertiesService.getScriptProperties().setProperty(nameVar, filterId);
and then retrieve it like so:
PropertiesService.getScriptProperties().getProperty(nameVar);
Per the API documentation for a Filter resource:
id: string The server assigned ID of the filter.
Thus, you cannot assign the ID, and any value you set for it in the call to .create is ignored.
You can still programmatically retrieve this filter, using .list and Array#filter, e.g.
function getAllFilters_(userId) {
const options = {};
const filters = [];
do {
var search = Gmail.Users.Settings.Filters.list(userId, options);
if (search.filter && search.filter.length) {
Array.prototype.push.apply(filters, search.filter);
options.pageToken = search.nextPageToken;
} while (options.pageToken);
return filters;
}
function getFiltersWithCriteria_(filterList, criteria) {
// `criteria` is an object of parameters that must be exactly matched in the filters' criteria property
const props = Object.keys(criteria);
const matches = filterList.filter(function (gFilter) {
// gFilter is a https://developers.google.com/gmail/api/v1/reference/users/settings/filters#resource
var fCriteria = gFilter.criteria;
return props.every(function (prop) {
return criteria[prop] === fCriteria[prop];
});
});
return matches;
}
function foo() {
const filters = getAllFilters_("me");
const matched = getFiltersWithCriteria_(filters, {
from: "george#example.com",
hasAttachment: true
});
console.log({message: "Matching filters", matches: matched});
}
Related
I have a function that takes a string from a search field during runtime, and stores it to localstorage. Since we want to store all search strings from the end user to record it, we need to get the current data from localstorage, and add the latest search string.
Here is my code:
const setDatatoLocalStorag = (searchQuery: string) => {
let searchHistory = localStorage.getItem("searchHistory");
let searchQueryArr = [];
if (searchHistory) {
JSON.parse(searchHistory);
searchQueryArr.push(searchQuery, searchHistory);
} else {
searchQueryArr.push(searchQuery);
}
localStorage.setItem("searchHistory", JSON.stringify(searchQueryArr));
}
Lets assume we run the function twice, with the searchQuery "dog" and "cat". This is how it will look like in localstorage:
["cat","[\"dog\"]"]
I believe localstorage will get the item as string "[myData]" which will cause the error. How to properly handle this?
I have tried to follow How to store an array of objects in Local Storage? withous success.
The problem is you aren't assigning JSON.parse(searchHistory); to a variable. I think what you want to do is this:
var searchQueryArr = ['dog'];
localStorage.setItem("searchHistory", JSON.stringify(searchQueryArr));
var searchHistory = JSON.parse(localStorage.getItem("searchHistory") || '[]');
console.log(searchQueryArr, searchHistory);
Note I wasn't able to get this to work with the inline editor, but I did try it on a real server and it worked.
Make a setter/getter pair that hide the encoding/unencoding. Then add a higher-level push that does a get and a set...
// const pretend local storage, keys => strings
const myLocalStorage = {}
function mySetItem(key, value) {
// use the actual local storage setItem() here
myLocalStorage[key] = JSON.stringify(value);
}
function myGetItem(key) {
// use the actual local storage getItem() here
return JSON.parse(myLocalStorage[key]);
}
function myPush(key, value) {
let current = myGetItem(key);
current.push(value)
mySetItem(key, current)
}
// test
const key = 'myKey'
mySetItem(key, []);
myPush(key, { message: 'hello' })
myPush(key, { message: 'dolly' })
console.log(myGetItem(key))
Is it possible to get count of listed products in an Amazon page?
I need to get this number. I know I can use javascript to get it by ID or class, but I know that amazon changes the values of IDs and classes in some period of time, so later on I wouldn't be able to get this number unless I check the ID or class by myself and change it in code.. So is there an API call or something to freely get this number, without changing code every time?
You need a combination of ItemSearch and the ResponseGroup BrowseNodes. It would be something like this if you were to use C# and pass the results back to your JavaScript app:
ItemSearchRequest request = new ItemSearchRequest();
request.ResponseGroup = new string[] { "BrowseNodes", "ItemAttributes" };
request.SearchIndex = "Movies";
request.Keywords = "game of thrones";
ItemSearch search = new ItemSearch();
search.AWSAccessKeyId = access_key_id;
search.AssociateTag = associate_tag;
search.Request = new ItemSearchRequest[] { request };
AWSECommerceServicePortTypeClient port = new AWSECommerceServicePortTypeClient("AWSECommerceServicePort");
port.ChannelFactory.Endpoint.EndpointBehaviors.Add(new AmazonSigningEndpointBehavior(access_key_id, secret_access_key));
ItemSearchResponse response = port.ItemSearch(search);
foreach (var items in response.Items)
{
foreach (var item in items.Item)
{
Console.WriteLine("{0}\t{1}\t{2}", item.ItemAttributes.Title, item.ASIN, item.ItemAttributes.Author[0]);
if (item.BrowseNodes != null)
{
Console.WriteLine(" - BrowseNodes");
foreach (var node in item.BrowseNodes)
{
Console.WriteLine(" -- \t{0}\t{1}\t{2}", node.TotalResults);
}
}
}
}
https://flyingpies.wordpress.com/2009/08/01/17/
https://docs.aws.amazon.com/AWSECommerceService/latest/DG/LocaleUS.html
https://docs.aws.amazon.com/AWSECommerceService/latest/DG/ItemSearch.html
https://docs.aws.amazon.com/AWSECommerceService/latest/DG/RG_BrowseNodes.html
is it possible in deepstream to subscribe to data using a list? it appears that changes to the data does not trip the subscribe() function, only something like an addEntry() appears to affect the list subscription.
const deepstream = require('deepstream.io-client-js') ;
const util = require('util') ;
const client = deepstream('localhost:6020').login();
var obj_1 = { 'sequelizeName':'Mark', 'sequelizeAddr':'123 Elm Lane' , 'sequelizeId':'1111'};
var obj_2 = { 'sequelizeName':'Lori', 'sequelizeAddr':'948 Maple Street' , 'sequelizeId':'2222'};
const rec_1 = client.record.getRecord('obj_one');
const rec_2 = client.record.getRecord('obj_two');
rec_1.set(obj_1);
rec_2.set(obj_2);
var listTest = client.record.getList('listTest');
listTest.setEntries( ['obj_one' ,'obj_two' ] );
listTest.subscribe( (result) => {
console.log('LIST SUBSCRIBE: ' + util.inspect(result));
})
setTimeout( () => {
obj_1.sequelizeAddr = '321 New Address';
rec_1.set(obj_1); // how can this change show up in the list subscribe?
}, 2000 );
I have been encouraged to try a new approach using lists, but I am unclear how to subscribe to changes in the data itself using a list, except to somehow have some sort of "generic" or "global" subscribe, which i am not sure is even possible.
Or is there some way I can subscribe using an anonymous record?
Lists are just arrays of strings. Your list content is not connected to the actual record. You can't even assume that a list entry is a record name. You would need to subscribe to each record name in a list manually to get its content updates.
this suggestion was made by both wolfram and phillipp:
class User{
constructor( recordName ) {
this.record = ds.record.getRecord( recordName );
this.record.subscribe( this._processUpdate.bind( this ) );
}
_processUpdate( data ) {
if( this.record.name === '...') {
// do stuff
}
}
}
this works great. thank you both.
I have the following data set:
person-base
{
-K771quXhYWTo-F8oei9
{
person: "Sam"
value: 2
}
-K771uFngeQ6j0rvDhN_
{
person: "Joe"
value: 1
}
}
I am trying to retrieve the value of one of these keys based on it's person child.
I created a query that I'm using to point to the person value that matches the value of my personName variable (in this case "Sam") and so far, based on what I see in the console, it correctly retrieves the respective key and it's children.
My code:
var personRef = new Firebase("https://person-base.firebaseio.com/");
var personName = "Sam";
var query = personRef.orderByChild('person').equalTo(personName);
query.on('value', function(snapshot) {
console.log(snapshot.val());
console.log(snapshot.val().key()); // error
});
My plan was to retrieve the parent key (generated by .push) that contains my person value and then to run something like the code I have below in order to retrieve value
personRef.child(key).on('value', function(childSnapshot) {
var obj = childSnapshot.val();
console.log(obj.value);
});
However I am unable to retrieve the parent with my query.
My fiddle for further reference: https://jsfiddle.net/y20Lucyx/1/
When you execute a query, the result is always a snapshot of all child nodes that match that query. Even though in your case there is only one matching child, you still need to handle the child with a loop:
query.on('value', function(snapshot) {
snapshot.forEach(function(sam) {
console.log(sam.val());
console.log(sam.key());
});
});
I'm still struggling to understand how to access Meteor.users as a foreign key from another collection query. I understand that only the current user is published by default so I have a publication on the server as
Meteor.publish('itemOwner', function(userId) {
check(userId, String);
var user = Meteor.users.find({id: userId});
return user;
// return Meteor.users.find({id: userId}, {
// fields: {'profile': 1} });
});
I then have a Deps.autorun on the client..
Deps.autorun(function () {
var itemOwnerId = Session.get("itemOwnerID");
if (itemOwnerId) {
debugger
var ID = Session.get("itemOwnerID");
Meteor.subscribe('itemOwner', Session.get("itemOwnerID"));
}
});
I set the session ID on a modal form load, and display it in the template by calling the ownerProfile helper (or try to)
Template.showQuoteModalInner.helpers({
getQuote: function () {
// Get the quote ID from the session var
var quote = Session.get("quoteID");
if(quote) {
debugger;
var ID = quote.user._id;
Session.set("itemOwnerID", quote.user._id);
return quote;
}
},
ownerProfile: function() {
debugger;
var quote = Session.get("quoteID");
if(quote) {
var ID = quote.user._id;
var theUser = Meteor.users.find({_id: quote.user._id});
return theUser;
};
}
});
Now, I can trace the user ID at each stage and see it getting correctly passed to the autorun and the helpers. If I stop the program at the debugger in the ownerProfile helper and in the console put in Meteor.user.fetch({_id: "the id here"}).fetch() I get the correct user back.. but, in the handler itself the Meteor.users.find returns null??? What am I missing?
Two possibilities I noticed.
First, you are missing an underscore in the find in your publish function.
.find({id: userId}) should be .find({_id: userId}).
But this probably isn't the issue if you are seeing the user (other than the logged in user) in the console.
Second, if you are not seeing the user from your Template.showQuoteModalInner.ownerProfile helper, it is probably because you are returning a find() instead of a findOne().
find() returns a cursor whereas findOne() returns the record. Try findOne() if you want to display that single user's attributes.