I am a newbie and am trying to use a script to send our school website's feeds
to our Google Chat (Google Workspace for Edu).
I found a code here that works like a charm with the testing Url (https://cloudblog.withgoogle.com/products/gcp/rss/),
but returns me an error when I point to our school's website.
TypeError: Cannot read property 'getChild' of null
Here is the code and below the Debug error
// URL of the RSS feed to parse
var RSS_FEED_URL = "https://www.icriccardomassa.edu.it/agid/feed/";
// https://cloudblog.withgoogle.com/products/gcp/rss/"; <- this works!
// Webhook URL of the Hangouts Chat room
var WEBHOOK_URL = "https://chat.googleapis.com/v1/spaces/AAAAueQ0Yzk/messages?key=AI [..]";
// When DEBUG is set to true, the topic is not actually posted to the room
var DEBUG = false;
function fetchNews() {
var lastUpdate = new Date(PropertiesService.getScriptProperties().getProperty("lastUpdate"));
var lastUpdate = new Date(parseFloat(PropertiesService.getScriptProperties().getProperty("lastUpdate")) || 0);
Logger.log("Last update: " + lastUpdate);
Logger.log("Fetching '" + RSS_FEED_URL + "'...");
var xml = UrlFetchApp.fetch(RSS_FEED_URL).getContentText();
var document = XmlService.parse(xml);
// var items = document.getRootElement().getChild('channel').getChildren('item').reverse();
var items = document.getRootElement().getChild('channel').getChildren('item').reverse();
Logger.log(items.length + " entrie(s) found");
var count = 0;
for (var i = 0; i < items.length; i++) {
var pubDate = new Date(items[i].getChild('pubDate').getText());
var og = items[i].getChild('og');
var title = og.getChild("title").getText();
var description = og.getChild("description").getText();
var link = og.getChild("url").getText();
if(DEBUG){
Logger.log("------ " + (i+1) + "/" + items.length + " ------");
Logger.log(pubDate);
Logger.log(title);
Logger.log(link);
// Logger.log(description);
Logger.log("--------------------");
}
if(pubDate.getTime() > lastUpdate.getTime()) {
Logger.log("Posting topic '"+ title +"'...");
if(!DEBUG){
postTopic_(title, description, link);
}
PropertiesService.getScriptProperties().setProperty("lastUpdate", pubDate.getTime());
count++;
}
}
Logger.log("> " + count + " new(s) posted");
}
function postTopic_(title, description, link) {
var text = "*" + title + "*" + "\n";
if (description){
text += description + "\n";
}
text += link;
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify({
"text": text
})
};
UrlFetchApp.fetch(WEBHOOK_URL, options);
}
Thank you in advance for your help!
Debugger errors
I need to get a here-API token to use it in HERE Matrix Routing API but I can't get it. the response from the server always return the below
"{"errorId":"ERROR-b877e827-1ed6-4a2d-bed8-
546d1b9b3bd6","httpStatus":401,"errorCode":401205,"message":"Unsupported
signature method in the header. Require HMAC-
SHA256","error":"invalid_request","error_description":"errorCode:
'401205'. Unsupported signature method in the header. Require HMAC-
SHA256"}"
here is my code :
var grant_type = 'client_credentials';
var oauth_consumer_key = 'koauth_consumer_key';
var access_key_secret = 'access_key_secret';
var oauth_nonce = DateTime.now().millisecondsSinceEpoch.toString();
var oauth_timestamp = (new DateTime.now().toUtc().millisecondsSinceEpoch / 100).toString();
var oauth_signature_method = 'HMAC-SHA256';
var oauth_version = '1.0';
var url = 'https://account.api.here.com/oauth2/token';
create_signature(secret_key, signature_base_string) {
var temp = Hmac(sha256, utf8.encode(secret_key)).convert(utf8.encode(signature_base_string));
var hmacBase64 = base64Encode(temp.bytes);
print(hmacBase64);
return hmacBase64;
}
create_parameter_string(grant_type, oauth_consumer_key, oauth_nonce, oauth_signature_method, oauth_timestamp, oauth_version) {
parameter_string = '';
parameter_string = parameter_string + 'grant_type=' + grant_type;
parameter_string = parameter_string + '&oauth_consumer_key=' + oauth_consumer_key;
parameter_string = parameter_string + '&oauth_nonce=' + oauth_nonce;
parameter_string = parameter_string + '&oauth_signature_method=' + oauth_signature_method;
parameter_string = parameter_string + '&oauth_timestamp=' + oauth_timestamp;
parameter_string = parameter_string + '&oauth_version=' + oauth_version;
return parameter_string;
}
create encoded_oauth_signature
var parameter_string = create_parameter_string(grant_type, oauth_consumer_key, oauth_nonce, oauth_signature_method, oauth_timestamp, oauth_version);
var encoded_parameter_string = Uri.encodeComponent(parameter_string);
var encoded_base_string = 'POST' + '&' + Uri.encodeComponent(url) + '&' + encoded_parameter_string;
var signing_key = access_key_secret + '&';
var oauth_signature = create_signature(signing_key, encoded_base_string);
var encoded_oauth_signature = Uri.encodeComponent(oauth_signature);
// #---------------------Requesting Token---------------------
var body = {
'grant_type': '$grant_type'
};
preparing body and header
var headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'OAuth oauth_consumer_key="$oauth_consumer_key",oauth_nonce="$oauth_nonce",oauth_signature_method="HMAC-SHA256",oauth_timestamp="$oauth_timestamp",oauth_version="1.0",oauth_signature="$encoded_oauth_signature"'
};
get token:
gettokenpy() async {
final response = await http.post(
Uri.parse(url),
body: body,
headers: headers,
);
return response.body.toString();
}
The error message indicates that input signature method is not supported. It is supposed to be HMAC-SHA256. The following guide can help you to understand how to get the OAuth 2.0 token.
https://developer.here.com/documentation/identity-access-management/dev_guide/topics/sdk.html#step-3-request-a-token
In Google Form, on submit, I want to send a new message as one of the fields from the form and want to include the rest of the form fields as threaded messages in to the parent message.
I manually captured one of my thread_ts and successfully sent threaded messages. But I do not know what is the [best] way to get thread_ts id as I submit the form.
var channel = 'xxxx';
function onSubmit(e) {
var response = e.response.getItemResponses();
var Parent = response[0].getResponse();
var Thread = response[1].getResponse();
var Thread2 = response[2].getResponse();
var message = '#Test - ' + Parent;
var payload = {
"payload": '{"text": "' + message + '"}'
//"payload": '{"channel": "xxx","thread_ts": "1571950486.000500","text": "' + Thread + '--' + Thread2 + '"}'
}
var options = {
"method": "post",
"payload": payload
};
UrlFetchApp.fetch(webhookUrl, options);
};
I do not get any errors.
Here is how I was able to do it:
var webhookUrl = 'https://hooks.slack.com/services/***/***/***';
function SendtoSlack(e) {
var formResponse = e.response;
var itemResponses = formResponse.getItemResponses();
for (var i = 0; i < itemResponses.length; i++) {
switch (itemResponses[i].getItem().getTitle()) {
case "Client":
var Client = itemResponses[i].getResponse() || '';
break;
case "Day":
var date = itemResponses[i].getResponse() || '';
break;
case "Time":
var time = itemResponses[i].getResponse() || '';
break;
case "Device":
var Device = itemResponses[i].getResponse() || '';
break;
case "Browser":
var Browser = itemResponses[i].getResponse() || '';
break;
case "Geo":
var GEO = itemResponses[i].getResponse() || '';
break;
}
}
var redirectAlert = '#***'+' - ' + Client;
var payload = {
"payload": '{"text": "' + redirectAlert + '"}',
}
var options = {
"method": "post",
"payload": payload
};
UrlFetchApp.fetch(webhookUrl, options);
var webhookUrl1 = 'https://slack.com/api/conversations.history?token=xoxp-***-***-***-***&channel=***&pretty=1';
var slackJSON = UrlFetchApp.fetch(webhookUrl1);
var slackJSONObject = JSON.parse(slackJSON);
var ts = slackJSONObject.messages[0].ts;
var threadedMessagePayload = {
"payload": '{"thread_ts": "' + ts + '","text": "' + '`\nDevice: ' + Device + '\nBrowser: ' + Browser + '\nGeo: ' + GEO + '\nReported Date & Time: ' + date + ' ' + time + '"}',
}
var optionsForThreadedMessage = {
"method": "post",
"payload": threadedMessagePayload
};
UrlFetchApp.fetch(webhookUrl, optionsForThreadedMessage);
}
What I need to do to circumvent this issue, because when I request data for 2 months I already receive this error, when there is a break per day, I have the following call. With Little data works perfect, but when I increase the period the server brings me
User request limit reached","type":"OAuthException","is_transient":true,"code":17,"error_subcode":2446079,"fbtrace_id":"...
function solicitacaoAssicrona(){
var service = getService()
var batch = [{"method": "GET", "relative_url":"v3.2/act_1125789557444919/insights/impressions,reach,frequency,spend,campaign_name,account_name,clicks,cost_per_10_sec_video_view,cpm,cpp?level=campaign&since=2016-03-03&until=2019-03-04&time_increment=1&limit=100"}]
// var batchUrl = encodeURIComponent(JSON.stringify(batch));
// Logger.log(batchUrl);
var url = "https://graph.facebook.com?include_headers=false&batch=" + encodeURIComponent(JSON.stringify(batch))
var response = UrlFetchApp.fetch(url, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
var result = JSON.parse(response.getContentText());
Logger.log(result)
// response.forEach(function(resp){
// var resp = JSON.parse(resp.body);
// //Logger.log(JSON.stringify(resp, null, 2));
//
//// resp.data[0].values.forEach(function(response){
////
////
//// })
////
// })
}
I'Ve looked at the documentation, but to the moment without success!
https://developers.facebook.com/docs/marketing-api/insights/best-practices/
That's the call I have
var metricas = [
'impressions',
'reach',
'unique_clicks',
'account_currency',
'account_id',
'account_name',
'ad_id',
'ad_name',
'adset_id',
'adset_name',
'buying_type',
'campaign_id',
'campaign_name',
'clicks',
'cost_per_inline_link_click',
'cost_per_inline_post_engagement',
'cost_per_unique_click',
'cost_per_unique_inline_link_click',
'cpc',
'cpm',
'cpp',
'ctr',
'date_start',
//'date_stop',
'frequency',
'inline_link_click_ctr',
'inline_link_clicks',
'inline_post_engagement',
'objective',
'relevance_score',
'social_spend',
'spend',
'unique_ctr',
'unique_inline_link_click_ctr',
'unique_inline_link_clicks',
'unique_link_clicks_ctr',
//'website_ctr',
'video_10_sec_watched_actions',
'cost_per_10_sec_video_view',
'video_30_sec_watched_actions',
'video_avg_percent_watched_actions',
'video_avg_time_watched_actions',
'video_p100_watched_actions',
'video_p25_watched_actions',
'video_p50_watched_actions',
'video_p75_watched_actions',
'video_play_actions',
'video_thruplay_watched_actions',
'video_p95_watched_actions',
]
var parameters = metricas.join(',');
var url = 'https://graph.facebook.com/v3.2/act_xxxxxxxxxx/insights?fields= + parameters + '&level=ad&time_range[since]=2019-02-05&time_range[until]=2019-04-05&time_increment=1&limit=200'
It's to do with how much data you can retrieve with batch requests. For longer periods, you should divide it into smaller chunks, sequential to each other, thus retrieving the data needed in multiple requests. Have a look at this example:
Code.gs
From line 88 of the file, you can see how it can be divided in multiple requests.
https://github.com/halsandr/Facebook_Connector/blob/master/Code.gs
function dateDelta(dObj, num) {
if (isNaN(num)) {
var dateStart = new Date(dObj);
} else {
var dateStart = new Date(dObj);
var dateStart = new Date(dateStart.setDate(dateStart.getDate() + num));
}
var dd = dateStart.getDate();
var mm = dateStart.getMonth()+1; //January is 0!
var yyyy = dateStart.getFullYear();
if(dd<10){
dd='0'+dd;
}
if(mm<10){
mm='0'+mm;
}
var dateStart = yyyy + "-" + mm + "-" + dd;
return dateStart;
}
var gStartDate = new Date(request.dateRange.startDate);
var gStartDate = new Date(dateDelta(gStartDate, -1));
var gEndDate = new Date(request.dateRange.endDate);
var gEndDate = new Date(dateDelta(gEndDate, +1));
var gRange = Math.ceil(Math.abs(gEndDate - gStartDate) / (1000 * 3600 * 24));
var gBatches = Math.ceil(gRange / 92);
if (gBatches < 2) {
var batch = [{"method": "GET", "relative_url": request.configParams.pageID + "/insights/page_fans,page_impressions,page_post_engagements?since=" + dateDelta(gStartDate) + "&until=" + dateDelta(gEndDate)}];
//console.log(batch);
} else {
batch = [];
var iterRanges = gRange / gBatches;
for (i = 0; i < gBatches; i++) {
var iterStart = dateDelta(gStartDate, (iterRanges * i));
if (i == (gBatches - 1)) {
var iterEnd = dateDelta(gEndDate);
} else {
var iterEnd = dateDelta(gStartDate, (iterRanges * (i + 1)) + 1);
}
batch.push({"method": "GET", "relative_url": request.configParams.pageID + "/insights/page_fans,page_impressions,page_post_engagements?since=" + iterStart + "&until=" + iterEnd})
}
//console.log(batch);
}
// Fetch the data with UrlFetchApp
var url = "https://graph.facebook.com?include_headers=false&batch=" + encodeURIComponent(JSON.stringify(batch))
The windows.pageload event handler submits the page on page load. My intention is for this to wire the event handler to the submit event when the form submit button is clicked. What did I do wrong? Thanks!
function submit_data () {
var parent1Phone = $("parent1Phone").value;
var areaCode = parent1Phone.substring(0,3);
var prefix = parent1Phone.substring(4,7);
var suffix = parent1Phone.substring(8,12);
var firstName = $("firstName").value;
var lastName = $("lastName").value;
var sportID = $("sportID").value;
var entryFrom = $("entryFrom").value;
var linkSource = codeSource;
var primaryEmail = $("primaryEmail").value;
var graduationYear = $("graduationYear").value;
var postalCode = $("postalCode").value;
var parent1FirstName = $("parent1FirstName").value;
var parent1LastName = $("parent1LastName").value;
var parent1Relationship = $("parent1Relationship").value;
var parent1Phone1= areaCode;
var parent1Phone2 = prefix;
var parent1Phone3 = suffix;
var parent1PhoneType = $("parent1PhoneType").value; //No validation required. No non-choice allowed.
var parent1Email = $("parent1Email").value;
var parent1EmailConfirm = $("parent1Email").value;
var successDestination = success;
var errorDestination = failure;
var url = "http://recruit- match.ncsasports.org/fasttrack/saefentry/submitFullFormRemote.go?";
window.location.href = url + "firstName="+ firstName + "&lastName=" + "&lastName=" + lastName +"&sportID=" + sportID + "&entryFrom=" + entryFrom + "&linkSource=" + linkSource + "&primaryEmail=" + primaryEmail +"&graduationYear=" + graduationYear + "&postalCode=" + postalCode + "&parent1FirstName=" + parent1FirstName + "&parent1LastName=" + parent1LastName + "&parent1Relationship=" + parent1Relationship + "&parent1Phone1=" + parent1Phone1 + "&parent1Phone2=" + parent1Phone2 + "&parent1Phone3=" + parent1Phone3 + "&parent1PhoneType=" + parent1PhoneType + "&parent1Email=" + parent1Email + "&parent1EmailConfirm=" + parent1Email + "&successDestination=" + successDestination + "&errorDestination=" + errorDestination;
}
function prepareEventHandlers() {
$("frmNcsa").onclick = submit_data();
}
window.onload = function() {
prepareEventHandlers();
}
You are calling submit_data in the assignment $("frmNcsa").onclick = submit_data();, it should be $("#frmNcsa").click(submit_data);
assuming all the strings passed to the jQuery function are the ids of elements, they shold be prepended with #.