GAS : How to check if a file exists in a specific folder and if so go to the next iteration - google-sheets

I'm writing a script that does the following :
send an email with an attachment (eg proof of payment) to people that register for our event when two criteria are met: payment has been processed, and if they have not yet received their proof of payment
make a copy of an existing file, using some variables in the new copy (this works fine) to personalize the proof of payment.
The copy of the file gets a new name (personalized).
I seem to be unable to make the script check correctly if the file already exists or not.
Who can help me out ?
function createDocument(e) {
var headers = Sheets.Spreadsheets.Values.get('SHEET ID', 'Lijst!A1:G');
var lid = Sheets.Spreadsheets.Values.get('SHEET ID', 'Lijst!A2:G');
var templateId = 'TEMPLATE ID';
for (var j = 0; j < lid.values.length; j++) {
if (lid.values[j][6] == 'ok' && lid.values[j][7] != 'Bewijs Verzonden') {
//collect the data from the member
var voornaam = lid.values[j][0];
var familienaam = lid.values[j][1];
var email = lid.values[j][2];
var aantal = lid.values[j][3];
var betaaldop = lid.values[j][5];
//Make a copy of the template file
var documentId = DriveApp.getFileById(templateId).makeCopy().getId();
var doc = DriveApp.getFileById(documentId);
var docname = 'Betalingsbewijs Reunie 2019 voor ' + familienaam + ' ' + voornaam + '.pdf';
//var filecheck = DriveApp.getFolderById('FOLDER ID');
var filecheck = DriveApp.getFilesByName(docname);
if (filecheck.hasNext()) {
Logger.log("No File Found");
} else {
//Get the document body as a variable
var body = DocumentApp.openById(documentId).getBody();
//Insert the data from spreadsheet
body.replaceText('<<Voornaam>>', voornaam)
body.replaceText('<<Naam>>', familienaam)
body.replaceText('<<Aantal deelnemers>>', aantal)
body.replaceText('<<Betaald op>>', betaaldop)
DocumentApp.openById(documentId).saveAndClose();
//move file to new folder and remove from parent folder
var file = DriveApp.getFileById(documentId);
file.getParents().next().removeFile(file);
DriveApp.getFolderById('FOLDER ID').addFile(file);
var pdfname = file.setName('Betalingsbewijs Reunie 2019 voor ' + familienaam + ' ' + voornaam + '.pdf');
var steil = "email#gmail.com";
var blob = pdfname.getBlob().getAs('application/pdf');
var subject = 'Betalingsbewijs Reunie 2019 voor ' + familienaam + ' ' + voornaam + ' met ' + aantal + 'deelnemer(s)';
var htmlBody =
"Beste " + voornaam + ", " +
"<br/>" +
"<br/>" +
"<br/>Bedankt voor uw inschrijving voor de Steil reünie op zaterdag 26 januari 2019." +
"<br/>Wij hebben uw betaling goed ontvangen." +
"<br/>Uw deelname aan de reünie is nu definitief in orde." +
"<br/>In bijlage kan u uw betalingsbewijs terugvinden in pdf." +
"<br/><br/>Indien u nog vragen heeft kan u ons steeds bereiken via reunie.steil#gmail.com." +
"<br/>Met verplegende groeten," +
"<br/>Het Steil Reünie team";
var optAdvancedArgs = {
name: "Steil Reünie 2019",
htmlBody: htmlBody,
replyTo: email,
cc: steil,
attachments: [blob]
};
GmailApp.sendEmail(email, subject, body, optAdvancedArgs);
var ConfirmationRange = "Lijst!H" + [j + 2];
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ConfirmationRange).setValue('Bewijs Verzonden');
}
}
}
}

Related

Opportunity Send Email

