The APIs for three of Apps Script's advanced services — Analytics, BigQuery, and Prediction — will undergo breaking changes on Monday, November 18. If you don't update your code to the new syntax before then, you'll receive error messages such as Required parameter is missing.
Required parameter is missing
Advanced services allow you to easily connect to certain public Google APIs from Apps Script. We're working to expand and improve our advanced services, and as a side effect some methods and parameters that were incorrectly listed as optional are now required.
On November 18, these services will switch to use the new method signatures shown in the tables below. To learn how new arguments should be structured, refer to the documentation for the underlying API. For example, the documentation for the BigQuery service's Jobs.query() method shows the valid properties for the resource object in the "Request body" section of the page.
Jobs.query()
resource
Analytics.Management.Uploads
.deleteUploadData( accountId, webPropertyId, customDataSourceId, optionalArgs)
.deleteUploadData( resource, accountId, webPropertyId, customDataSourceId)
BigQuery.Datasets
.insert( resource, optionalArgs)
.insert( resource, projectId)
.update( resource, optionalArgs)
.update( resource, projectId, datasetId)
BigQuery.Jobs
.insert( resource, mediaData, optionalArgs)
.insert( resource, projectId, mediaData)
.query( projectId, query)
.query( resource, projectId)
BigQuery.Tabledata
.insertAll( projectId, datasetId, tableId, optionalArgs)
.insertAll( resource, projectId, datasetId, tableId)
BigQuery.Tables
.insert( resource, projectId, datasetId)
.update( resource, projectId, datasetId, tableId)
Prediction.Hostedmodels
.predict( project, hostedModelName, optionalArgs)
.predict( resource, project, hostedModelName)
Prediction.Trainedmodels
.insert( project, optionalArgs)
.insert( resource, project)
.predict( project, id, optionalArgs)
.predict( resource, project, id)
.update( project, id, optionalArgs)
.update( resource, project, id)
If you want to prepare your code ahead of time, you can add a try/catch around your existing code that retries with the new method signature if the old one fails. For example, the following sample applies this approach to the BigQuery service's Jobs.query() method:
try/catch
var result; try { result = BigQuery.Jobs.query(projectId, query, { timeoutMs: 10000 }); } catch (e) { // Refer to the BigQuery documentation for the structure of the // resource object. var resource = { query: query, timeoutMs: 1000 }; result = BigQuery.Jobs.query(resource, projectId); }
We apologize for inconvenience and look forward to sharing exciting news about advanced services in the coming weeks.
We launched Actions in the Inbox at Google I/O 2013 as a quick way for users to get things done directly from Gmail. Integrating with this technology only requires adding some markup to an email to define what the message is about and what actions the user can perform.
We support a variety of action types covering common scenarios such as adding a movie to a queue, product reviews, or other even pre-defined requests. Especially popular with senders is the One-Click Action to validate a user’s email address, as shown below:
If you are using Mandrill, the email infrastructure service from MailChimp, writing a Python app to send one of those emails, only takes a few lines of code! Take a look at this example:
import mandrill # Replace with your own values API_KEY = 'YOUR_API_KEY' FROM_ADDRESS = 'YOUR_FROM_ADDRESS' TO_ADDRESS = 'YOUR_TO_ADDRESS' SUBJECT = 'Please validate your email address' HTML_CONTENT = """ <html> <body> <script type='application/ld+json'> { "@context": "http://schema.org", "@type": "EmailMessage", "action": { "@type": "ConfirmAction", "name": "Confirm Registration", "handler": { "@type": "HttpActionHandler", "url": "https://mydomain.com/validate?id=abc123" } } } </script> <p>Please click on this link to validate your email address:</p> <p><a href="https://mydomain.com/validate?id=abc123">https://mydomain.com/validate?id=abc123</a></p> </body> </html> """ # Instantiate the Mandrill client with your API Key mandrill_client = mandrill.Mandrill(API_KEY) message = { 'html': HTML_CONTENT, 'subject': SUBJECT, 'from_email': FROM_ADDRESS, 'to': [{'email': TO_ADDRESS}], } result = mandrill_client.messages.send(message=message)
To run this app, just replace the API key with the credentials from your Mandrill account and configure the sender and recipient addresses. You should also edit the HTML content to provide your action handler URL, and customize the messaging if you want.
You can use Actions in the Inbox to reduce the friction and increase the conversion rate. Please note that you are not limited to validating email addresses: you can also review products and services, reply to event invitations, and much more.
For more information, please visit our documentation at https://developers.google.com/gmail/actions. You can also ask questions on Stack Overflow, with the tag google-schemas.
Apps Script started out as a simple tool to let developers add new features to Google Apps, but it’s grown into a programming platform that thousands of professional coders use every day. We hear a couple common requests from developers when they’re building complex projects with Apps Script: they want a full-featured IDE, and they want to sync to external version-control systems like GitHub.
Today, we’re introducing support for Apps Script in the Google Plugin for Eclipse. You can now sync with your existing Apps Script files on Google Drive, edit them in Eclipse — offline, if necessary, and with all the benefits of autocomplete — then write your code back to Drive so you can run it in the cloud. Because the plugin stores a copy of each script in a local workspace, you can manage Apps Script projects with your favorite version-control system.
Getting started is easy:
For step-by-step instructions on installation and use, see the documentation on using Apps Script with the Google Plugin for Eclipse.
Just in case you were wondering, the plugin uses the public Google Drive SDK to sync Apps Script files between your local file system and Google’s servers. We’ve previously covered the techniques it uses in our documentation on importing and exporting projects and the recent episode of Apps Script Crash Course on Google Developers Live below.
Last month, we announced several new ways to customize Google Forms. As of this week, three of those options are also available in forms created from Apps Script — embedding YouTube videos, displaying a progress bar, and showing a custom message if a form isn’t accepting responses.
Adding a YouTube video is as simple as any other Google Forms operation in Apps Script — from the Form object, just call addVideoItem(), then setVideoUrl(youtubeUrl). Naturally, you can also control the video’s size, alignment, and so forth.
Form
addVideoItem()
setVideoUrl(youtubeUrl)
To show a progress bar, call setProgressBar(enabled). Don’t even need a second sentence to explain that one. The custom message for a form that isn’t accepting responses is similarly easy: setCustomClosedFormMessage(message), and you’re done.
setProgressBar(enabled)
setCustomClosedFormMessage(message)
Want to give it a try yourself? Copy and paste the sample code below into the script editor at script.google.com, then hit Run. When the script finishes, click View > Logs to grab the URL for your new form, or look for it in Google Drive.
script.google.com
function showNewFormsFeatures() { var form = FormApp.create('New Features in Google Forms'); var url = form.getPublishedUrl(); form.addVideoItem() .setVideoUrl('http://www.youtube.com/watch?v=38H7WpsTD0M'); form.addMultipleChoiceItem() .setTitle('Look, a YouTube video! Is that cool, or what?') .setChoiceValues(['Cool', 'What']); form.addPageBreakItem(); form.addCheckboxItem() .setTitle('Progress bars are silly on one-page forms.') .setChoiceValues(['Ah, that explains why the form has two pages.']); form.setProgressBar(true); form.setCustomClosedFormMessage('Too late — this form is closed. Sorry!'); // form.setAcceptingResponses(false); // Uncomment to see custom message. Logger.log('Open this URL to see the form: %s', url); }
Security is a top priority for Google, just as it is for many of our Google Apps customers. As a domain administrator, a big part of keeping your users safe is knowing when and how they are using their accounts. Since we launched the Admin SDK Reports API in June, we've continued to add features to let you more easily visualize Google Apps' usage and security in your domain. These new features include:
Security Reports
Usage Reports
Refer to the Reports API documentation for more details on how to use the Reports API and to see what is possible with all of our entire Admin SDK.
Drive is a great drop zone for incoming files -- no matter if they’re coming from cameras, scanners, faxes, or countless other devices or apps. But throwing files into the root folder makes it difficult for users to find and organize their content.
I’ve seen developers create a folder when the user first connects the app with Drive to keep files organized by the app that created it. It’s a simple technique that is easy to implement and good default behavior for most applications.
With the Picker API, we can go a step further and offer users the choice of destinations too. For example, I’d like my scanner to put work files in one folder and personal files in another, or even configure multiple destinations depending on the type of document I’m scanning.
For this particular use case, the picker needs to be configured to show folders and only show folders. That requires customizing the DocsView just a little.
var docsView = new google.picker.DocsView() .setIncludeFolders(true) .setMimeTypes('application/vnd.google-apps.folder') .setSelectFolderEnabled(true);
By enabling folders & the ability to select them while simultaneously filtering out everything else, users can quickly and easily select one of their existing folders as a destination. The rest of the code to show the picker is par for the course.
// Handle user actions with the picker. var callback = function(data) { if (data.action == google.picker.Action.PICKED) { var doc = data.docs[0]; alert("You picked " + doc.id); } }; var picker = new google.picker.PickerBuilder() .addView(docsView) .setCallback(callback) .build(); picker.setVisible(true);
Not only is this easy to implement, it’s safer for users. By offloading this functionality to the Picker API, an app only needs the drive.file scope to write files into the user’s preferred location.
You can learn more about the Picker API at developers.google.com or ask questions at StackOverflow with the google-drive-sdk tag.