Add contacts to Google Contacts' main Contacts list (not hidden) - google-apps-script

I'm using the GAS code bellow to add a new contact into Google Contacts (https://contacts.google.com/):
var contact = ContactsApp.createContact('Bbbb', 'Cccc', 'mymail#mails.com').addUrl(ContactsApp.Field.WORK_WEBSITE, 'https://sites.google.com/site/...');
The code works perfectly but for a single detail: it adds the new contact to a hidden list and not to the main or visible «Contacts» list.
I know it works because when I use the lookup box to search for the newly created contact it's there, in the «Other contacts» list. I need it to be created in the main «Contacts» list from the beginning, otherwise I would have to do it manually using the «Add to contacts» icon with every contact created (I'm planning to add some thousands of contacts.)
Thanks.

For me, I have to add them to the ContactGroup named System Group: My Contacts.
function finishAddingContact(contact) {
var mainGroup = ContactsApp.getContactGroup("System Group: My Contacts");
if(mainGroup)
mainGroup.addContact(contact);
}
Note that getContactGroup(string) is an exact name match.
I recommend inspecting your ContactGroups for system groups, and then selecting the appropriate one from that list. It's probably the one with the most contacts in it:
function inspect() {
var groups = ContactsApp.getContactGroups();
for(var g = 0; g < groups.length; ++g) {
if(groups[g].isSystemGroup()) {
Logger.log(groups[g].getName() + ": " + groups[g].getContacts().length + " members, id=" + groups[g].getId());
}
}
}

Thanks a lot tehhwch.
I used your second code to get the right group ("System Group: My Contacts"), and then:
var contact = ContactsApp.createContact('Wunder', 'Bar', 'excellent#help.com');
var group = ContactsApp.getContactGroup("System Group: My Contacts");
group.addContact(contact);
It works, and the contact is immediately visible in my Android device.

Related

Is there any limitations in adding widgets using appscript for developing gmail add-on?

We have a requirement where we will add multiple sections and each section with multiple widgets, i got to know we have limitation on sections as 100 per card, do we have any limitations on the widget count per card in appscript to develop gmail add-on.
Ex:
var card = CardService.newCardBuilder()
.setHeader(CardService.newCardHeader().setTitle('Quick Label');
var section = CardService.newCardSection(); section.addWidget(CardService.newKeyValue().setMultiline(true).setContent("text"));
section.addWidget(CardService.newKeyValue().setMultiline(true).setContent("text"));......
card.addSection(section);
card.addSection(section);
card.addSection(section);..enter code here
Please help me out on this.
Thanks
There is indeed a limitation to the number of widgets you can add. At most, there can only be 100 in a card.
So, if you want to create a card with multiple sections that have multiple widgets each, you have to take into account that the product of sections and widgets per section cannot surpass 100.
As a result, if you only have one section, you can have 100 widgets there. And if you have 100 sections, there can only be one widget per section if you want them all to show up.
You can check this limitation easily by deploying this add-on and changing numSections and numWidgets accordingly:
function buildWidgets(e) {
var card = CardService.newCardBuilder()
.setHeader(CardService.newCardHeader()
.setTitle('Quick Label').setImageUrl('https://www.gstatic.com/images/icons/material/system/1x/label_googblue_48dp.png'));
var numSections = 10; // Change this to notice limitation
var numWidgets = 10; // Change this to notice limitation
for (var i = 0 ; i < numSections; i++) {
var tempsection = CardService.newCardSection().setHeader('Texts '+ i + 'aaaa.');
for(var j = 0; j < numWidgets; j++) {
tempsection.addWidget(CardService.newTextButton().setText("Sections num"+j).setOnClickAction(CardService.newAction().setFunctionName("test")));
}
card = card.addSection(tempsection);
}
card = card.build();
return [card];
}
I don't know why you want so many sections and widgets, but please be aware that it's considered a Best practice to keep the cards simple and without too many widgets.
I hope this is of any help to you.

BigCommerce Stencil - Product Variant Stock Levels

A client wants to set up A/B testing on the Product Detail Page related to the stock_level of a product's variants. Once the user selects their options, if the quantity is less than 5, I'd show something like "Hurry, only 3 more in stock"...
I believe I have the correct Inventory settings enabled, because I can retrieve the stock_level of a product without options.
Has anyone had success pulling variant SKU stock_levels in stencil?
Thanks
This can be done using javascript in the assets/js/theme/common/product-details.js file. On initial page load and each time a product option is changed, there is a function updateView(data) that is called. The data parameter contains all the info you need for the selected variation.
Starting on line 285, replace this:
updateView(data) {
const viewModel = this.getViewModel(this.$scope);
this.showMessageBox(data.stock_message || data.purchasing_message);
with this:
updateView(data) {
const viewModel = this.getViewModel(this.$scope);
if(data.stock < "5") {
data.stock_message = "Hurry, only " + data.stock + " left!";
}
this.showMessageBox(data.stock_message || data.purchasing_message);

Windows phone 8.1 using Contact Picker to retrieve both email and phone number

I am using the following code to allow the user to select contacts:
ContactPicker ContactPicker = new ContactPicker();
ContactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.PhoneNumber);
var Contacts = await ContactPicker.PickContactsAsync();
if (Contacts.Count > 0)
{
foreach (Contact contact in Contacts)
{
string telephone = string.Empty;
string email = string.Empty;
if (contact.Phones.Count > 0)
{
telephone = contact.Phones[0].Number;
}
if (contact.Emails.Count > 0)
{
email = contact.Emails[0].Address;
}
PartyPerson person = new PartyPerson(DateTime.Now.ToString("PP_yyMMdd_hhmmss_ffff"), true, contact.DisplayName, 0, 0, 0, email, telephone);
AddPartyPerson(person);
}
}
ContactPicker = null;
However, I only get phone number, the object "contact" does not contain any email addresses even though they are present in the contact information.
One option is to switch:
ContactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.PhoneNumber);
with
ContactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.Email);
But then I don't get a phone number... I want to be able to retrieve all the information in one select.
Is there any way to select both information via one select?
(I also tried adding more than one entry to DesiredFieldsWithContactFieldType but then I get an exception...)
Best regards,
Keran
EDIT 07.08.2015:
Since the "ContactPicker.DesiredFieldsWithContactFieldType" can only accept one type of "ContactFieldType", the way I worked around this was first allow the user to get the contacts by ContactFieldType.PhoneNumber and then I programatically retrieve the email addressess of the selected contacts.
From the users point of view, this won't be a problem since everything will be visible correctly in the ContactPicker.PickContactsAsync, we just need to retrieve the missing email information manually in code-behind, which is easy since we know what contacts were selected by the user.
Try this:
ContactStore contactStore = await ContactManager.RequestStoreAsync(ContactStoreAccessType.AllContactsReadOnly);
ContactPicker contactPicker = new ContactPicker();
IList<Contact> pickedContacts = await contactPicker.PickContactsAsync();
int pickedCount = pickedContacts != null ? pickedContacts.Count : 0;
if (pickedCount > 0)
{
for (int i = 0; i < count; ++i)
{
Contact c = pickedContacts[i];
Contact realContact = await contactStore.GetContactByIdAsync(c.Id);
//...
}
}
So, you first need to get the "skeleton" of the contact, and then you can get the whole contact entity with all its properties from the ContactStore object.
It works for me on Windows 10 Mobile. There shouldn't be much difference from Windows 8.
Hope it helps.