I tried to find a solution to my problem but I couldn't.
I have written some code to send an automatic email from Opportunity Salesforce and I write a test class but the code coverage doesn't go over 39%.
This is a code:
public class OpportunityEmail {
public static Boolean sendOppEmail(Opportunity opp){
OrgWideEmailAddress iOrgWideEmailAddress;
OrgWideEmailAddress iOrgWideEmailAddressAlert;
iOrgWideEmailAddress = OrgWideEmailAddressHelper.getByAddress(Label.SendPartnerOppEmail);
iOrgWideEmailAddressAlert = OrgWideEmailAddressHelper.getByAddress(Label.SendPartnerOppEmailAlert);
Boolean hasError = false;
Map<Id, Opportunity> mpOpp = new Map<Id, Opportunity>();
String msg = Label.OpportunitySendEmailSuccess;
Boolean myRet = false ;
System.debug(opp);
try {
Opportunity lstOpp = [select AccountId,Primary_Contact__c,CustomerAccount__c,SendEmailDone__c from Opportunity where id =: opp.Id];
Account accPrt = [select CompanyEmail__c from Account where id =: opp.AccountId];
String primContcSped = '';
if(opp.Primary_Contact__c != null){
Contact primContc = [select Email from Contact where id =: opp.Primary_Contact__c];
primContcSped = primContc.Email;
}
Account accCust = [select Account.Name,
Account.VATNumber__c,
Account.FiscalCode__c,
Account.Phone,
Account.Mobile__c,
Account.CompanyEmail__c,
Account.SDICode__c,
Account.BillingStreet,
Account.BillingPostalCode,
Account.BillingCity,
Account.BillingStateCode,
Account.BillingState,
Account.ShippingStreet,
Account.ShippingPostalCode,
Account.ShippingCity,
Account.ShippingStateCode,
Account.ShippingState from Account where id =: opp.CustomerAccount__c];
String Template = OpportunityEmail__c.getValues('Template1').TemplateEmail__c;
EmailTemplate eT = [select id, DeveloperName, Body, HtmlValue, Subject from EmailTemplate where Name =: Template];
Id TemplateId = eT.Id ;
String subject = eT.Subject;
String HtmlBody = eT.HtmlValue;
Id account = opp.Id;
String address = accPrt.CompanyEmail__c;
String ccaddress = '';
if(primContcSped != null){
ccaddress = primContcSped;
}
String ReplyToEmail = OpportunityEmail__c.getValues('Operation').ReplyToEmail__c;
String Customer = accCust.Name + '<br>' +
'P.Iva: ' + accCust.VATNumber__c + '<br>' +
'Cod.Fiscale: ' + accCust.FiscalCode__c + '<br>' +
'Telefono: ' + accCust.Phone + '<br>' +
'Mobile: ' + accCust.Mobile__c + '<br>' +
'Email: ' + accCust.CompanyEmail__c + '<br>' +
'SDI: ' + accCust.SDICode__c + '<br><br>' +
'Sede Legale: ' + '<br>' +
accCust.BillingStreet + ', ' + accCust.BillingPostalCode + ' ' + accCust.BillingCity + ' (' + accCust.BillingStateCode + ') ' + '<br><br>' +
'Sede Operativa: ' + '<br>' +
accCust.ShippingStreet + ', ' + accCust.ShippingPostalCode + ' ' + accCust.ShippingCity + ' (' + accCust.ShippingStateCode + ') ';
String Description = '';
if(opp.Description != null){
Description = opp.Description;
}
String ItemTable = '';
if(opp.HardwareBundle__c != null){
ItemTable = '<table style="width:30%;border: 1px solid black;"> <tr> <th style="text-align: left;border: 1px solid black;"> Service/Products </th> </tr>';
List<Schema.PicklistEntry> fieldResult = Opportunity.HardwareBundle__c.getDescribe().getPicklistValues();
Opportunity lstBund = [select HardwareBundle__c from Opportunity where id =: opp.Id];
String[] tmpBund = lstBund.HardwareBundle__c.split(';');
for(String s : tmpBund){
for(Schema.PicklistEntry f : fieldResult) {
if (f.getValue() == s){
ItemTable = ItemTable + '<tr> <td style = "text-align: left;">'+ f.getLabel()+'</td></tr>';
break;
}
}
}
ItemTable = ItemTable + '</table>';
}
subject = subject.replace('CustomerAccount', accCust.Name);
HtmlBody = HtmlBody.replace('{Customer1}', Customer);
HtmlBody = HtmlBody.replace('ItemTable', ItemTable);
HtmlBody = HtmlBody.replace('{!Description}', Description);
EmailManager.sendMailCcAdd(TemplateId, account, address, ccaddress, iOrgWideEmailAddress, ReplyToEmail, subject, HtmlBody);
lstOpp.SendEmailDone__c = true;
update lstOpp;
myRet = true ;
} catch (Exception e) {
String data = 'STACK TRACE:\n' +e.getStackTraceString() + '\nMESSAGE:\n' + e.getMessage()+ '\nLine:\n' + e.getLineNumber();
CustomLogHelper.addNewLog('OpportunityEmail.sendOppEmail',data);
CustomLogHelper.saveCurrentCustomLog();
hasError = true;
mpOpp.put(opp.id, opp);
msg = Label.OpportunitySendEmailFail +', Error: '+ data;
}
return myRet;
}
}
And this is a test class code
#isTest
private class OpportunityEmailTest2 {
#testSetup static void setup(){
EmailTemplate validEmailTemplate = new EmailTemplate();
validEmailTemplate.isActive = true;
validEmailTemplate.Name = 'PartnerEmail';
validEmailTemplate.DeveloperName = 'PartnerEmail';
validEmailTemplate.TemplateType = 'custom';
validEmailTemplate.FolderId = UserInfo.getUserId();
validEmailTemplate.IsActive = true;
validEmailTemplate.HtmlValue = 'Test email';
validEmailTemplate.Subject = 'Soggetto Email Test';
insert validEmailTemplate;
}
#isTest static void OpportunityEmailTest1() {
RecordType aRT = new RecordType();
aRT = [SELECT id, Name from RecordType where Name ='Company'];
Account accCust = new Account();
accCust.SDIPec__c = '1901837#gmail.com';
accCust.SDICode__c = '0000000';
accCust.Phone = '0233498737';
accCust.Mobile__c = '3452229458';
accCust.CompanyEmail__c = 'comp#gmail.com';
accCust.Name = 'Cuenta test1';
accCust.CommercialName__c = 'Cuenta test1';
accCust.VATNumber__c = '03442194837';
accCust.FiscalCode__c = 'RBNMHL70D15A059E';
accCust.BillingStreet = 'Via Pesciatina 129 Fraz. Lunata';
accCust.BillingPostalCode = '00187';
accCust.BillingCity = 'Legnano';
accCust.BillingStateCode = 'MI';
accCust.BillingState = 'Milan';
accCust.BillingCountryCode = 'IT';
accCust.ShippingStreet = 'Via Pesciatina 129 Fraz. Lunata';
accCust.ShippingPostalCode = '00187';
accCust.ShippingCity = 'Legnano';
accCust.ShippingStateCode = 'MI';
accCust.ShippingState = 'Milan';
accCust.RecordType = aRT;
insert accCust;
Account accPart = new Account();
accPart.SDIPec__c = '20190130#gmail.com';
accPart.SDICode__c = '0000000';
accPart.VATNumber__c = '03446283948';
accPart.FiscalCode__c = 'BRTLMN83C16B406T';
accPart.Name = 'Cuenta test2';
accPart.CommercialName__c = 'Cuenta test2';
accPart.CompanyEmail__c = 'CompanyEmail__2#gmail.com';
accPart.BillingStreet = 'VIA DE FLAGILLA 24';
accPart.BillingPostalCode = '00187';
accPart.BillingCity = 'ROMA';
accPart.BillingStateCode = 'RM';
accPart.BillingCountryCode = 'IT';
accPart.ShippingStreet = 'VIA DE FLAGILLA 24';
accPart.ShippingPostalCode = '00187';
accPart.ShippingCity = 'ROMA';
accPart.ShippingStateCode = 'RM';
accPart.RecordType = aRT;
insert accPart;
Contact pryCont = new Contact();
pryCont.LastName = 'Contact Test';
pryCont.MobilePhone = '3452229384';
pryCont.Email = 'contactemail#email.it';
insert pryCont;
Opportunity iOpport = new Opportunity();
iOpport.Name = 'Test Opportunity Email';
iOpport.StageName = 'Proposal';
iOpport.CloseDate = Date.today();
//iOpport.RecordTypeId = '0120N000000RUeXQAW'; //PROD
//iOpport.RecordTypeId = '0121w0000009fgJAAQ'; //PARTIAL COPY
iOpport.RecordTypeId = '0121w0000006dPnAAI'; //MYDEV
iOpport.AccountId = accPart.Id;
iOpport.CustomerAccount__c = accCust.Id;
iOpport.Primary_Contact__c = pryCont.Id;
iOpport.Description = 'Descrizione test';
iOpport.HardwareBundle__c = 'BD05';
iOpport.OpportunityHardware__c = true;
iOpport.SendEmailDone__c = false;
insert iOpport;
OpportunityEmail.sendOppEmail(iOpport);
OrgWideEmailAddress iOrgWideEmailAddress;
iOrgWideEmailAddress = OrgWideEmailAddressHelper.getByAddress(Label.SendPartnerOppEmail);
String Template = 'PartnerEmail';
EmailTemplate eT = [select id, DeveloperName, Body, HtmlValue, Subject from EmailTemplate where Name =: Template LIMIT 1];
Id TemplateId = eT.Id ;
String subject = eT.Subject;
String HtmlBody = eT.HtmlValue;
Id account = iOpport.Id;
String address = accPart.CompanyEmail__c;
String ccaddress = pryCont.Email;
String ReplyToEmail = 'replayemail#email.com';
String Customer = accCust.Name + '<br>' +
'P.Iva: ' + accCust.VATNumber__c + '<br>' +
'Cod.Fiscale: ' + accCust.FiscalCode__c + '<br>' +
'Telefono: ' + accCust.Phone + '<br>' +
'Mobile: ' + accCust.Mobile__c + '<br>' +
'Email: ' + accCust.CompanyEmail__c + '<br>' +
'SDI: ' + accCust.SDICode__c + '<br><br>' +
'Sede Legale: ' + '<br>' +
accCust.BillingStreet + ', ' + accCust.BillingPostalCode + ' ' + accCust.BillingCity + ' (' + accCust.BillingStateCode + ') ' + '<br><br>' +
'Sede Operativa: ' + '<br>' +
accCust.ShippingStreet + ', ' + accCust.ShippingPostalCode + ' ' + accCust.ShippingCity + ' (' + accCust.ShippingStateCode + ') ';
String Description = iOpport.Description;
String ItemTable = iOpport.HardwareBundle__c;
EmailManager.sendMailCcAdd(TemplateId, account, address, ccaddress, iOrgWideEmailAddress, ReplyToEmail, subject, HtmlBody);
}
}
I understood that the part of code not cover is this:
String Template = OpportunityEmail__c.getValues('Template1').TemplateEmail__c;
EmailTemplate eT = [select id, DeveloperName, Body, HtmlValue, Subject from EmailTemplate where Name =: Template];
Id TemplateId = eT.Id ;
String subject = eT.Subject;
String HtmlBody = eT.HtmlValue;
Id account = opp.Id;
String address = accPrt.CompanyEmail__c;
String ccaddress = '';
if(primContcSped != null){
ccaddress = primContcSped;
}
String ReplyToEmail = OpportunityEmail__c.getValues('Operation').ReplyToEmail__c;
String Customer = accCust.Name + '<br>' +
'P.Iva: ' + accCust.VATNumber__c + '<br>' +
'Cod.Fiscale: ' + accCust.FiscalCode__c + '<br>' +
'Telefono: ' + accCust.Phone + '<br>' +
'Mobile: ' + accCust.Mobile__c + '<br>' +
'Email: ' + accCust.CompanyEmail__c + '<br>' +
'SDI: ' + accCust.SDICode__c + '<br><br>' +
'Sede Legale: ' + '<br>' +
accCust.BillingStreet + ', ' + accCust.BillingPostalCode + ' ' + accCust.BillingCity + ' (' + accCust.BillingStateCode + ') ' + '<br><br>' +
'Sede Operativa: ' + '<br>' +
accCust.ShippingStreet + ', ' + accCust.ShippingPostalCode + ' ' + accCust.ShippingCity + ' (' + accCust.ShippingStateCode + ') ';
String Description = '';
if(opp.Description != null){
Description = opp.Description;
}
String ItemTable = '';
if(opp.HardwareBundle__c != null){
ItemTable = '<table style="width:30%;border: 1px solid black;"> <tr> <th style="text-align: left;border: 1px solid black;"> Service/Products </th> </tr>';
List<Schema.PicklistEntry> fieldResult = Opportunity.HardwareBundle__c.getDescribe().getPicklistValues();
Opportunity lstBund = [select HardwareBundle__c from Opportunity where id =: opp.Id];
String[] tmpBund = lstBund.HardwareBundle__c.split(';');
for(String s : tmpBund){
for(Schema.PicklistEntry f : fieldResult) {
if (f.getValue() == s){
ItemTable = ItemTable + '<tr> <td style = "text-align: left;">'+ f.getLabel()+'</td></tr>';
break;
}
}
}
ItemTable = ItemTable + '</table>';
}
subject = subject.replace('CustomerAccount', accCust.Name);
HtmlBody = HtmlBody.replace('{Customer1}', Customer);
HtmlBody = HtmlBody.replace('ItemTable', ItemTable);
HtmlBody = HtmlBody.replace('{!Description}', Description);
EmailManager.sendMailCcAdd(TemplateId, account, address, ccaddress, iOrgWideEmailAddress, ReplyToEmail, subject, HtmlBody);
lstOpp.SendEmailDone__c = true;
update lstOpp;'
But I don't understand which is a solution.
Thank you so much for your help!
String Template = OpportunityEmail__c.getValues('Template1').TemplateEmail__c;
In this line, I see that you are trying to access a Custom Setting OpportunityEmail__c. Custom Settings behave just like data, which means that you need to insert it in the test method before you can use it.
Your other option is to use a Custom Metadata Type instead, which can be retrieved from the environment via a SOQL query.

