According to this answer, Gmail does not expose an API for sending and receiving payments. Therefore, I am trying to use Stripe to accomplish that.
Code.js
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
(async () => {
const product = await stripe.products.create({
name: 'My SaaS Platform',
type: 'service',
});
})();
However, GAS does not directly support async and require at this time. Is there any possible workaround so I can use Stripe to send and receive payments in my GAS app?
If that's not possible, what direction should I go from here?
How about this answer? Please think of this as just one of several answers.
Issue and workaround:
Unfortunately, the module of Node.js cannot be directly used for Google Apps Script. So it is required to prepare the script for Google Apps Script. Fortunately, at the official document of the link in your question, there are several samples. Using this, how about converting to the script of Google Apps Script?
Sample script:
When your script in your question is converted to Google Apps Script, it becomes as follows.
From:
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');
(async () => {
const product = await stripe.products.create({
name: 'My SaaS Platform',
type: 'service',
});
})();
To
function myFunction() {
var url = "https://api.stripe.com/v1/products";
var params = {
method: "post",
headers: {Authorization: "Basic " + Utilities.base64Encode("sk_test_4eC39HqLyjWDarjtT1zdp7dc:")},
payload: {name: "My SaaS Platform", type: "service"}
};
var res = UrlFetchApp.fetch(url, params);
Logger.log(res.getContentText())
}
In this case, both requests of Node.js and Google Apps Script are the same.
Note:
At the sample script of Node.js, sk_test_4eC39HqLyjWDarjtT1zdp7dc is used for the key. But in this case, because the basic authorization is used, please use sk_test_4eC39HqLyjWDarjtT1zdp7dc: by adding :.
References:
Billing Quickstart
Class UrlFetchApp
If I misunderstood your question and this was not the direction you want, I apologize.
Related
I've searched the documentation of Twilio Studio and I haven't found any information about sending Interactive Messages or receiving latitude and longitude from Location Messages. In case of the latter I have found unofficial mentions of location information not being supported in Twilio Studio.
Are interactive messages and location information currently supported in Twilio Studio? If not, are there plans of implementing support for them? Is there a current workaround, specially about obtaining the location information?
Many thanks.
What workarounds I've tried
In the case of the location info:
I've tried running calling a Twilio Function in Studio that receives a location and echoes the coordinates in a reply. The Function connected to the Whatsapp Sandbox by itself works, but when it's called inside the Twilio Flow doesn't.
I assume that the Function cannot access the event parameters when it's called from a Studio Flow.
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.MessagingResponse();
if (!event.Latitude || !event.Longitude) {
twiml.message("Send a location.");
callback(null, twiml);
} else {
const location = {
lat: event.Latitude,
lon: event.Longitude
};
twiml.message(
`${location.lat}, ${location.lon}`
);
callback(null, twiml);
}
};
(The code was originally taken from this tutorial.)
EDIT:
This is quite embarrassing, but I figured how to access the Latitude annd Longitude info.
Simply access the following Liquid variable
{{widgets.send_and_reply_1.inbound.Longitude}}
{{widgets.send_and_reply_1.inbound.Latitude}}
(Change the send_and_reply by the name of the correct node.)
You already answered your question above but for completion, I want to add my two cents too.
Yes, it is possible to send locations, formatted and interactive messages in WhatsApp via the Twilio platform. Here's a link to the respective docs page that contains all the features. Note that this is the docs page of the "WhatsApp Business API with Twilio" and not Studio but the content still applied when Studio handles WhatsApp messaging flow.
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require('twilio')(accountSid, authToken);
client.messages
.create({
messagingServiceSid: 'MGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
body: 'This is one of the Twilio office locations',
persistentAction: ['geo:37.787890,-122.391664|375 Beale St'],
to: 'whatsapp:+15005550006'
})
.then(message => console.log(message.sid));
There's also this docs page about using buttons in WhatsApp, which mentions which message types are currently supported. The trick is that you create message templates with the buttons and then you'll use the normal message body in Studio to refer to the template.
So my app creates spreadsheets programmatically as our projects expand (a new spreadsheet for each project). Each spreadsheet has a container-bound script that has some javascript in it to give the spreadsheet some extra functionality. Now I need all the scripts attached to these spreadsheets to use the same GCP project. I know how to set the GCP project manually (from this article), but I need to be able to set the GCP project programmatically when the spreadsheets are created.
I figure this can be done using UrlFetchApp, but I can't figure out the url that the "Set Project" button uses to make this happen. I tried inspecting the html on that settings page, but it's like 16000 lines of code, and while I found the button, I can't figure out the url it posts to.
Can someone help me out here? I need either the formatting of the url post, or another method to set the GCP project of a script with Apps Script.
Here's my code that I'm planning to use:
function changeGCPproject() {
const scriptId = '1Q8Frqjb6vh5....';
const gcpProjectNumber = '596....';
const url = `https://script.google.com/home/projects/${scriptId}/whateverformat?projectNumber=${gcpProjectNumber}`; //this is the url formatting that I need
const token = ScriptApp.getOAuthToken();
const params = {
method: 'post',
headers: {
Authorization: 'Bearer ' + token,
},
muteHttpExceptions: true
};
UrlFetchApp.fetch(url, params);
}
Thanks!
I've started working with React and Node.js for the first time, on building an private Shopify App. The app's purpose is to listen to an add to cart button, when clicked it should create a custom product in the Shopify Backend with the Shopify Product API. I've worked plenty in basic JavaScript and have great experience in jQuery, to handle the more basics of this project. The tought part is binding the POST event to the add to cart click, creating the product and adding it to the cart.
I'm trying the following solution for creating the product in the backend. Is this the correct way of doing it, or is there a better solution for doing this?
How can i bind this Fetch function to an click event?
let new_product = {
product: {
title: Custom,
body_html: test,
vendor: Custom,
product_type: customproduct,
tags: Customproduct
}
};
fetch('/admin/api/2020-07/products.json', {
method: 'post',
body: JSON.stringify(new_product),
headers: {
'X-Shopify-Access-Token': process.env.SHOPIFY_API_SECRET_KEY,
'Accept': 'application/json'
},
})
I'm using Isomorphic Fetch in my project, which should work server and client side.
Any help and guidance would be appreciately recieved.
Thank you!
You have got several questions there. Before answering, it is important to clear few misconceptions that I assumed from your wording and sample code. There are 3 types of Shopify Apps.
Public
Custom
Private
So if you are building a Private app, then provided code will not work for creating Product because Private apps use Basic authentication while Public and Custom apps manage authentication with OAuth 2.0.
I'm using Isomorphic Fetch in my project, which should work server and
client side.
Even though it works on Server and Client ends, do not call Shopify API from Client side as this will expose your private app credentials.
To implement what you are trying to do, you need to modify React App as well as Backend code.
Add an event listener to Button
Send a POST request to Backend server
Create Product on Shopify via API
Add the product to cart using ID returned in previous step
Return the Cart URL in response
Sample code in React would look like
function Product() {
const addProduct = async () => {
const cart = await fetch("/your-end-point", {
method: "post",
body: JSON.stringify({
// add product params
}),
});
};
return <button onClick={addProduct}>Add Product</button>;
}
ReactDOM.render(<Product />, document.getElementById("root"));
Then inside your Node.js application, handle the Shopify API part. Instead of using fetch, I will recommend using Official Node.js module for Shopify.
Sample code will look like
const Shopify = require("shopify-api-node");
router.post("/your-end-point", async (req, res) => {
try {
const shopify = new Shopify({
shopName: "your-shop-name",
apiKey: "your-api-key",
password: "your-app-password",
});
const product = await shopify.product.create(req.body);
// use product ID from previous request
const checkout = await shopify.checkout.create({
/*checkout params */
});
res.status(200).send(checkout);
} catch (ex) {
console.log(ex);
}
});
I am trying to fetch git azure devops api to get information about repositories and branches in js.
In order to achieve that, I made a little application with the following code :
$(document).ready(function() {
var personalToken = btoa(':'+'<personnalAccessToken>');
fetch('https://dev.azure.com/<company>/<project>/_apis/git/repositories?api-version=5.1', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
'Authorization': 'Basic '+ personalToken
}
}).then(function(response) {
return response.json();
}).then(function(repositories) {
console.log("There are "+repositories.count+" repositories");
}).catch(function(error) {
console.log('Fetch error: ' + error.message);
});
This code is working great but as you can see there is my personnalAccessToken writen directly inside the code... which is really bad...
When I am using git in command line, I don't have to specify any credential information because I use git credential manager for windows. Which means my personnalAccessToken is already stored, cached and automatically used everytime I use a git command, like clone, etc.
So, I would like my js code to use the same thing, I would like it to use my stored credentials automatically to fetch the api without being required to set my personnalAccessToken in code.
I have already searched for hours but can't find out if it is possible.
I have already searched for hours but can't find out if it is
possible.
Sorry but as I know it's impossible. The way you're calling the Rest API is similar to use Invoke-RestMethod to call rest api in Powershell.
In both these two scenarios, the process will try to fetch PAT for authentication in current session/context and it won't even try to search the cache in Git Credential Manager.
You should distinguish the difference between accessing Azure Devops service via Rest API and by Code:
Rest API:
POST https://dev.azure.com/{organization}/{project}/{team}/_apis/wit/wiql?api-version=5.1
Request Body:
{
"query": "Select [System.Id], [System.Title], [System.State] From WorkItems Where [System.WorkItemType] = 'Task' AND [State] <> 'Closed' AND [State] <> 'Removed' order by [Microsoft.VSTS.Common.Priority] asc, [System.CreatedDate] desc"
}
Corresponding Code in C#:
VssConnection connection = new VssConnection(new Uri(azureDevOpsOrganizationUrl), new VssClientCredentials());
//create http client and query for resutls
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
Wiql query = new Wiql() { Query = "SELECT [Id], [Title], [State] FROM workitems WHERE [Work Item Type] = 'Bug' AND [Assigned To] = #Me" };
WorkItemQueryResult queryResults = witClient.QueryByWiqlAsync(query).Result;
Maybe you can consider using a limited PAT, limit its scope to Code only:
I know there exists other Authentication mechanism
:
For Interactive JavaScript project: ADALJS and Microsoft-supported Client Libraries.
You can give it a try but I'm not sure if it works for you since you're not using real Code way to access the Azure Devops Service... Hope it makes some help :)
If you have the script set up in an Azure Runbook you can set it as an encrypted variable there and have it pull it from there before running rather than having it directly written into the code.
$encryptedPatVarName = "ADO_PAT"
$adoPat = Get-AutomationVariable -Name $encryptedPatVarName
$adoPatToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($adoPat)"))
$adoHeader = #{authorization = "Basic $adoPatToken"}
The above is the Powershell version of it. I have seen some people do it with other
I'm trying to use the Facebook Graph API to get the latest status from a public page, let's say http://www.facebook.com/microsoft
According to http://developers.facebook.com/tools/explorer/?method=GET&path=microsoft%2Fstatuses - I need an access token. As the Microsoft page is 'public', is this definitely the case? Is there no way for me to access these public status' without an access token?
If this is the case, how is the correct method of creating an access token for my website? I have an App ID, however all of the examples at http://developers.facebook.com/docs/authentication/ describe handling user login. I simply want to get the latest status update on the Microsoft page and display it on my site.
This is by design. Once it was possible to fetch the latest status from a public page without access token. That was changed in order to block unidentified anonymous access to the API. You can get an access token for the application (if you don't have a Facebook application set for your website - you should create it) with the following call using graph API:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&
grant_type=client_credentials
This is called App Access Token. Then you proceed with the actual API call using the app access token from above.
hope this helps
You can use AppID and Secret key to get the public posts/feed of any page. This way you don't need to get the access-token. Call it like below.
https://graph.facebook.com/PAGE-ID/feed?access_token=APP-ID|APP-SECRET
And to get posts.
https://graph.facebook.com/PAGE-ID/posts?access_token=APP-ID|APP-SECRET
It's no more possible to use Facebook Graph API without access token for reading public page statuses, what is called Page Public Content Access in Facebook API permissions. Access token even is not enough. You have to use appsecret_proof along with the access token in order to validate that you are the legitimate user. https://developers.facebook.com/blog/post/v2/2018/12/10/verification-for-individual-developers/.
If you are individual developer, you have access to three pages of the data (limited), unless you own a business app.
You can get the posts by simply requesting the site that your browser would request and then extracting the posts from the HTML.
In NodeJS you can do it like this:
// npm i request cheerio request-promise-native
const rp = require('request-promise-native'); // requires installation of `request`
const cheerio = require('cheerio');
function GetFbPosts(pageUrl) {
const requestOptions = {
url: pageUrl,
headers: {
'User-Agent': 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0'
}
};
return rp.get(requestOptions).then( postsHtml => {
const $ = cheerio.load(postsHtml);
const timeLinePostEls = $('.userContent').map((i,el)=>$(el)).get();
const posts = timeLinePostEls.map(post=>{
return {
message: post.html(),
created_at: post.parents('.userContentWrapper').find('.timestampContent').html()
}
});
return posts;
});
}
GetFbPosts('https://www.facebook.com/pg/officialstackoverflow/posts/').then(posts=>{
// Log all posts
for (const post of posts) {
console.log(post.created_at, post.message);
}
});
For more information and an example of how to retrieve more than 20 posts see: https://stackoverflow.com/a/54267937/2879085
I had a similar use case for some weeks and I used this API:
https://rapidapi.com/axesso/api/axesso-facebook-data-service/
I could fetch all posts and comments in some minutes, worked quite well for me.