using the googleapis library in dart to update a calendar and display it on a webpage - calendar

I am new to dart and I have been trying to figure out how to use the googleapis library to update a calendars events, then display the calendar/events on a webpage.
So far I have this code that I was hoping would just change the #text id's text to a list of events from the selected calendars ID:
import 'dart:html';
import 'package:googleapis/calendar/v3.dart';
import 'package:googleapis_auth/auth_io.dart';
final _credentials = new ServiceAccountCredentials.fromJson(r'''
{
"private_key_id": "myprivatekeyid",
"private_key": "myprivatekey",
"client_email": "myclientemail",
"client_id": "myclientid",
"type": "service_account"
}
''');
const _SCOPES = const [CalendarApi.CalendarScope];
void main() {
clientViaServiceAccount(_credentials, _SCOPES).then((http_client) {
var calendar = new CalendarApi(http_client);
String adminPanelCalendarId = 'mycalendarID';
var event = calendar.events;
var events = event.list(adminPanelCalendarId);
events.then((showEvents) {
querySelector("#text2").text = showEvents.toString();
});
});
}
But nothing displays on the webpage. I think I am misunderstanding how to use client-side and server-side code in dart... Do I break up the file into multiple files? How would I go about updating a calendar and displaying it on a web page with dart?
I'm familiar with the browser package, but this is the first time I have written anything with server-side libraries(googleapis uses dart:io so I assume it's server-side? I cannot run the code in dartium).
If anybody could point me in the right direction, or provide an example as to how this could be accomplished, I would really appreciate it!

What you might be looking for is the hybrid flow. This produces two items
access credentials (for client side API access)
authorization code (for server side API access using the user credentials)
From the documentation:
Use case: A web application might want to get consent for accessing data on behalf of a user. The client part is a dynamic webapp which wants to open a popup which asks the user for consent. The webapp might want to use the credentials to make API calls, but the server may want to have offline access to user data as well.
The page Google+ Sign-In for server-side apps describes how this flow works.

Using the following code you can display the events of a calendar associated with the logged account. In this example i used createImplicitBrowserFlow ( see the documentation at https://pub.dartlang.org/packages/googleapis_auth ) with id and key from Google Cloud Console Project.
import 'dart:html';
import 'package:googleapis/calendar/v3.dart';
import 'package:googleapis_auth/auth_browser.dart' as auth;
var id = new auth.ClientId("<yourID>", "<yourKey>");
var scopes = [CalendarApi.CalendarScope];
void main() {
auth.createImplicitBrowserFlow(id, scopes).then((auth.BrowserOAuth2Flow flow) {
flow.clientViaUserConsent().then((auth.AuthClient client) {
var calendar = new CalendarApi(client);
String adminPanelCalendarId = 'primary';
var event = calendar.events;
var events = event.list(adminPanelCalendarId);
events.then((showEvents) {
showEvents.items.forEach((Event ev) { print(ev.summary); });
querySelector("#text2").text = showEvents.toString();
});
client.close();
flow.close();
});
});
}

Related

Using the paypalhere sdk in react web app

I'm building a web app for inventory management. I've got React on the frontend, and Nodejs+mongodb on the backend. Our company vends at local events and most of our sales are paid with cards. To process card payments we use the Paypal Here app on our phones which connects to a card reader and we manually type in the payment amount. Since we have over 200 different products (custom art), we decided to build this application so that we can quickly search for the product(s) being purchased, add them to the "cart" where the total price plus tax will be automatically calculated, and then a total of 3 payment option buttons will be present, one for cash, one for venmo, and one for card. At first, I figured the card selection button could link externally to the Paypal Here app and the payment amount would be automatically filled in when redirected, but then I realized I could actually integrate a Paypalhere sdk in the application, which sounded better than a redirect. There's three different sdks, one for ios, one for android, and one for the web, and the one for the web is what I need. I looked for an npm package, no luck, then I tried manually inserting the script and src into the document via react helment, no luck, on componentDidMount, no luck. I'm not used to not having an npm package to use, so my question today is how can I integrate this sdk into my React app?
Heres a link to the web integration documentation: https://developer.paypal.com/docs/integration/paypal-here/sdk-dev/web/#integration
Heres an the code I used to manually insert the script onComponentDidMount, I don't know if it worked, but even if it did, I don't know how to access it...
useEffect(() => {
const script = document.createElement("script");
script.src = "https://www.paypalobjects.com/pph/websdk/js/pphwebsdk-1.1.14.min.js";
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
};
}, []);
Don't remove the script after adding it.
You can set a callback function to have your code that uses PPH run after the script loads. Here's an example with a callback function, it's for regular PayPal buttons rather than PPH, but you can adapt it to your needs.
function loadAsync(url, callback) {
var s = document.createElement('script');
s.setAttribute('src', url); s.onload = callback;
document.head.insertBefore(s, document.head.firstElementChild);
}
loadAsync('https://www.paypal.com/sdk/js?client-id=sb&currency=USD', function() {
paypal.Buttons({
// Set up the transaction
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01'
}
}]
});
},
// Finalize the transaction
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
// Show a success message to the buyer
alert('Transaction completed by ' + details.payer.name.given_name);
});
}
}).render('body');
});
Alternatively, you can just load the SDK statically from in the index <head> of your application, and it'll always be there ready for use.