RangeError: Maximum call stack size exceeded with vanilla JS

I'm finishing my first project where I POST data to a server and then retrieve it in the form of a list on a separate page. I have gotten to the point where I can now post and retrieve the data, however I'm getting this error:
Uncaught RangeError: Maximum call stack size exceeded
at renderSearchResults (menu.js:8)
at renderSearchResults (menu.js:38)
My code is below. Any help would be appreciated.
var userInfo = JSON.parse(sessionStorage.getItem('user'));
function search() {
/* var userInfo = JSON.parse(sessionStorage.getItem('user')); */
var xhr = new XMLHttpRequest();
xhr.open('GET', (`https://ict4510.herokuapp.com/api/menus?api_key=${userInfo.user.api_key}` ));
xhr.onload = function renderSearchResults() {
if (this.status == 200) {
var menuInfo = JSON.parse(this.responseText);
var output = '';
for (var i in menuInfo.menu) {
output +=
'<div class="foodItems">' +
'<ul>' +
'<li>Food Item: ' + menuInfo.menu[i].item + '</li>' +
'<li>Description: ' + menuInfo.menu[i].description + '</li>' +
'<li> Price: ' + menuInfo.menu[i].price + '</li>' +
'</ul>' +
+
'</div>';
}
console.log(output);
document.getElementById('foods').innerHTML = output;
}
renderSearchResults();
}
xhr.send();
}
search();