Creating a user generated list in flash

I'm trying to create a flash application that will keep track of user generated values. The app should basically allow the user to input the name of the item and it's cost. The total costs should then be added up to show a total value to the user. I can probably figure out how to add the values together, but I'm not really sure how to allow the user to create a list and then allow the user to save it. Can anyone point me towards a tutorial or point me in the right direction?
I am using variables to add user inputed numbers to come up with a total. The first problem is that actionscript 3.0 does not allow variables for texts. I just converted it to 2.0 to fix this. The second problem, is when I test the app and put in my values and click submit, I get NaN in the total values field. Is there a reason why it wouldn't add the values?
Here is the code I used for the submit button:
on (release) {
total = Number(rent) + Number(food) + Number(travel) + Number(entertainment) + Number(bills);
}
Am I missing anything?
Can I give the input text instance names and then give them variables? How are some ways to go about this?
Thanks for the help!
Have an object array, say for example
var stack:Array = new Array();
Then push the item name and it's cost to that array when user inputs, like
stack.push({item:AAA, cost:xx});
So that you can generate the list whenever you want with that array.
You have to see how this works in code. A list in actionscript could be stored inside an array, vector, dictionary or even an Object.
Var myList:Array = [];
myList.push({name: "item 1", cost: 5 });
myList.push({name: "item 2", cost: 7.5 });
If you want to grab the 'product' of "item 1" from the list, you have to create a function for that, lets call it getProductByName
function getProductByName(name:String):Object
{
for each(var product:Object in myList)
{
if (product.name === name) return product;
}
return null; // no match found
}
You can call that function like this:
var product = getProductByName("item 1");
trace(product.cost); // 5
And you can alter the product, so lets make it more expensive
product.cost += 1;
trace(product.cost); // 6
Have fun! If you are using classes, you would create one for the product, with public name and cost, and in that case you'de better use a vector, to ensure working with the right type.
This is what fixed the issue for me in action script 3.0:
myButton.addEventListener(MouseEvent.CLICK, addThem);
function addThem(e:MouseEvent)
{
totalField.text = String ( Number(field1.text) + Number(field2.text) + ....);
}
I also had to name the instances appropriately.

How do I find the page number/number of pages in a document?

I want to create a new document based on a template and need to know when my insertion or append results in a new page in the final printed output is there any property/attribute eg number of pages that can be used for this?
I've search this a lot in the past and I don't think there's any property or any other way to know page info.
The solution I use is to insert page breaks on my template or via the script, using my own knowledge of how my template works, i.e. how much space it takes as I iterate, etc.
And then I know which page I am by counting the page breaks.
Anyway, you could an enhancement request on the issue tracker.
One way to get total number of pages:
function countPages() {
var blob = DocumentApp.getActiveDocument().getAs("application/pdf");
var data = blob.getDataAsString();
var re = /Pages\/Count (\d+)/g;
var match;
var pages = 0;
while(match = re.exec(data)) {
Logger.log("MATCH = " + match[1]);
var value = parseInt(match[1]);
if (value > pages) {
pages = value;
}
}
Logger.log("pages = " + pages);
return pages;
}