Posted by Wesley Chun (@wescpy), Developer Advocate, G Suite
We recently introduced Hangouts Chat to general availability. This next-generation messaging platform gives G Suite users a new place to communicate and to collaborate in teams. It features archive & search, tighter G Suite integration, and the ability to create separate, threaded chat rooms. The key new feature for developers is a bot framework and API. Whether it's to automate common tasks, query for information, or perform other heavy-lifting, bots can really transform the way we work.
In addition to plain text replies, Hangouts Chat can also display bot responses with richer user interfaces (UIs) called cards which can render header information, structured data, images, links, buttons, etc. Furthermore, users can interact with these components, potentially updating the displayed information. In this latest episode of the G Suite Dev Show, developers learn how to create a bot that features an updating interactive card.
As you can see in the video, the most important thing when bots receive a message is to determine the event type and take the appropriate action. For example, a bot will perform any desired "paperwork" when it is added to or removed from a room or direct message (DM), generically referred to as a "space" in the vernacular.
Receiving an ordinary message sent by users is the most likely scenario; most bots do "their thing" here in serving the request. The last event type occurs when a user clicks on an interactive card. Similar to receiving a standard message, a bot performs its requisite work, including possibly updating the card itself. Below is some pseudocode summarizing these four event types and represents what a bot would likely do depending on the event type:
function processEvent(req, rsp) { var event = req.body; // event type received var message; // JSON response message if (event.type == 'REMOVED_FROM_SPACE') { // no response as bot removed from room return; } else if (event.type == 'ADDED_TO_SPACE') { // bot added to room; send welcome message message = {text: 'Thanks for adding me!'}; } else if (event.type == 'MESSAGE') { // message received during normal operation message = responseForMsg(event.message.text); } else if (event.type == 'CARD_CLICKED') { // user-click on card UI var action = event.action; message = responseForClick( action.actionMethodName, action.parameters); } rsp.send(message); };
The bot pseudocode as well as the bot featured in the video respond synchronously. Bots performing more time-consuming operations or those issuing out-of-band notifications, can send messages to spaces in an asynchronous way. This includes messages such as job-completed notifications, alerts if a server goes down, and pings to the Sales team when a new lead is added to the CRM (Customer Relationship Management) system.
Hangouts Chat supports more than JavaScript or Python and Google Apps Script or Google App Engine. While using JavaScript running on Apps Script is one of the quickest and simplest ways to get a bot online within your organization, it can easily be ported to Node.js for a wider variety of hosting options. Similarly, App Engine allows for more scalability and supports additional languages (Java, PHP, Go, and more) beyond Python. The bot can also be ported to Flask for more hosting options. One key takeaway is the flexibility of the platform: developers can use any language, any stack, or any cloud to create and host their bot implementations. Bots only need to be able to accept HTTP POST requests coming from the Hangouts Chat service to function.
At Google I/O 2018 last week, the Hangouts Chat team leads and I delivered a longer, higher-level overview of the bot framework. This comprehensive tour of the framework includes numerous live demos of sample bots as well as in a variety of languages and platforms. Check out our ~40-minute session below.
To help you get started, check out the bot framework launch post. Also take a look at this post for a deeper dive into the Python App Engine version of the vote bot featured in the video. To learn more about developing bots for Hangouts Chat, review the concepts guides as well as the "how to" for creating bots. You can build bots for your organization, your customers, or for the world. We look forward to all the exciting bots you're going to build!
opendir()
writedir()
stat()
is_readable()
is_file()
PushTask:addTasks()
<?php // Include the Twilio PHP library require "Services/Twilio.php"; // Set your AccountSid and AuthToken from www.twilio.com/user/account $AccountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; $AuthToken = "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"; // Instantiate a new Twilio Rest Client $client = new Services_Twilio($AccountSid, $AuthToken); // Make an array of people we know, to send them a message: $people = array( "+14158675309" => "Curious George", "+14158675310" => "Boots", "+14158675311" => "Virgil", ); // Loop over all our friends: foreach ($people as $number => $name) { $sms = $client->account->sms_messages->create( "YYY-YYY-YYYY", // Change the 'From' number to a Twilio number you've purchased $number, // the number we are sending to - Any phone number "Hey $name, Monkey Party at 6PM. Bring Bananas!" // the sms body ); echo "Sent message to $name"; // Display a confirmation message }
application: examplehelloworld version: 1 runtime: php api_version: 1 threadsafe: true handlers: - url: .* script: main.php
application: examplehelloworld version: 1 runtime: php api_version: 1 threadsafe: true handlers: - url: /images static_dir: images - url: /send-sms script: send-sms.php - url: /make-call script: make-call.php - url: .* script: index.php
<?php require 'Services/Twilio.php'; include 'credentials.php'; $client = new Services_Twilio($AccountSid, $AuthToken); $call = $client->account->calls->create( '1512-555-1212', // From this number '17035551212', // Send to this number 'http://twimlets.com/echo?Twiml=%3CResponse%3E%3CSay%3EHello%20Monkey!%3C%2FSay%3E%3C%2FResponse%3E&' ); print $call->sid;
<?php require 'Services/Twilio.php'; include 'credentials.php'; $client = new Services_Twilio($AccountSid, $AuthToken); $call = $client->account->sms_messages->create( '1512-555-1212', // From this number '17035551212', // Send to this number 'Hello monkey!!' ); print $call->sid;
<?php $db = new PDO( 'mysql:unix_socket=/cloudsql/hello-php-gae:my-cloudsql-instance;dbname=demo_db;charset=utf8', 'demo_user', 'demo_password' ); foreach($db->query('SELECT * FROM users') as $row) { echo $row['username'].' '.$row['first_name']; //etc... }
<?php $handle = fopen('gs://hello-php-gae-files/prime_numbers.txt','w'); fwrite($handle, "2"); for($i = 3; $i <= 2000; $i = $i + 2) { $j = 2; while($i % $j != 0) { if($j > sqrt($i)) { fwrite($handle, ", ".$i); break; } $j++; } } fclose($handle);
<?php $primes = explode(",", file_get_contents('gs://hello-php-gae-files/prime_numbers.txt') ); if(isset($primes[100])) echo "The 100th prime number is ".$primes[100];
(Cross-posted with the App Engine and Enterprise Blogs)
Support is as important as product features when choosing a platform for your applications. And let’s face it, sometimes we all need a bit of help. No matter which Google Cloud Platform services you are using — App Engine, Compute Engine, Cloud Storage, Cloud SQL, BigQuery, etc. — or what time of day, you should be able to get the answers you need. While you can go to Stack Overflow or Google Groups, we realize some of you may need 24x7 coverage, phone support or direct access to a Technical Account Manager team.
To meet your support requirements, we’re introducing a comprehensive collection of support packages for services on Google Cloud Platform, so you can decide what level best fits your needs:
Sign up or click here to find out more information about the new Google Cloud Platform support options.
Brett McCully is the Manager of the Google Cloud Platform Support team and is currently based in Seattle.
Posted by Ashleigh Rentz, Editor Emerita
public static void invokeExample() { String s; MethodType mt; MethodHandle mh; MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(String.class, char.class, char.class); MethodHandle mh = lookup.findVirtual(String.class, "replace", mt); s = (String) mh.invokeExact("App Engine Java 6 runtime",'6','7'); System.out.println(s); }
public static void viewTable(Connection con, String query) throws SQLException { try ( Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(query) ) { while (rs.next()) { // process results // } } catch (SQLException e) { // con resource is auto-closed, no need to do anything here! // } }
Map<String, List<String>> myMap = new HashMap<>();
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
public class SuperHeroes { public List listSuperHeroes() { List list = new ArrayList(); list.add(new SuperHero ("Champion of the Obvious", "Brad Abrams")); list.add(new SuperHero ("Mr. Justice", "Chris Ramsdale")); return list; } }
@Api(name = "superheroes", version = "v1") public class SuperHeroesV1 { ... }
$ curl http://localhost:8888/_ah/api/superheroes/v1/superheroes { "items": [ { "knownAs" : "Champion of the Obvious", "realName" : "Brad Abrams" }, { "knownAs" : "Mr. Justice", "realName" : "Chris Ramsdale" }
Real result = superheroes.list().execute();
GTLQuerySuperHeroesV1 *query = [GTLQuerySuperHeroesV1 queryForSuperHeroesList]; [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, GTLSuperHeroes *object, NSError *error) { NSArray *items = [object items]; }];
// ... var ROOT = 'https://' + window.location.host + '/_ah/api'; gapi.client.load('superheroes', 'v1', loadSuperheroesCallback, ROOT); // Get the list of superheroes gapi.client.superheroes.superheroes.list().execute(function(resp) { displaySuperheroesList(resp); });