Run script if cell change in Google Sheets

I have this code, it works if i run it from Script Editor, but doesnt run when i change the cell to "Send Melding". The script runs until it comes to MailApp.sendEmail, then it stops..
Heres the code :
function onEdit(e) {
var s = SpreadsheetApp.getActiveSheet(), r, colCell;
if(s.getName() === 'SkapOversikt') { //checks that we're on the correct sheet
r = s.getActiveCell();
colCell = r.getColumn();
if(colCell === 1 || colCell === 6) { //checks the column
nextCell = r.offset(0, 0);
if(nextCell.getValue() === 'Send Melding') { //Inneholder "Send Melding", kjør script
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = sheet.getRange(7, 7).getValue();
var subject = 'Skapoversikt har blitt oppdatert på : '+sheet.getRange(4, 2).getValue();
var body = 'Blåse info på ' + sheet.getRange(4, 2).getValue() + ' har blitt oppdatert. ' + '\n' + '\nFølg link for å se endringer : ' + ss.getUrl() + '\n' + '\n' + 'Melding fra melder : ' + '\n' + '" ' + sheet.getRange(6, 7).getValue() + ' " ' + '\n ' + '\n (Dette er en generert mail fra Google Sheets og vil ikke kunne besvares) ' + '\n' + '\n - AK AS ';
MailApp.sendEmail(recipients, subject, body);
var sheet = SpreadsheetApp.getActive().getSheetByName('SkapOversikt');
sheet.getRange('G6').setValue('Ingen Melding');
sheet.getRange('A6').setValue('Velg');
Browser.msgBox('Takk for det - Meldingen er sendt!' , 'Meldingen er sendt til : '+sheet.getRange(7, 7).getValue()+ '\n' + ' - (Fra epost : )', Browser.Buttons.OK);
}
}
}
}
I don't think you can send emails on a simple onEdit trigger. Try changing the name of your function (e.g: sendMails(e) ) and add an installable trigger by going into Resources > add a trigger > sendMails > from spreadsheet > on Edit.
See if it then works ?