Google App Script / Gmail add-on : How to display a window with text and buttons over Gmail?

I made a Google App script to answer automatically to my emails (a kind of clever email robot assistant). Nevertheless, I would like to check each answer made by the robot before sending.
So I would like to have a window over Gmail showing the user email and the robot answer, and two buttons "send" "skip". In this way, I could check the answer prepared by the robot and either send it or skip it (or potentially edit it).
How to display a window with text, editText and buttons over GMail from Google App Script ?
Thanks !
Regards.
You have to check Gmail Add-on : https://developers.google.com/gsuite/add-ons/gmail
For a first start you can check the codelab from Google, it will give you the code to set a first add-on in 5 minutes then you can adapt it to your needs : https://codelabs.developers.google.com/codelabs/apps-script-intro/
Stéphane
An easy solution would be to have the robot save the e-mail as 'draft'. That way, you can easily check the emails before manually sending them.
If you are still interested in creating the gmail add-on (which could display the original email, response, and buttons for sending or editing), you may be interested in building card-based interfaces. These will appear to the right of your Gmail web client, and will look like the following:
The code used to display such interface (with two buttons, one that automatically sends the email and another one that opens the editor on it) is the following:
function buildAddOn(e) {
// Activate temporary Gmail add-on scopes.
var accessToken = e.messageMetadata.accessToken;
GmailApp.setCurrentMessageAccessToken(accessToken);
return buildDraftCard(getNextDraft());
}
function buildDraftCard(draft) {
if (!draft) {
var header = CardService.newCardHeader().setTitle('Nothing to see here');
return CardService.newCardBuilder().setHeader(header).build();
} else {
var header = CardService.newCardHeader()
.setTitle(draft.getMessage().getSubject());
var section = CardService.newCardSection();
var messageViewer = CardService.newTextParagraph()
.setText(draft.getMessage().getBody());
var sendButton = CardService.newTextButton()
.setText('Send')
.setOnClickAction(CardService.newAction()
.setFunctionName('sendMessage')
.setParameters({'draftId': draft.getId()})
);
var editButton = CardService.newTextButton()
.setText('Edit')
.setOnClickAction(CardService.newAction()
.setFunctionName('editMessage')
.setParameters({'draftId': draft.getId()})
);
var buttonSet = CardService.newButtonSet()
.addButton(sendButton)
.addButton(editButton);
section.addWidget(messageViewer);
section.addWidget(buttonSet)
return CardService.newCardBuilder()
.setHeader(header)
.addSection(section)
.build();
}
}
function sendMessage(e) {
GmailApp.getDraft(e.parameters.draftId).send();
return CardService.newActionResponseBuilder().setNavigation(
CardService.newNavigation()
.popToRoot()
.updateCard(buildDraftCard(getNextDraft()))
).build();
}
function editMessage(e) {
var messageId = GmailApp.getDraft(e.parameters.draftId).getMessageId();
var link = "https://mail.google.com/mail/#all/" + messageId;
return CardService.newActionResponseBuilder().setOpenLink(
CardService.newOpenLink()
.setUrl(link)
.setOnClose(CardService.OnClose.RELOAD_ADD_ON)
).build();
}
function getNextDraft() {
return GmailApp.getDrafts().pop()
}
And the appsscript.json configuration is the following:
{
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://mail.google.com/"
],
"gmail": {
"name": "Gmail Add-on Draft Autoresponse UI",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/label_googblue_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "buildAddOn"
}],
"openLinkUrlPrefixes": [
"https://mail.google.com/"
],
"primaryColor": "#4285F4",
"secondaryColor": "#4285F4"
}
}
Bear in mind however, that these interfaces at the moment still have some limitations. They can only be displayed whilst having a message open, and the HTML formatting of the email may look a bit off. You can find more information on how to test & run the code above by following this link.

