Can I define a simple trigger from a standalone script? - gsuite-addons

Specifically, I want to use the onSelectionChange(e) event to show a sidebar depending on what's in the selected cell. The problem is: the project I am working on is a standalone script. So I want to know if there is a way to use the onOpen event (for example) and check if the script is being run from a spreadsheet and somehow 'inject' the trigger.

I was trying something pretty much like in the documentation, but I never got it to fire, I guess because it was a standalone script.
const onSelectionChange = (e) => {
Logger.log(`onSelectionChange triggered: ${e.toString()}`);
const { range } = e;
if (range.getNumRows() === 1 && range.getNumColumns() === 1) {
range.setBackground('green');
}
};
So the actual solution for me was to create a new document with clasp. Using the command:
npx clasp create --type sheets --title "foo" --rootDir ./dist
and then uploading the script to this new project.

Related

Get notification in a VS Code extension when the Python interpreter is changed

I am writing a VS Code extension that depends on the currently set Python interpreter. When I change the Python Interpreter via the VS Code UI, the extension needs to refresh and get the latest Python path (mainly to show the right environment settings in the TreeView). For now, I have a refresh button in my custom TreeView that I need to press after selecting a different Python interpreter.
However, this is a second manual step. Is there a way to get a notification in my extension, when a user changes the Python Interpreter, e.g., an event the extension can listen to?
I only found VS Code's Activation Events, but it doesn't look like this would help. I didn't find any other events that get triggered after the command python.setInterpreter is executed
Finally found it. The right config to watch for is python.defaultInterpreterPath
vscode.workspace.onDidChangeConfiguration(event => {
let affected = event.affectsConfiguration("python.defaultInterpreterPath");
if (affected) {
doSomething();
}
});
To support the usingNewInterpreterStorage case (default today), add:
const extension = vscode.extensions.getExtension('ms-python.python')!;
await extension.activate();
extension.exports.settings.onDidChangeExecutionDetails((event: any) => {
doSomething();
});

Output text at the very end of custom Nx workspace generator

Is it possible to output/log text at the very end the workspace generator output?
I would like to notify the user of the next steps he/she should do, but my logs are kind of hidden above all the output generated by the tree updates.
export default async function (tree: Tree, schema: GeneratorOptions) {
await applicationGenerator(tree, {
// options go here
});
//format all the new files
await formatFiles(tree);
// log out next steps
logger.info('next steps');
logger.info('* Complete information in /src/environment files');
logger.info('* Adjust example routes in /src/app/app.tsx');
}
The code above results in the following output, as you can see my logs are completely at the top (and nobody would ever see them)
I was having the same problem and judging from this open issue it does not seem to be a way to do it.
What I ended up doing was wrapping the command to run the generator in a node script and then run that script instead:
import {execSync} from "child_process";
execSync('nx workspace-generator your-generator', {stdio: 'inherit'})
console.log('after')

How to get user input in protractor tool