Getting all videos of a channel using youtube API

I want to get all videos of a single channel that i have its Id. The problem that I am getting only the channel informations.
this is the link that I am using:
https://gdata.youtube.com/feeds/api/users/UCdCiB_pNQpR0M_KkDG4Dz5A?v=2&alt=json&q=goal&orderby=published&max-results=10
That link is for the now-retired V2 API, so it will not return any data. Instead, you'll want to use V3 of the API. The first thing you'll need to do is register for an API key -- you can do this by creating a project at console.developers.google.com, setting the YouTube data API to "on," and creating a public access key.
Since you have your user channel ID already, you can jump right into getting the videos from it; note, however, that if you ever don't know the channel ID, you can get it this way:
https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername={username}&key={YOUR_API_KEY}
With the channel ID, you can get all the videos from the channel with the search endpoint, like this:
https://www.googleapis.com/youtube/v3/search?order=date&part=snippet&channelId={channel id here}&maxResults=25&key={YOUR_API_KEY}
In this case, ordering by date is the same as the old V2 parameter for ordering by "published."
There are also a lot of other parameters you can use to retrieve videos while searching a channel; see https://developers.google.com/youtube/v3/docs/search/list for more details.
I thought I would share my final result using JavaScript. It uses the Google YouTube API key and UserName to get the channel ID, then pulls the videos and displays in a list to a given div tag.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>YouTube Channel Listing</title>
<script type="text/javascript">
function getJSONData(yourUrl) {
var Httpreq = new XMLHttpRequest();
try {
Httpreq.open("GET", yourUrl, false);
Httpreq.send(null);
} catch (ex) {
alert(ex.message);
}
return Httpreq.responseText;
}
function showVideoList(username, writediv, maxnumbervideos, apikey) {
try {
document.getElementById(writediv).innerHTML = "";
var keyinfo = JSON.parse(getJSONData("https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=" + username + "&key=" + apikey));
var userid = keyinfo.items[0].id;
var channeltitle = keyinfo.items[0].snippet.title;
var channeldescription = keyinfo.items[0].snippet.description;
var channelthumbnail = keyinfo.items[0].snippet.thumbnails.default.url; // default, medium or high
//channel header
document.getElementById(writediv).innerHTML += "<div style='width:100%;min-height:90px;'>"
+ "<a href='https://www.youtube.com/user/" + username + "' target='_blank'>"
+ "<img src='" + channelthumbnail + "' style='border:none;float:left;margin-right:10px;' alt='" + channeltitle + "' title='" + channeltitle + "' /></a>"
+ "<div style='width:100%;text-align:center;'><h1><a href='https://www.youtube.com/user/" + username + "' target='_blank'>" + channeltitle + "</a></h1>" + channeldescription + "</div>"
+ "</div>";
var videoinfo = JSON.parse(getJSONData("https://www.googleapis.com/youtube/v3/search?order=date&part=snippet&channelId=" + userid + "&maxResults=" + maxnumbervideos + "&key=" + apikey));
var videos = videoinfo.items;
var videocount = videoinfo.pageInfo.totalResults;
// video listing
for (var i = 0; i < videos.length; i++) {
var videoid = videos[i].id.videoId;
var videotitle = videos[i].snippet.title;
var videodescription = videos[i].snippet.description;
var videodate = videos[i].snippet.publishedAt; // date time published
var videothumbnail = videos[i].snippet.thumbnails.default.url; // default, medium or high
document.getElementById(writediv).innerHTML += "<hr /><div style='width:100%;min-height:90px;'>"
+ "<a href='https://www.youtube.com/watch?v=" + videoid + "' target='_blank'>"
+ "<img src='" + videothumbnail + "' style='border:none;float:left;margin-right:10px;' alt='" + videotitle + "' title='" + videotitle + "' /></a>"
+ "<h3><a href='https://www.youtube.com/watch?v=" + videoid + "' target='_blank'>" + videotitle + "</a></h3>" + videodescription + ""
+ "</div>";
}
} catch (ex) {
alert(ex.message);
}
}
</script>
</head>
<body>
<div id="videos"></div>
<script type="text/javascript">
showVideoList("USER_NAME", "videos", 25, "YOUR_API_KEY");
</script>
</body>
</html>
ADDITION - I also wrote a function to handle if you are using a channel ID instead of a UserName based account.
Here is that code:
function showVideoListChannel(channelid, writediv, maxnumbervideos, apikey) {
try {
document.getElementById(writediv).innerHTML = "";
var vid = getJSONData("https://www.googleapis.com/youtube/v3/search?order=date&part=snippet&channelId=" + channelid + "&maxResults=" + (maxnumbervideos + 1) + "&key=" + apikey);
var videoinfo = JSON.parse(vid);
var videos = videoinfo.items;
var videocount = videoinfo.pageInfo.totalResults;
var content = "<div style='height:600px;overflow-y:auto;'>";
for (var i = 0; i < videos.length - 1; i++) {
var videoid = videos[i].id.videoId;
var videotitle = videos[i].snippet.title;
var videodescription = videos[i].snippet.description;
var videodate = videos[i].snippet.publishedAt; // date time published
var newdate = new Date(Date.parse((videodate + " (ISO 8601)").replace(/ *\(.*\)/, "")));
var min = newdate.getMinutes();
if (min < 10) {
min = "0" + min;
}
if (newdate.getHours() > 12) {
newdate = newdate.getMonth() + 1 + "/" + newdate.getDate() + "/" + newdate.getFullYear() + " " + (newdate.getHours() - 12) + ":" + min + " PM";
} else if (newdate.getHours() == 12) {
newdate = newdate.getMonth() + 1 + "/" + newdate.getDate() + "/" + newdate.getFullYear() + " " + newdate.getHours() + ":" + min + " PM";
} else {
newdate = newdate.getMonth() + 1 + "/" + newdate.getDate() + "/" + newdate.getFullYear() + " " + newdate.getHours() + ":" + min + " AM";
}
var videothumbnail = videos[i].snippet.thumbnails.default.url; // default, medium or high
content += "<hr /><div style='width:100%;min-height:90px;'>"
+ "<a href='https://www.youtube.com/watch?v=" + videoid + "' target='_blank'>"
+ "<img src='" + videothumbnail + "' style='border:none;float:left;margin-right:10px;' alt='" + videotitle + "' title='" + videotitle + "' /></a>"
+ "<h3><a href='https://www.youtube.com/watch?v=" + videoid + "' target='_blank'>" + videotitle + "</a></h3>" + videodescription + "<br />"
+ "<span style='color:#738AAD;font-size:Small;'>" + newdate + "</span>"
+ "</div>";
}
content += "</div>";
document.getElementById(writediv).innerHTML = content;
} catch (ex) {
alert(ex.message);
}
}
It is very easy method to get channel videos using your channel API key:
Step 1: You must have an YouTube account.
Step 2: Create your YouTube channel API key
Step 3: Create project console.developers.google.com,
<?php
$API_key = 'Your API key'; //my API key dei;
$channelID = 'Your Channel ID'; //my channel ID
$maxResults = 5;
$video_list =
json_decode(file_get_contents('https://www.googleapis.com/youtube/v3/search?
order=date&part=snippet&channelId='.$channelID.
'&maxResults='.$maxResults.'&key='.$API_key.''));
?>
Example : https://www.googleapis.com/youtube/v3/channelspart=snippet&forUsername=
{username}&key={YOUR_API_KEY}
Here is the way to get all videos with only 2 quotas using YouTube Data API (v3)
First of all do a list on channels with part=contentDetails (1 quota) :
https://youtube.googleapis.com/youtube/v3/channels?part=contentDetails&id=[CHANNEL_ID]&key=[YOUR_API_KEY]
You will get this result :
{
...
"items": [
{
...
"contentDetails": {
"relatedPlaylists": {
"likes": "",
"uploads": "UPLOADS_PLAYLIST_ID"
}
}
}
]
}
Then take UPLOADS_PLAYLIST_ID and do a list on playlistItems with part=contentDetails (1 quota):
https://youtube.googleapis.com/youtube/v3/playlistItems?part=contentDetails&playlistId=[UPLOADS_PLAYLIST_ID]&key=[YOUR_API_KEY]
You will get this result:
{
...
"items": [
{
...
"contentDetails": {
"videoId": "VIDEO_ID",
"videoPublishedAt": "2022-10-27T16:00:08Z"
}
},
...
],
"pageInfo": {
"totalResults": 5648,
"resultsPerPage": 5
}
}
You got the list of the videos under items
You can of course change the size of this list by adding maxResults=50 (max value is 50)