Asynchronously Respond in new Hangout Chat using rest API, without using google app engine

How can I post message as a bot(async) in new hangouts chat without using the Google App Engine. I have gone through the examples, but all of them use App Engine for authentication, but i need to authenticate it without using the same.
Here is a code sample that connects to a chat using an http request and a webhook from Google Hangout Chat with a Python script. Webhooks are the only alternative to using a service account. More info here: https://developers.google.com/hangouts/chat/how-tos/webhooks
`from httplib2 import Http
from json import dumps
#
# Hangouts Chat incoming webhook quickstart
#
def main():
url = '<webhook url here>'
bot_message = {
'text' : 'text go here'}
message_headers = { 'Content-Type': 'application/json; charset=UTF-8'}
http_obj = Http()
response = http_obj.request(
uri=url,
method='POST',
headers=message_headers,
body=dumps(bot_message),
)
print(response)
if __name__ == '__main__':
main()
`
If your bot implementation is with google app script try to do it with google service account and as indicated here an example of async message
// Example bot for Hangouts Chat that demonstrates bot-initiated messages
// by spamming the user every minute.
//
// This bot makes use of the Apps Script OAuth2 library at:
// https://github.com/googlesamples/apps-script-oauth2
//
// Follow the instructions there to add the library to your script.
// When added to a space, we store the space's ID in ScriptProperties.
function onAddToSpace(e) {
PropertiesService.getScriptProperties()
.setProperty(e.space.name, '');
return {
'text': 'Hi! I\'ll post a message here every minute. ' +
'Please remove me after testing or I\'ll keep spamming you!'
};
}
// When removed from a space, we remove the space's ID from ScriptProperties.
function onRemoveFromSpace(e) {
PropertiesService.getScriptProperties()
.deleteProperty(e.space.name);
}
// Add a trigger that invokes this function every minute via the
// "Edit > Current Project's Triggers" menu. When it runs, it will
// post in each space the bot was added to.
function onTrigger() {
var spaceIds = PropertiesService.getScriptProperties()
.getKeys();
var message = { 'text': 'Hi! It\'s now ' + (new Date()) };
for (var i = 0; i < spaceIds.length; ++i) {
postMessage(spaceIds[i], message);
}
}
var SCOPE = 'https://www.googleapis.com/auth/chat.bot';
// The values below are copied from the JSON file downloaded upon
// service account creation.
var SERVICE_ACCOUNT_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n';
var SERVICE_ACCOUNT_EMAIL = 'service-account#project-id.iam.gserviceaccount.com';
// Posts a message into the given space ID via the API, using
// service account authentication.
function postMessage(spaceId, message) {
var service = OAuth2.createService('chat')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(SERVICE_ACCOUNT_PRIVATE_KEY)
.setClientId(SERVICE_ACCOUNT_EMAIL)
.setPropertyStore(PropertiesService.getUserProperties())
.setScope(SCOPE);
if (!service.hasAccess()) {
Logger.log('Authentication error: %s', service.getLastError());
return;
}
var url = 'https://chat.googleapis.com/v1/' + spaceId + '/messages';
UrlFetchApp.fetch(url, {
method: 'post',
headers: { 'Authorization': 'Bearer ' + service.getAccessToken() },
contentType: 'application/json',
payload: JSON.stringify(message),
});
}
You need to perform some below steps.
Create a service-account in console.developers.google.com and download the private key in JSON format
Use below modules if you code in python.
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.discovery import build, build_from_document
from httplib2 import Http
Below snippet will post the message to user via chat.google.
scopes = ['https://www.googleapis.com/auth/chat.bot']
credentials = ServiceAccountCredentials.from_json_keyfile_name('/path/to/json',
scopes)
http = Http()
credentials.authorize(http)
chat = build('chat', 'v1', http=http)
resp = chat.spaces().messages().create(
parent=space,
body={'text': 'HELLO WORLD'}).execute()
You would require a space name where you can post the code. You will get the same from hangout chat response.
It’s possible to do so using JavaScript, python, (possibly more). You can check out examples here: https://github.com/gsuitedevs/hangouts-chat-samples/tree/master/node/basic-cloud-functions-bot
If you’re using cards and JavaScript I would encourage you to checkout my library here: https://github.com/BaReinhard/hangouts-card-helper
I’m also in the process of creating another example for JavaScript that is more async focused that should provide and example that’s a bit easier to reason about the code. Will link when the PR is pushed.
Edit:
I realize that you mentioned REST api. The above answer is more useful for a specific bot that can be accessed #mentions. However, if you can provide us with a bit more information I can better fix my answer to answer your question.

