Post to Instagram via API - google-apps-script

I've been trying to setup a small app using Google Apps Script that just posts to Instagram. I got the bulk of the code I'm using from this post.
function postToIG() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('IG Post');
var image = sheet.getRange(2,1).getValue();
var text = sheet.getRange(2,2).getValue();
var access_token = "TOKEN";
var formData = {
'image_url': image,
'caption': text,
'access_token': access_token
};
var options = {
'method' : 'post',
'payload' : formData,
"muteHttpExceptions": true
};
const container = 'https://graph.facebook.com/v15.0/ID/media';
const response = UrlFetchApp.fetch(container, options);
console.log(response.getContentText());
const creation = response.getContentText();
var data = JSON.parse(creation);
var creationId = data.id
var formDataPublish = {
'creation_id': creationId,
'access_token': access_token
};
var optionsPublish = {
'method' : 'post',
'payload' : formDataPublish,
"muteHttpExceptions": true
};
const sendinstagram = 'https://graph.facebook.com/v15.0/ID/media_publish';
var response2 = UrlFetchApp.fetch(sendinstagram, optionsPublish);
console.log(response2.getContentText());
}
I just keep getting the same error message for both requests in the code
{"error":{"message":"Unsupported post request. Object with ID
'ID' does not exist, cannot be loaded due to missing
permissions, or does not support this operation. Please read the Graph
API documentation at
https://developers.facebook.com/docs/graph-api","type":"GraphMethodException","code":100,"error_subcode":33,"fbtrace_id":"AtTVaV-ODec9Iuagp4efYuX"}}
I'm not sure how exactly to get the Instagram user ID that would go in for the ID value in the code. I've tried several different methods and gotten different IDs and I get the same error for all of them.
My account is a business account and linked to a Facebook page. Furthermore, I got the access token being used from the Graph API Explorer on the Facebook developers site. I added all of the permissions listed for the media and media_publish endpoints. Additionally, the Instagram Graph API product is added to the app I've created for this on the Facebook developers page.
EDIT:
Got what I think is the correct ID using the Graph API Explorer and accessing the endpoint "https://graph.facebook.com/v15.0/me/accounts" however even using this new ID value I am still getting the same error message as shown above
UPDATE
I was able to figure this out. I did have the correct ID value however it turns out there is also an Instagram Business Account ID that can be retrieved using the Graph API Explorer. Once I started using this ID, it ran just fine

Related

Google Sheets activity sending to GA4 with App Script

I have been trying to change my script that used to send to the old UA Google Analytics using the IMAGE() but with the new GA4 you have to send a POST. I tried to use the onOpen(e) with some of the code below but nothing seems to work even though I am not getting any errors. Does anyone know if it is possible to make a call [POST] with this information:
function onOpen(e) {
// Make a POST request with a JSON payload.
var data = {
"client_id": Utilities.getUuid(),
"user_id": "webuser",
"events": ["name", "cve_database"]
};
var options = {
'method' : 'post',
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data)
};
var response = UrlFetchApp.fetch('https://www.google-analytics.com/mp/collect?api_secret=<ID-Here>&measurement_id=<GA4 Acc>', options);
Logger.log(response)
}
I tried to get it to update the Google Analytics information so that I can keep track of the users who view the page.

OAuth2 access token coming back as Null in Google App Script

Apologies if this is a silly question, I am very new to programming in general and I have never worked with OAuth before.
I am currently trying to build a Google App Script which interacts with an external service and authenticates using OAuth2.
I am having a lot of trouble with OAuth2... for starters, I'm not sure I am using the correct library for this. I am going off the one recommended by Google for ads script - https://developers.google.com/google-ads/scripts/docs/examples/oauth20-library
I know there is another popular one available in GitHub https://github.com/googleworkspace/apps-script-oauth2
I was not able to use it because everything comes out as 'is not a function', no matter how I add the library, manually or through the built-in feature.
I started building the API call, based on the first library and I had some partial success, I started getting back a 500 error message and I realized my accessToken is null.
function SHICall(){
var tokenUrl = "X/token";
const scriptProperties = PropertiesService.getScriptProperties();
var clientId = scriptProperties.getProperty('CLIENT_ID');
var clientSecret = scriptProperties.getProperty('SECRET');
var opt_scope = "CustomerAPI.Public";
// Access token is obtained and cached.
const authUrlFetch = OAuth2.withClientCredentials(tokenUrl, clientId, clientSecret, opt_scope);
const url = "X";
Logger.log(authUrlFetch);
var options = {
headers: { 'Content-Type': "application/json", 'Accept': "application/json"},
muteHttpExceptions: true,
method: "GET",
contentType: "application/json",
validateHttpsCertificates: false,
};
// Use access token in each request
const response = authUrlFetch.fetch(url, options);
// ... use response
Logger.log(response);
}
Any clue why the token is coming back as null? I based my API Call on google's documentation again https://developers.google.com/google-ads/scripts/docs/features/third-party-apis#oauth_2

Google Sheets AddOn - AppScript & BigQuery Integration via Service Account

I have a Google Sheets workspace addon and recently did some work to integrate BigQuery. Essentially BigQuery hold a record of books each of which has an author, title etc and my Addon allows people to pull the books that they have read into their sheet. The first column in the sheet allows people to choose from all the authors in the DB, based on that selection the second column is populated with data from BigQuery with all books by that author etc etc. There is no need for my AddOn to access a user's BigQuery, they only access 'my' BgQuery.
This all works fine, but when I submitted my addon for approval I was told
Unfortunately, we cannot approve your request for the use of the following scopes
https://www.googleapis.com/auth/bigquery
We recommend using service accounts for this type of information exchange.
This seems fair and reading up on Service Accounts it seems a much better fit for my use case. I've gone through the process of creating the service accounts and downloaded my security details json file, however I just can't figure out how to actually query BigQuery from AppScript.
In my non-service account method I have the BigQuery Library installed in AppScript and basically run
var queryResults = BigQuery.Jobs.query(request, projectId);
I've been trying to work from an example at https://developers.google.com/datastudio/solution/blocks/using-service-accounts
function getOauthService() {
var serviceAccountKey = getServiceAccountCreds('SERVICE_ACCOUNT_KEY');// from private_key not private_key_id of JSON file
var serviceAccountEmail = getServiceAccountCreds('SERVICE_ACCOUNT_EMAIL');
return OAuth2.createService('RowLevelSecurity')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(serviceAccountKey)
.setIssuer(serviceAccountEmail)
.setPropertyStore(scriptProperties)
.setCache(CacheService.getScriptCache())
.setScope(['https://www.googleapis.com/auth/bigquery.readonly']);
}
function getData(request) {
var accessToken = getOauthService().getAccessToken();
var billingProjectId = getServiceAccountCreds('BILLING_PROJECT_ID');
// var email = Session.getEffectiveUser().getEmail();
// return cc
// .newBigQueryConfig()
// .setAccessToken(accessToken)
// .setBillingProjectId(billingProjectId)
// .setUseStandardSql(true)
// .setQuery(BASE_SQL)
// .addQueryParameter('email', bqTypes.STRING, email)
// .build();
}
I've commented out the code in the above which relates to
var cc = DataStudioApp.createCommunityConnector();
in the above tutorial since I'm not using DataStudio but I'm really not sure what to replace it with so I can query BigQuery with AppScript via a Service Account. Can anyone offer any advice?
Based on the advice from #TheAddonDepot in the comments above my revised code now looks like:
function getBigQueryService() {
return (
OAuth2.createService('BigQuery')
// Set the endpoint URL.
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the private key and issuer.
.setPrivateKey(JSON_CREDS.private_key) // from the json file downloaded when you create service account
.setIssuer(JSON_CREDS.client_email). // from the json file downloaded when you create service account
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Caching
.setCache(CacheService.getUserCache())
// Locking
.setLock(LockService.getUserLock())
// Set the scopes.
.setScope(['https://www.googleapis.com/auth/bigquery.readonly'])
// .setScope('https://www.googleapis.com/auth/bigquery')
)
}
function queryData(){
const bigQueryService = getBigQueryService()
if (!bigQueryService.hasAccess()) {
Logger.log("BQ ERROR IS "+ bigQueryService.getLastError())
}
//const projectId = bigqueryCredentials.project_id
var projectId = "<yourprojectid>"
let url = 'https://bigquery.googleapis.com/bigquery/v2/projects/<yourprojectid>/queries'; //projectID is taken from the security json file for the service account, although it doesn't seem to matter if you use the project code
const headers = {
Authorization: `Bearer ${bigQueryService.getAccessToken()}`,
'Content-Type': 'application/json',
}
var data = {query:"<your query>",useLegacySql:false};
const options = {
method: 'post',
headers,
//contentType: 'application/json',
payload: JSON.stringify(data),
muteHttpExceptions: true // on for debugging
}
try {
const response = UrlFetchApp.fetch(url, options)
const result = JSON.parse(response.getContentText())
Logger.log("here is result "+ JSON.stringify(result))
} catch (err) {
console.error(err)
}
}

Web scraping with Google Apps Script

I'm trying to pull data from the following sample web page using Google Apps Script:
url = http://www.premierleague.com/players/2064/Wayne-Rooney/stats?se=54
using, UrlFetchApp.Fetch(url)
The problem is when I use UrlFetchApp.Fetch(url) to do that, I don't get the page information defined by the 'se' parameter in the url. Instead, I get the information on the following URL because it looks like the 'se=54' page is asynchronously loaded:
http://www.premierleague.com/players/2064/Wayne-Rooney/stats
Is there any way to pass the parameter 'se' some other way? I was looking at the function and it allows the specification of 'options', as they are referred to, but the documentation on the topic is very limited.
Any help would be most appreciated. Many thanks
Tommy
Go to that website in your browser and open the developer tools (F12 or ctr-shift-i). Click on the network tab and reload the page with F5.
A list of requests will appear. At the bottom of the list you should see the asynchronous requests made to fetch the information. Those requests get the data in json form from footballapi.pulselive.com.
You can do the same thing in apps script. But you have to send a correct "origin" header line or your request gets rejected.
Here is an example.
function fetchData() {
var url = "http://footballapi.pulselive.com/football/stats/player/2064?comps=1";
var options = {
"headers": {
"Origin": "http://www.premierleague.com"
}
}
var json = JSON.parse(UrlFetchApp.fetch(url, options).getContentText());
for(var i = 0; i < json.stats.length; i++) {
if(json.stats[i].name === "goals") Logger.log(json.stats[i]);
}
}
Please try the following solution:
var options =
{
"method" : "GET",
"followRedirects" : true,
"muteHttpExceptions": true
};
var result = UrlFetchApp.fetch(url, options);

Trello API Moving Card to another List using Google Apps Script

I trying to use Google Apps Script to move a filtered set of cards from one list to another in Trello using their API and this method:
https://trello.com/docs/api/card/index.html#put-1-cards-card-id-or-shortlink-idlist
But I keep getting the following error message:
Request failed for returned code 404. Truncated server response:
Cannot PUT /1/cards/54aa79112b9cdbb78fe43abf/5419475e4948228f2be857bd
My code looks like this:
var url = 'https://api.trello.com/1/cards/'+*ID OF CARD TO BE MOVED*+'/'+*ID OF LIST TO MOVE CARD TO*
var options = {
"method": "PUT",
"oAuthServiceName": "trello",
"oAuthUseToken": "always"
};
UrlFetchApp.fetch(url, options);
Any idea on what I am doing wrong? Do I need to add a payload to the options (so far have only done get and pull requests and it has all worked via the url rather than a payload) if so what would that be the documentation isn't that clear.
Otherwise any other thoughts on what the problem might be
The route you're trying to use is described as PUT /1/cards/[card id or shortlink]/idList - in this specific case, it looks like you want PUT /1/cards/54aa79112b9cdbb78fe43abf/idList. Then, the payload is described in the Arguments section - there should be a single argument named value, and its value is the id of the list.
I'm new in app scritps but i have this solution for your problem
function UpdateTrelloCard() {
var IDcard = "..."
var idafterlist = "...";
var options = {
'method' : 'put',
};
var response = UrlFetchApp.fetch(url + "cards/" + IDcard + "?idList=" + idafterlist + "&key=" + api_key + "&token=" + api_token, options);
var lists = JSON.parse((response.getContentText()));
Logger.log(idtrello)
Logger.log(lists)
}