I tried to retrieve the variable Default from json of people api but it doesn't work with "default" . how to do it ? thank you for your answer
see my test script below, please (last line at bottom)
var person = People.People.get('people/' + accountId, {personFields: 'names,photos,phoneNumbers,addresses,birthdays,sipAddresses,organizations,genders'});
//** var val_displayName_P = person.names[0].displayName;
var val_photoUrl = person.photos[0].url.replace("=s100","=s128");
var primary_BLN = person.photos[0].metadata.primary;
var default_BLN = person.photos[0].default;
Seems like it is not returning default field in JSON response when a particular accountID contains user-provided photo(default : false), looks like a bug to me, not sure.
In case of User-provided photo, this is the log i am getting :-
And in case of default photo:-
Maybe that's why execution is breaking at last line.
If this is the case, for now you can try this :-
const photo= person.photos[0]
var default_BLN = photo.hasOwnProperty('default') ? photo.default : false;
Reference:
Photo
JSON is case sensitive, try person.photos[0].Default.
Related
I am using a free currency converter API as shown in the code:
// Free Currency Converter
url = 'https://free.currencyconverterapi.com/api/v5/convert?q=EUR_USD&compact=ultra';
response = UrlFetchApp.fetch(url);
rateEURUSD_FCC_JSON = JSON.parse(response.getContentText());
rateEURUSD_FCC = rateEURPLN_FCC_JSON.EUR_USD;
Logger.log('rateEURUSD_FCC = ' + rateEURUSD_FCC);
And that works well.
Now I want to use the same method but in a function taking currency1 and currency2 as inputs.
url = 'https://free.currencyconverterapi.com/api/v5/convert?q='+Currency1+'_'+Currency2+'&compact=ultra';
response = UrlFetchApp.fetch(url);
fiatRate_FCC_JSON = JSON.parse(response.getContentText());
fiatPairName = Object.keys(fiatRate_FCC_JSON);
I can see the name of the key created in the object but I do not know how to get the value of that element (that key?).
theValue = fiatRate_FCC_JSON.xxxxxxxxxxxxxxxxxxxxx
I think I need to use currency1 and currency2 to build the name of the field I want to access but I do not know how to do this.
Can anyone help?
Yes, I have tried looking on google and through the forum's search tool so please do not direct me back there if that would be your only contribution. Thanks.
EDIT:
This worked
theValue = fiatRate_FCC_JSON[Currency1+'_'+Currency2];
Thanks Tanaike.
How about this?
theValue = fiatRate_FCC_JSON[Currency1+'_'+Currency2];
If this didn't work, please tell me. I would like to modify.
I think that can help you also
var theValue = fiatRate_FCC_JSON[fiatPairName[0]]
I want to make some links in my spreadsheet. I can make a string that looks like this. I looked around, though I did only find methods to link links that are already in the spreadsheet.
var linkBattlenet = "http://eu.battle.net/wow/en/character/"+toonrealm+"/"+toon.name+"/advanced"
var showLink = "battle.net link"+toon.name //this is what shall be seen in the spreadsheet.
I tried
var showLink = "battle.net link"+toon.name
var linkBattlenet = showLink.link("http://eu.battle.net/wow/en/character/"+toonrealm+"/"+toon.name+"/advanced")
Here i got the problem that it printed a string into the spreadsheet cell, that looks like this:
"%Character name%" .
(I am returnig the value in an array)
Instead of using showLink.link(), you can directly assign the string value to the cell.
Tried this code below:
function makeLink(){
var name = "john";
var showLink = ""http://eu.battle.net/wow/en/character/+name+"/advanced"";
var mainsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Main');
mainsheet.getActiveCell().setValue(showLink);
}
If you don't want to see the complete url in the cell, you can also try this line instead:
var showLink = '=HYPERLINK("http://eu.battle.net/wow/en/character/'+name+'/advanced","clickhere")';
Hope that helps!
I want to be able to add an "Ignore List" with the results being saved on the users browser.
The Ignored List is saved as a JSON array and looks like this:
[{"username":"test_user","date_added":"19/08/13","description":"Don't like this person."},{"username":"test_user_2","date_added":"19/08/13","description":"Don't like this person."}]
And the function required to add the users look like this:
function add_to_ignore_list()
{
var ignored_users = localStorage.getItem("ignore_list"); // returns ignore list
var username = return_current_username(); // returns test_user3
var date = return_current_date(); // returns 19/08/13
var description = prompt("Why do you want to ignore this user?"); // returns desc
add_to_list = {
"username" : username,
"date_added" : date,
"description" : description
};
ignored_users.push(add_to_list);
localStorage["ignore_list"] = JSON.stringify(ignored_users);
$(".user_wrapper").css("background-color","#B40404");
}
For some reason it isn't working and I can't see why Please help.
ignored_users is stored as a string.
When you retrieve it from localStorage, you need to parse it before you use it.
change:
var ignored_users = localStorage.getItem("ignore_list");
to (assumes it had previously been stored):
var ignored_users = JSON.parse(localStorage.getItem("ignore_list"));
In a mail merge application I use the .replace() method to replace field identifiers by custom values and also in a reverse process to get the identifiers back.
The first way works every time since the replace first argument is a pretty normal string that I have chosen on purpose... but when I reverse the process it happens sometimes that the string contains incorrect regular expression characters.
This happens mainly on phone numbers in the form +32 2 345 345 or even with some accentuated characters.
Given I can't prevent this from happening and that I have little hope that my endusers won't use this phone number format I was wondering if someone could suggest a workaround to escape illegal characters when they come up ? note : it can be at any place in the string.
below is the code for both functions.
... (partial code)
var newField = ChampSpecial(curData,realIdx,fctSpe);// returns the value from the database
if(newField!=''){replacements.push(newField+'∏'+'#ch'+(n+1)+'#')};
//Logger.log('value in '+n+'='+realIdx+' >> '+Headers[realIdx]+' = '+ChampSpecial(curData,realIdx,fctSpe))
app.getElementById('textField'+(n+1)).setHTML(ChampSpecial(curData,realIdx,fctSpe));
if(e.parameter.source=='insertInText'){
body.replaceText('#ch'+(n+1)+'#',newField);
}
}
UserProperties.setProperty('replacements',replacements.join('|'));
cloakOn();
colorize('#ffff44');
return app;
}
function fieldsInDoc(e){
cloakOff();// remet d'abord les champs vides
var replacements = UserProperties.getProperty('replacements').split('|');
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
for(var n=0;n<replacements.length;++n){
var field = replacements[n].split('∏')[1];
var testVal = replacements[n].split('∏')[0];
body.replaceText(testVal,field);
}
colorize('#ffff44');
}
In the reverse process you are using the fieldvalues provided that can include regex special characters. you have to escape them before replacing:
body.replaceText(field.replace(/[[\]{}()*-+?.,\\^$|#\s]/, '\\$&'), '#ch'+(n+1)+'#');
This said, the "replace back the markers" a bad idea. What happens if two fields of the mail merge have the same value or the replacement text is already present in the document template...
One possible solution was to prevent the example fields in the doc from containing regex special characters so the replace had to occur in the forward process, not in the reverse (as suggested in the other answer).
Escaping these character in the fields values didn't work* so I ended up with a simple replacement by a hyphen (which make sense in most cases to replace a slash or a '+').
(*) the reverse process uses the value kept in memory so the escape sign was disturbing the replace in that function, preventing it to work properly.
the final working code goes simply like this :
//(in the first function)
var newField = ChampSpecial(curData,realIdx,fctSpe).replace(/([*+?^=!:${}()|\[\]\/\\])/g, "-");// replace every occurrence of *+?^... by '-' (global search)
About the comment stating that this approach is a bad idea I can only say that I'm afraid there is not really other ways to get that behavior and that the probability to get errors if finally quite low since the main usage of mail merge is to insert proper names, adresses, emails and phone numbers that are rarely in the template itself.
As for the field indicators they will never have the same name since they are numerically indexed (#chXX#).
EDIT : following Taras's comment I'll try another solution, will update later if it works as expected.
EDIT June 19 , Yesssss... found it.
I finally found a far better solution that doesn't use regular expression so I'm not forced to escape special characters ... the .find() method accepts any string.
The code is a bit more complex but the results is worth the pain :-))
here is the full code in 2 functions if ever someone looks for something similar.
function valuesInDoc(e){
var lock = LockService.getPrivateLock(); // just in case one clicks the second button before this one ends
var success = lock.tryLock(5000);
if (!success) {
Logger.log('tryLock failed to get the lock');
return
}
colorize('#ffffff');// this function removes the color tags on the field marlers
var app = UiApp.getActiveApplication();
var listVal = UserProperties.getProperty('listSel').split(',');
var replacements = [];
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var find = body.findText('#ch');
if(find == null){return app };
var curData = UserProperties.getProperty('selItem').split('|');
var Headers = [];
var OriHeaders = UserProperties.getProperty('Headers').split('|');
for(n=0;n<OriHeaders.length;++n){
Headers.push('#'+OriHeaders[n]+'#');
}
var fctSpe = 0 ;
for(var i in Headers){if(Headers[i].indexOf('SS')>-1){fctSpe = i}}
for(var n=0;n<listVal.length;++n){
var realIdx = Number(listVal[n]);
Logger.log(n);
var newField = ChampSpecial(curData,realIdx,fctSpe);
//Logger.log(newField);
app.getElementById('textField'+(n+1)).setHTML(ChampSpecial(curData,realIdx,fctSpe));
if(e.parameter.source=='insertInText'){
var found = body.findText('#ch'+(n+1)+'#');// look for every field markers in the whole doc
while(found!=null){
var elemTxt = found.getElement().asText();
var startOffset = found.getStartOffset();
var len = ('#ch'+(n+1)+'#').length;
elemTxt.deleteText(startOffset, found.getEndOffsetInclusive())
elemTxt.insertText(startOffset,newField);// remove the marker and write the sample value in place
Logger.log('n='+n+' newField = '+newField+' for '+'#ch'+(n+1)+'#'+' at position '+startOffset)
replacements.push(newField+'∏'+'#ch'+(n+1)+'#'+'∏'+startOffset);// memorize the change that just occured
found = body.findText('#ch'+(n+1)+'#',found); //loop until all markers are replaced
}
}
}
UserProperties.setProperty('replacements',replacements.join('|'));
cloakOn();
colorize('#ffff44');// colorize the markers if ever one is left but it shouldn't happen
lock.releaseLock();
return app;
}
function fieldsInDoc(e){
var lock = LockService.getPrivateLock();
var success = lock.tryLock(5000);
if (!success) {
Logger.log('tryLock failed to get the lock');
return
}
cloakOff();// remet d'abord les champs vides > shows the hidden fields (markers that had no sample velue in the first function
var replacements = UserProperties.getProperty('replacements').split('|');// recover replacement data as an array
Logger.log(replacements)
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
for(var n=replacements.length-1;n>=0;n--){ // for each replacement find the data in doc and write a field marker in place
var testVal = replacements[n].split('∏')[0]; // [0] is the sample value
if(body.findText(testVal)==null){break};// this is only to handle the case one click on the wrong button trying to place markers again when they are already there ;-)
var field = replacements[n].split('∏')[1];
var testValLength = testVal.length;
var found = body.findText(testVal);
var startOffset = found.getStartOffset();
Logger.log(testVal+' = '+field+' / start: '+startOffset+' / Length: '+ testValLength)
var elemTxt = found.getElement().asText();
elemTxt.deleteText(startOffset, startOffset+testValLength-1);// remove the text
// elemTxt.deleteText(startOffset, found.getEndOffsetInclusive() )
elemTxt.insertText(startOffset,field);// and write the marker
}
colorize('#ffff44'); // colorize the marker
lock.releaseLock();// and release the lock
}
I have a script that goes through a spreadsheet, retrieves values from the cells and inserts the values in a doc. The code works perfectly but I've noticed that when I make a copy of the doc, run the same code and pass the doc ID within the code I get the following error:
No item with the given ID could be found, or you do not have permission to access it.
I've tried to make the doc public but I get the same error. Interestingly if I create a new doc and pass that doc ID to the function it works just fine.
the code:
var templateid = "1IrEbukq3cVKg9MAPT-Aanfe4XCzoc-RCJKq6sOpQKGU"; // get template file id
var copyDoc = DocsList.getFileById(templateid).makeCopy(docName);
I'm not sure I understood exactly when you problem occurs but I'd guess it is when you try to access copyDoc.
This is because you try to access it by its ID (as it appears from the error message) and you don't have it : from the code you write here copyDoc is a document, if you want its Id just add .getId() at the end like this :
var copyDoc = DocsList.getFileById(templateid).makeCopy(docName).getId();
Hoping I had the right guess ;-)
You could also do that like this so you'll have everything ready to use :
var doctemplate = DocumentApp.openById("1IrEbukq3cVKg9MAPT-Aanfe4XCzoc-RCJKq6sOpQKGU");// this can be placed outside the function as a global variable
var docname="new name for the copy";
var copydoc=DocsList.copy(doctemplate,docname);
var copydocId = copydoc.getId();
Edit : corrected error in code following jwesonga comment (thx)