How to make initial authenticated request with token from local storage?

I'm using vanilla flux with some utils for communicating with my APIs.
On initial page load I'd like to read some token from local storage and then make a request to my API to get my data.
I've got a LocalStorageUtils.js library for interacting with window.localStorage. My container component handles all login/logout actions and reads the current user on page load.
App.js
componentWillMount() {
LocalStorageUtils.get('user');
}
LocalStorageUtils reads the value and brings it into Flux via ServerAction similar to the flux chat example.
get(key) {
var value = window.localStorage.getItem(key);
if (value) {
ServerActionCreators.receiveFromLocalStorage(key, value);
}
}
That puts the user into my UserStore and into my views where I can show the username and some logout link, etc.
I also have ApiUtils.js for requesting data from the server. So the question is: Where do I tell my ApiUtils that I have a logged-in user at initial page load?
I could call some method inside ApiUtils from my LocalStorageUtils but that does not feel right.
Or do I have to make another round trip whenever I get a change event inside my container component?
You should pass the user as data to your ApiUtils class and removing the need from being concerned about how your ApiUtils is used.
var ApiUtils = function () {
this.get = function (endpoint, data) {
return theWayYouSendAjaxRequests.get(endpoint).setData(data);
};
};
// Wherever your ApiUtils is used.
var api = new ApiUtils();
api.get('/me', {user: userFromStore});
I found a solution that works and feels right.
As getting data from local storage is synchronous there is no need to pipe it through Flux via ServerActionCreators. Simply use LocalStorageUtils to get the current user and call the login method with that user. The login Action is the same you would use when a user initially logs in. login triggers getting new data from server. The new data is saved in my DataStore and the user is saved to my UserStore.
Thanks for all hints at Twitter and at https://reactiflux.slack.com/.

How to store user session in secha touch 2

Im using Sencha Touch 2 where i have a login form asking for username and password
now i want to store user details via Session/Cookie so the user can logout,
i browsed some links which i got
Sencha-touch : save login / password (save session, multi-tasks)
but im being an new to sench touch develpment
any help using code examples will be of very great input for me
Thanks in advance
You can use the HTML5 localStore object. For instance, when a user logs in and your server request is made, on the callback of a successful server request you can store any necessary data. Here is a snippet from one of my apps:
loginCallback: function(options, success, response) {
this.mainSplash.setMasked(false);
var responseOjbect = Ext.JSON.decode(response.responseText);
if (responseOjbect.success) {
this.clearLoginStorage(); //runs a function to clear some login storage values
if (rememberme) {
localStorage.setItem("rememberme", 1);
} else {
localStorage.setItem("rememberme", 0);
}
localStorage.setItem("userid", responseOjbect.userid);
localStorage.setItem("first_name", responseOjbect.first_name);
localStorage.setItem("last_name", responseOjbect.last_name);
localStorage.setItem("appsettingone", responseOjbect.appsettingone);
localStorage.setItem("appsettingtwo", responseOjbect.appsettingtwo);
localStorage.setItem("setdate", new Date());
if (!this.dashboard) {
Ext.create('myApp.view.Dashboard', {
//additional config
});
}
Ext.Viewport.setActiveItem(this.dashboard);
} else {
Ext.Msg.alert('Attention', responseOjbect.errorMessage, Ext.emptyFn);
}
}
Once you have set your localStorage items, they can be retrieved or removed like so:
localStorage.getItem("user_id"); //retrieve
localStorage.removeItem("userid"); //remove
So when you call your logout function, just don't remove any localStorage objects you want to keep. Then you can call localStorage.getItem("VALUE") to retrieve them upon next login
This is something which is managed by the server, not the client, so you want to look at , not at sencha itself.
On a guess that you are using php, for something really basic, take a look at:
http://www.html-form-guide.com/php-form/php-login-form.html

Resources