simplify and rearrange my google script for faster process this often stucks in the middle of the process

Can anyone simplify and rearrange my script such that it works faster without stucking . This script was made to extract spreadsheet data from 4 spreadsheets and deleting blank rows based on a column criteria, This script is working well but taking long time and suddenly/often breaks process saying that spreadsheet page needs to refresh thus stopping the entire process. which should follow with rerunning the script. - Thanks in advance.
my script is as follows :
function myFunction() {
// spreadsheets key to extract data.
//Bhaskar 0AjkkHlm3kCphdFh3M2dtRDdoZHhWZlg5UzFjSWZFcVE
//RAmohan 0AjkkHlm3kCphdGFlNTVhSDc5VXVTeS0xc2ZISDRGZlE
//Krishnareddy 0AjkkHlm3kCphdEhDWEllalpoM3VmNE5weUNLZkd4TVE
//Suni 0AjkkHlm3kCphdFUxTXJlN3lGYkRMY2NXUUkzSTVfbEE
var copieddata = SpreadsheetApp.openById('0AjkkHlm3kCphdFh3M2dtRDdoZHhWZlg5UzFjSWZFcVE').
getSheetByName('List').getDataRange().getValues();
//getSheetByName('List').getRange('I6:AT500').getValues();
var s1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
SpreadsheetApp.setActiveSheet(s1);
//getRange(StartingROWS(1,2,3,4,...),StartingCOLUMNS(A,B,C,D..),
s1.getRange(1,1,copieddata.length,copieddata[0].length).setValues(copieddata);
//var col1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumColumns();
//var row1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumRows();
SpreadsheetApp.flush(); //force the data to be written
// here ends sheet 1 -------
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var numRows = sheet.getLastRow();
var datasheet = sheet.getDataRange();
var data = datasheet.getValues();
//Browser.msgBox(" data lenght -" + data.length + " rage is " + datasheet);
for (var i = data.length; i > 0; --i){
var ii=i-1;
var row = data[ii];
var name = row[6];
var len = name.length;
//Browser.msgBox("row number" + i + " ->" + row[10] + "<- its length =" + len);
if(name.length!=3){
//Browser.msgBox("delete ." + i);
sheet.deleteRow(i);
}
SpreadsheetApp.flush(); //force the data to be written
}
SpreadsheetApp.flush(); //force the data to be written
// ------------------
var lrange = SpreadsheetApp.getActiveSheet().getLastRow();
//Browser.msgBox("l range - " + lrange);
var copieddata = SpreadsheetApp.openById('0AjkkHlm3kCphdGFlNTVhSDc5VXVTeS0xc2ZISDRGZlE').
getSheetByName('List').getDataRange().getValues();
var s1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
SpreadsheetApp.setActiveSheet(s1);
s1.getRange((lrange+1),1,copieddata.length,copieddata[0].length).setValues(copieddata);
//var col1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumColumns();
//var row1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumRows();
SpreadsheetApp.flush(); //force the data to be written
// here ends sheet 2 -------
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var numRows = sheet.getLastRow();
var datasheet = sheet.getDataRange();
var data = datasheet.getValues();
//Browser.msgBox(" data lenght -" + data.length + " rage is " + datasheet);
for (var i = data.length; i > 0; --i){
var ii=i-1;
var row = data[ii];
var name = row[6];
var len = name.length;
//Browser.msgBox("row number" + i + " ->" + row[10] + "<- its length =" + len);
if(name.length!=3){
//Browser.msgBox("delete ." + i);
sheet.deleteRow(i);
}
SpreadsheetApp.flush(); //force the data to be written
}
// ------------------
var lrange = SpreadsheetApp.getActiveSheet().getLastRow();
//Browser.msgBox("l range - " + lrange);
var copieddata = SpreadsheetApp.openById('0AjkkHlm3kCphdEhDWEllalpoM3VmNE5weUNLZkd4TVE').
getSheetByName('List').getDataRange().getValues();
var s1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
SpreadsheetApp.setActiveSheet(s1);
s1.getRange((lrange+1),1,copieddata.length,copieddata[0].length).setValues(copieddata);
//var col1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumColumns();
//var row1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumRows();
SpreadsheetApp.flush(); //force the data to be written
// here ends sheet 3 -------
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var numRows = sheet.getLastRow();
var datasheet = sheet.getDataRange();
var data = datasheet.getValues();
//Browser.msgBox(" data lenght -" + data.length + " rage is " + datasheet);
for (var i = data.length; i > 0; --i){
var ii=i-1;
var row = data[ii];
var name = row[6];
var len = name.length;
//Browser.msgBox("row number" + i + " ->" + row[10] + "<- its length =" + len);
if(name.length!=3){
//Browser.msgBox("delete ." + i);
sheet.deleteRow(i);
}
SpreadsheetApp.flush(); //force the data to be written
}
// ------------------
var lrange = SpreadsheetApp.getActiveSheet().getLastRow();
//Browser.msgBox("l range - " + lrange);
var copieddata = SpreadsheetApp.openById('0AjkkHlm3kCphdFUxTXJlN3lGYkRMY2NXUUkzSTVfbEE').
getSheetByName('List').getDataRange().getValues();
var s1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
SpreadsheetApp.setActiveSheet(s1);
s1.getRange((lrange+1),1,copieddata.length,copieddata[0].length).setValues(copieddata);
//var col1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumColumns();
//var row1count = SpreadsheetApp.getActiveSheet().getRange(1,1,copieddata.length,copieddata[0].length).getNumRows();
SpreadsheetApp.flush(); //force the data to be written
// here ends sheet 4 -------
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var numRows = sheet.getLastRow();
var datasheet = sheet.getDataRange();
var data = datasheet.getValues();
//Browser.msgBox(" data lenght -" + data.length + " rage is " + datasheet);
for (var i = data.length; i > 0; --i){
var ii=i-1;
var row = data[ii];
var name = row[6];
var len = name.length;
//Browser.msgBox("row number" + i + " ->" + row[10] + "<- its length =" + len);
if(name.length!=3){
//Browser.msgBox("delete ." + i);
sheet.deleteRow(i);
}
SpreadsheetApp.flush(); //force the data to be written
}
}
spreadsheet link is as follows : Clik here to enter into my spreadsheet
here's my attempt:
function myFunction2() {
var source = ['0AjkkHlm3kCphdFh3M2dtRDdoZHhWZlg5UzFjSWZFcVE',
'0AjkkHlm3kCphdGFlNTVhSDc5VXVTeS0xc2ZISDRGZlE',
'0AjkkHlm3kCphdEhDWEllalpoM3VmNE5weUNLZkd4TVE',
'0AjkkHlm3kCphdFUxTXJlN3lGYkRMY2NXUUkzSTVfbEE'];
var copied = [];
for (var i = 0; i < source.length; i++) {
copied = copied.concat(SpreadsheetApp.openById(source[i]).getSheetByName('List').getDataRange().getValues());
}
for (var j = 0; j < copied.length; j++) {
if (copied[j][6].length != 3) {
copied.splice(j, 1);
j--;
}
}
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
sheet.clearContents();
sheet.getRange(1, 1, copied.length, copied[0].length).setValues(copied);
}
In this I create one big javascript array from the four spreadsheets, remove elements ("rows") from that array (rather than deleting rows in the spreadsheet itself which I presume is the reason why it's slow), clear the destination sheet, and set the values of the modified array in one go.
HTH
Adam

Resources