Actually I want to get user input from user whoever runs the script. I do not want to hardcode the testdata path in the script. for example when I run a script to test angularjs using protractor and javascript. User should be able to give path of the testdata, so that I can use that variable inside the script.
You can do this by passing in a params.testData value from the command line.
protractor conf.js --params.testData=D:\path\to\testdata.xlsx
Then in your test you will reference it using the global browser.params object. You will also need to use fs to read the file and process the data. Honestly, it would probably be easier if you created a .json file for the test data instead of an .xlsx but it looks there are libraries out there to help you parse an xlsx document already if you have to stick with that. Check this answer for some examples.
This code will not work as is but the basic idea will be something like this:
before(() => {
const testDataPath = browser.params.testData;
fs.readFile(testDataPath, (err, data) => {
if(err) { // fail? };
const testData = data;
// do some other stuff with test data ...
});
}
You are going to need to do some additional processing of the data from the .xlsx file to get it in the correct format but this should hopefully help get you on the right path.

How to execuete windows workflow from commandline

I need to execute workflow from command line that is already created using UI.
Already I have tried to invoke workflow by creating workflow instance.
the code shown below which is i was tried
XmlTextReader reader = new XmlTextReader("Workflow1.xml");
Console.WriteLine("Waiting for Workflow completion..");
WorkflowRuntime runtime = new WorkflowRuntime();
WorkflowInstance instance = runtime.CreateWorkflow(reader);
instance.Start();
but it shows the error message "xml tag is not framed well".
I have fully copied the workflow xaml content and pasted in Workflow1.xml file.
is there any other possibilities to achieve this.
Thanks in Advance.
It looks like you are using Windows Workflow 4, but you are trying to use the Windows Workflow 3 runtime to execute the workflow. I've got a white paper [1] on WF 4 that might be useful, but here's a snippet from that article that might be helpful. It uses the workflowInvoker class to execute the workflow. You can also use WorkflowApplication if you have long running workflows that need bookmarking capabilities.
Activity mathWF;
using (Stream mathXaml = File.OpenRead("Math.xaml"))
{
mathWF = ActivityXamlServices.Load(mathXaml);
}
var outputs = WorkflowInvoker.Invoke(mathWF,
new Dictionary<string, object> {
{ "operand1", 5 },
{ "operand2", 10 },
{ "operation", "add" } });
Assert.AreEqual<int>(15, (int)outputs["result"], "Incorrect result returned");
Developer's Introduction to Windows Workflow

Google Apps Script - Scripts in copied spreadsheet not retaining trigger

I am using a script in a Google Spreadsheet to, upon form submission, copy an existing spreadsheet and google form to create a new spreadsheet and new form and then connect the new form to the new spreadsheet so the new spreadsheet is receiving the responses from the new form.
The script in the copied spreadsheet is copied to the new spreadsheet, but the installed triggers don't exist. Is there a way to create those triggers from the original spreadsheet's script (the spreadsheet that received the form submission that created the new SS and form) or do I need to rely upon non-installed triggers in the new spreadsheet to create the installed trigger?
Triggers run scripts which require authorization by the user. Because your script is bound to a spreadsheet, it will need to be authorized on each copy.
I have a similar system (copies of a master sheet + code) and we addressed this by adding a custom menu to run a script when someone makes a copy. I added a custom menu and a setup script which would authorize the trigger.
function onOpen(e) {
var ui = SpreadsheetApp.getUi().createMenu("PGP Setup").addItem("Run", "setup").addToUi();
}
function setup() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('makeDocs')
.timeBased()
.everyHours(1)
.create();
}
It's easy on the user who created the sheet and has been reliable for us so far.
I was able to solve my issue with the code below. The function 'newSSTrigger' is in the original script (not a copied one) and is called after the new SS and Form are created and sync'd - this is where the the variable idOfNewSS comes from. The trigger will not create a script in the new objects or even be seen in the new object's scripts as an installed trigger. To find the trigger go to Edit>All Your Triggers from any script. Triggers not greyed out are attached to the document in some way.
This seems to have two benefits:
1) I never have to deal with any permissions - the triggers work without me touching the new docs at all.
2) If I update the 'myFunction' (below) it changes how the existing triggers work because the trigger retrieves its instructions from the original script - in its current state. This means I can update all existing triggers created by this script just by editing this function.
function newSSTrigger(idOfNewSS) {
var newSS = SpreadsheetApp.openById(idOfNewSS);
ScriptApp.newTrigger("myFunction")
.forSpreadsheet(newSS)
.onFormSubmit()
.create();
}
function myFunction() {
do stuff...
}
A different option that would work for people who are not just copying a sheet programmatically (or who are anticipating users making copies that the developer doesn't have permission to edit) is to take care of it for the user inside the bound script. You could use code similar to this:
function onOpen(){
var triggers = ScriptApp.getProjectTriggers();
if(triggers.length == 0){
ScriptApp.newTrigger('yourFunction')
.timeBased()
.everyHours(1)
.create();
}
This says that if there are no triggers, add a time-based trigger. You can see this documentation for variations.