├── .codeclimate.yml
├── LICENCE
├── ProcessApp.js
└── README.md
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | ---
2 | engines:
3 | duplication:
4 | enabled: true
5 | config:
6 | languages:
7 | - ruby
8 | - javascript
9 | - python
10 | - php
11 | eslint:
12 | enabled: true
13 | fixme:
14 | enabled: true
15 | ratings:
16 | paths:
17 | - "**.inc"
18 | - "**.js"
19 | - "**.jsx"
20 | - "**.module"
21 | - "**.php"
22 | - "**.py"
23 | - "**.rb"
24 | exclude_paths:
25 | - "tests/"
26 | - "spec/"
27 | - "**/vendor/"
28 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2019 Kanshi TANAIKE
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 |
--------------------------------------------------------------------------------
/ProcessApp.js:
--------------------------------------------------------------------------------
1 | /**
2 | * GitHub https://github.com/tanaikech/ProcessApp
3 | * Retrieve total execution time of time-driven trigger.
4 | * @param {Object} object Object
5 | * @return {Object} Total execution time of time-driven trigger
6 | */
7 | function getExecutionTimeOfTrigger(object) {
8 | return new ProcessApp(1).GetExecutionTimeOfTrigger(object);
9 | }
10 |
11 | /**
12 | * Retrieve endpoint of dev mode for Web Apps.
13 | * @param {String} projectId Project ID
14 | * @return {String} URL of dev mode
15 | */
16 | function getDevUrl(projectId) {
17 | return new ProcessApp(2).GetDevUrl(projectId);
18 | }
19 |
20 | /**
21 | * Retrieve functions which are running.
22 | * @return {String} URL of dev mode
23 | */
24 | function getRunningFunctions() {
25 | return new ProcessApp(1).GetRunningFunctions();
26 | }
27 |
28 | /**
29 | * Retrieve total execution time of the specific process type.
30 | * @param {Object} object Object
31 | * @return {Object} Total execution time of the specific process type
32 | */
33 | function getExecutionTimeOfProcessType(object) {
34 | return new ProcessApp(1).GetExecutionTimeOfProcessType(object);
35 | }
36 | ;
37 | (function(r) {
38 | var ProcessApp;
39 | ProcessApp = (function() {
40 | var addQuery, defaultStartEndTime, parseData;
41 |
42 | ProcessApp.name = "ProcessApp";
43 |
44 | function ProcessApp(method_) {
45 | switch (method_) {
46 | case 1:
47 | this.url = "https://script.googleapis.com/v1/processes";
48 | break;
49 | case 2:
50 | this.url = "https://script.googleapis.com/v1/projects/{projectId}/deployments?fields=deployments";
51 | }
52 | this.at = ScriptApp.getOAuthToken();
53 | }
54 |
55 | ProcessApp.prototype.GetExecutionTimeOfTrigger = function(p_) {
56 | var data, e, endTime, endpoint, nextPageToken, params, q, ref, startTime;
57 | try {
58 | if (p_ == null) {
59 | p_ = {};
60 | }
61 | params = {
62 | headers: {
63 | Authorization: 'Bearer ' + this.at
64 | }
65 | };
66 | ref = defaultStartEndTime.call(this, p_), startTime = ref[0], endTime = ref[1];
67 | data = [];
68 | nextPageToken = "";
69 | while (true) {
70 | q = {
71 | pageToken: nextPageToken,
72 | fields: "*",
73 | "userProcessFilter.functionName": p_.functionName || "",
74 | "userProcessFilter.scriptId": p_.projectId || "",
75 | "userProcessFilter.startTime": startTime,
76 | "userProcessFilter.endTime": endTime,
77 | "userProcessFilter.types": "TIME_DRIVEN"
78 | };
79 | endpoint = addQuery.call(this, this.url, q);
80 | r = UrlFetchApp.fetch(endpoint, params);
81 | r = JSON.parse(r.getContentText());
82 | Array.prototype.push.apply(data, r.processes);
83 | nextPageToken = r.nextPageToken || "";
84 | if (!nextPageToken) {
85 | break;
86 | }
87 | }
88 | return parseData.call(this, data);
89 | } catch (error) {
90 | e = error;
91 | throw new Error(e);
92 | }
93 | };
94 |
95 | ProcessApp.prototype.GetDevUrl = function(p_) {
96 | var e, params, projectId;
97 | if (p_ == null) {
98 | throw new Error("Please set projectId.");
99 | }
100 | try {
101 | projectId = typeof p_ === "object" ? p_.projectId : p_;
102 | this.url = this.url.replace("{projectId}", projectId);
103 | params = {
104 | headers: {
105 | Authorization: 'Bearer ' + this.at
106 | }
107 | };
108 | r = UrlFetchApp.fetch(this.url, params);
109 | r = JSON.parse(r.getContentText());
110 | return "https://script.google.com/macros/s/" + r.deployments[0].deploymentId + "/dev";
111 | } catch (error) {
112 | e = error;
113 | throw new Error(e);
114 | }
115 | };
116 |
117 | ProcessApp.prototype.GetRunningFunctions = function() {
118 | var e, endpoint, params, q;
119 | try {
120 | params = {
121 | headers: {
122 | Authorization: 'Bearer ' + this.at
123 | }
124 | };
125 | q = {
126 | fields: "*",
127 | "userProcessFilter.statuses": "RUNNING"
128 | };
129 | endpoint = addQuery.call(this, this.url, q);
130 | r = UrlFetchApp.fetch(endpoint, params);
131 | r = JSON.parse(r.getContentText());
132 | return r.processes || [];
133 | } catch (error) {
134 | e = error;
135 | throw new Error(e);
136 | }
137 | };
138 |
139 | ProcessApp.prototype.GetExecutionTimeOfProcessType = function(p_) {
140 | var data, e, endTime, endpoint, nextPageToken, params, q, ref, startTime;
141 | try {
142 | if (p_ == null) {
143 | p_ = {};
144 | }
145 | params = {
146 | headers: {
147 | Authorization: 'Bearer ' + this.at
148 | }
149 | };
150 | ref = defaultStartEndTime.call(this, p_), startTime = ref[0], endTime = ref[1];
151 | data = [];
152 | nextPageToken = "";
153 | while (true) {
154 | q = {
155 | pageToken: nextPageToken,
156 | fields: "*",
157 | "userProcessFilter.functionName": p_.functionName || "",
158 | "userProcessFilter.scriptId": p_.projectId || "",
159 | "userProcessFilter.types": p_.processType || "EDITOR",
160 | "userProcessFilter.startTime": startTime,
161 | "userProcessFilter.endTime": endTime
162 | };
163 | endpoint = addQuery.call(this, this.url, q);
164 | r = UrlFetchApp.fetch(endpoint, params);
165 | r = JSON.parse(r.getContentText());
166 | Array.prototype.push.apply(data, r.processes);
167 | nextPageToken = r.nextPageToken || "";
168 | if (!nextPageToken) {
169 | break;
170 | }
171 | }
172 | return parseData.call(this, data);
173 | } catch (error) {
174 | e = error;
175 | throw new Error(e);
176 | }
177 | };
178 |
179 | defaultStartEndTime = function(p_) {
180 | var endTime, startTime, t;
181 | startTime = "";
182 | endTime = "";
183 | if (p_.startTime && p_.endTime) {
184 | startTime = p_.startTime;
185 | endTime = p_.endTime;
186 | } else {
187 | t = new Date();
188 | endTime = t.toISOString();
189 | t.setDate(t.getDate() - 1);
190 | startTime = t.toISOString();
191 | }
192 | return [startTime, endTime];
193 | };
194 |
195 | parseData = function(data) {
196 | var r1, r2, statistics;
197 | r1 = data.reduce(function(obj, e) {
198 | obj[e.functionName] = obj[e.functionName] ? obj[e.functionName] + Number(e.duration.replace("s", "")) : Number(e.duration.replace("s", ""));
199 | return obj;
200 | }, {});
201 | r2 = Object.keys(r1).map(function(e) {
202 | return {
203 | functionName: e,
204 | totalExecutionTimeSec: Math.round(r1[e] * 100) / 100,
205 | totalExecutionTimeMin: Math.round((r1[e] / 60) * 100) / 100
206 | };
207 | });
208 | statistics = r2.reduce(function(obj, e) {
209 | obj.allFunctions = obj.allFunctions ? obj.allFunctions.concat(e.functionName) : [e.functionName];
210 | obj.totalExecutionTimeSec = obj.totalExecutionTimeSec ? obj.totalExecutionTimeSec + e.totalExecutionTimeSec : e.totalExecutionTimeSec;
211 | obj.totalExecutionTimeMin = obj.totalExecutionTimeMin ? obj.totalExecutionTimeMin + e.totalExecutionTimeMin : e.totalExecutionTimeMin;
212 | return obj;
213 | }, {});
214 | statistics.totalExecutionTimeSec = Math.round(statistics.totalExecutionTimeSec * 100) / 100;
215 | statistics.totalExecutionTimeMin = Math.round(statistics.totalExecutionTimeMin * 100) / 100;
216 | return {
217 | statistics: statistics,
218 | eachFunction: r2
219 | };
220 | };
221 |
222 | addQuery = function(url_, obj_) {
223 | return url_ + Object.keys(obj_).reduce(function(p, e, i) {
224 | return p + (i === 0 ? "?" : "&") + e + "=" + encodeURIComponent(obj_[e]);
225 | }, "");
226 | };
227 |
228 | return ProcessApp;
229 |
230 | })();
231 | return r.ProcessApp = ProcessApp;
232 | })(this);
233 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ProcessApp
2 | =====
3 |
4 |
5 | [](LICENCE)
6 |
7 |
8 | # Overview
9 | **This is a library for retrieving the process and information of Google Apps Script.**
10 |
11 |
12 | # Methods
13 | 1. [getExecutionTimeOfTrigger()](#getexecutiontimeoftrigger) : This method retrieves the total execution time of all functions executed by the time-driven trigger at owner's account. For example, you can know the total execution time of all functions executed by the time-driven trigger in 24 h.
14 | 1. [getDevUrl()](#getdevurl) : This method retrieves the endpoint of developer mode for Web Apps like ``https://script.google.com/macros/s/#####/dev``.
15 | 1. [getRunningFunctions()](#getrunningfunctions) : This method retrieves the functions which are running now.
16 | 1. [getExecutionTimeOfProcessType()](#getexecutiontimeofprocesstype) : This method retrieves the total execution time of all functions by filtering the process type. For example, the total execution time of Web Apps can be retrieved.
17 |
18 | I would like to add more methods in the future.
19 |
20 | # Library's project key
21 | ~~~
22 | 1y3BjeYyJUdI9U2JZ97POIXRTaYnjsbH6SUapd43s8S8vh2Io5pho6xZ6
23 | ~~~
24 |
25 | # How to install
26 | - Open Script Editor. And please operate follows by click.
27 | - -> Resource
28 | - -> Library
29 | - -> Input Script ID to text box. Script ID is **``1y3BjeYyJUdI9U2JZ97POIXRTaYnjsbH6SUapd43s8S8vh2Io5pho6xZ6``**.
30 | - -> Add library
31 | - -> Please select latest version
32 | - -> Developer mode ON (If you don't want to use latest version, please select others.)
33 | - -> Identifier is "**``ProcessApp``**". This is set under the default.
34 |
35 | [If you want to read about Libraries, please check this.](https://developers.google.com/apps-script/guide_libraries).
36 |
37 | # Enable Apps Script API
38 | This library uses [Apps Script API](https://developers.google.com/apps-script/api/reference/rest/). So please enable Apps Script API at API console as follows.
39 |
40 | - On script editor
41 | - Resources -> Cloud Platform project
42 | - View API console
43 | - At Getting started, click "Explore and enable APIs".
44 | - At left side, click Library.
45 | - At Search for APIs & services, input "apps script". And click Apps Script API.
46 | - Click Enable button.
47 | - If this API has already been enabled, please don't turn off.
48 |
49 | ## About scopes
50 | This library uses the following 3 scopes. These are installed in the library. So users are not required to do anything for this.
51 |
52 | - ``https://www.googleapis.com/auth/script.external_request``
53 | - ``https://www.googleapis.com/auth/script.processes``
54 | - ``https://www.googleapis.com/auth/script.deployments.readonly``
55 |
56 | # Methods
57 |
58 | ## 1. getExecutionTimeOfTrigger()
59 | ### Overview
60 | This method retrieves the total execution time of all functions executed by the time-driven trigger at owner's account. For example, you can know the total execution time of all functions executed by the time-driven trigger in 24 h.
61 |
62 | ### Description
63 | There are [quotas for "Triggers total runtime"](https://developers.google.com/apps-script/guides/services/quotas). For example, it's 90 min/day for the consumer account. So when users use the time-driven trigger, it is very important to know the current total execution time of all functions by the time-driven trigger. But there were no methods for directly retrieving the total execution time before. When Apps Script API was updated, the method of ["processes"](https://developers.google.com/apps-script/api/reference/rest/v1/processes) was also added. I thought that this might be able to be used for this situation, and I had experimented about this. As the result, it was found that this method can be used for directly retrieving the total execution time of all functions executed by the time-driven trigger. So I published this.
64 |
65 | ### Sample script
66 | This method can be used simply like below. In this case, as the default setting, the total execution time from now to 24 h ago is retrieved.
67 |
68 | ~~~javascript
69 | var res = ProcessApp.getExecutionTimeOfTrigger();
70 | ~~~
71 |
72 | Of course, you can see the period for retrieving the total execution time can be set using as follows. In this sample script, the total execution time from ``2019-02-01T00:00:00.000Z`` to ``2019-02-02T00:00:00.000Z`` of a function of ``myFunction1`` in the project ID of ``#####`` is retrieved.
73 |
74 | ~~~javascript
75 | var object = {
76 | projectId: "#####", // Project ID
77 | functionName: "myFunction1", // function name that you want to know the total execution time.
78 | startTime: "2019-02-01T00:00:00.000Z",
79 | endTime: "2019-02-02T00:00:00.000Z",
80 | };
81 | var res = ProcessApp.getExecutionTimeOfTrigger(object);
82 | ~~~
83 |
84 | - About ``startTime`` and ``endTime``
85 | - A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z". [Ref](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp)
86 |
87 | #### Result
88 | For example, when 2 functions of ``myFunction1()`` and ``myFunction2()`` are run by the time-driven trigger and the script is ``var res = ProcessApp.getExecutionTimeOfTrigger()``, this method returns the following result. From the result, it is found that the total execution time of both functions from now to 24 h ago is 1380 s. The breakdown of this is 1200 s and 180 s for ``myFunction1()`` and ``myFunction2()``, respectively.
89 |
90 | ~~~
91 | {
92 | "statistics": {
93 | "allFunctions": [
94 | "myFunction1",
95 | "myFunction2"
96 | ],
97 | "totalExecutionTimeSec": 1380.00,
98 | "totalExecutionTimeMin": 23.00
99 | },
100 | "eachFunction": [
101 | {
102 | "functionName": "myFunction1",
103 | "totalExecutionTimeSec": 1200.00,
104 | "totalExecutionTimeMin": 20.00
105 | },
106 | {
107 | "functionName": "myFunction2",
108 | "totalExecutionTimeSec": 180.00,
109 | "totalExecutionTimeMin": 3.00
110 | }
111 | ]
112 | }
113 | ~~~
114 |
115 | [Also this method was posted to Stackoverflow as an answer.](https://stackoverflow.com/a/54604118)
116 |
117 |
118 | ## 2. getDevUrl()
119 | ### Overview
120 | This method retrieves the endpoint of developer mode for Web Apps like ``https://script.google.com/macros/s/#####/dev``.
121 |
122 | ### Description
123 | There is the method in Class ScriptApp for retrieving the endpoint of Web Apps. It's ``ScriptApp.getService().getUrl()``. This method returns the endpoint of the deployed Web Apps like ``https://script.google.com/macros/s/#####/exec``. It's not the endpoint of developer mode like ``https://script.google.com/macros/s/#####/dev``. So I created this method of ``getDevUrl()``.
124 |
125 | ### Sample script
126 | ~~~javascript
127 | var projectId = "#####";
128 | var res = ProcessApp.getDevUrl(projectId);
129 | ~~~
130 |
131 | #### Result
132 | ~~~
133 | https://script.google.com/macros/s/#####/dev
134 | ~~~
135 |
136 |
137 | ## 3. getRunningFunctions()
138 | ### Overview
139 | This method retrieves the functions which are running now.
140 |
141 | ### Description
142 | For example, it supposes that there is a a function is run by the time-driven trigger and the execution time of function is long. At that time, I had a case that it is required to know whether the function is running now. So I created this method of ``getRunningFunctions()``. This method can be also used the event trigger and Web Apps.
143 |
144 | ### Sample script
145 | ~~~javascript
146 | var res = ProcessApp.getRunningFunctions();
147 | ~~~
148 |
149 | #### Result
150 | The process information of the running function is returned.
151 |
152 | ~~~json
153 | [
154 | {
155 | "projectName": "sample project",
156 | "functionName": "myFunction",
157 | "processType": "EDITOR",
158 | "processStatus": "RUNNING",
159 | "userAccessLevel": "OWNER",
160 | "startTime": "2000-01-01T00:00:00.000Z",
161 | "duration": "12.345s"
162 | }
163 | ]
164 | ~~~
165 |
166 |
167 | ## 4. getExecutionTimeOfProcessType()
168 | ### Overview
169 | This method retrieves the endpoint of developer mode for Web Apps like ``https://script.google.com/macros/s/#####/dev``.
170 |
171 | ### Description
172 | There is the method in Class ScriptApp for retrieving the endpoint of Web Apps. It's ``ScriptApp.getService().getUrl()``. This method returns the endpoint of the deployed Web Apps like ``https://script.google.com/macros/s/#####/exec``. It's not the endpoint of developer mode like ``https://script.google.com/macros/s/#####/dev``. So I created this method of ``getDevUrl()``.
173 |
174 | ### Sample script
175 | The basic usage is almost the same with [getExecutionTimeOfTrigger()](#getexecutiontimeoftrigger). In this method, the result is filtered by the process type. You can select the process type from [here](https://developers.google.com/apps-script/api/reference/rest/v1/processes#ProcessType)
176 |
177 | | Process type | Description |
178 | |:---|:---|
179 | | PROCESS_TYPE_UNSPECIFIED | Unspecified type. |
180 | | ADD_ON | The process was started from an add-on entry point. |
181 | | EXECUTION_API | The process was started using the Apps Script API. |
182 | | TIME_DRIVEN | The process was started from a time-based trigger. |
183 | | TRIGGER | The process was started from an event-based trigger. |
184 | | WEBAPP | The process was started from a web app entry point. |
185 | | EDITOR | The process was started using the Apps Script IDE. |
186 | | SIMPLE_TRIGGER | The process was started from a G Suite simple trigger. |
187 | | MENU | The process was started from a G Suite menu item. |
188 |
189 | This method can be used simply like below. In this case, as the default setting, the total execution time from now to 24 h ago is retrieved. And the process type of "EDITOR" is used. "EDITOR" means that the total execution time of functions executed by the script editor is retrieved.
190 |
191 | ~~~javascript
192 | var res = ProcessApp.getExecutionTimeOfTrigger();
193 | ~~~
194 |
195 | Of course, you can see the period for retrieving the total execution time can be set using as follows. In this sample script, the total execution time from ``2019-02-01T00:00:00.000Z`` to ``2019-02-02T00:00:00.000Z`` of a function of ``doGet`` executed by Web Apps in the project ID of ``#####`` is retrieved.
196 |
197 | ~~~javascript
198 | var object = {
199 | projectId: "#####", // Project ID
200 | functionName: "doGet", // function name that you want to know the total execution time.
201 | processType: "WEBAPP",
202 | startTime: "2019-02-01T00:00:00.000Z",
203 | endTime: "2019-02-02T00:00:00.000Z",
204 | };
205 | var res = ProcessApp.getExecutionTimeOfTrigger(object);
206 | ~~~
207 |
208 | #### Result
209 |
210 | ~~~
211 | {
212 | "statistics": {
213 | "allFunctions": [
214 | "doGet",
215 | ],
216 | "totalExecutionTimeSec": 1200.00,
217 | },
218 | "eachFunction": [
219 | {
220 | "functionName": "doGet",
221 | "totalExecutionTimeSec": 1200.00,
222 | "totalExecutionTimeMin": 20.00
223 | }
224 | ]
225 | }
226 | ~~~
227 |
228 | -----
229 |
230 |
231 | # Licence
232 | [MIT](LICENCE)
233 |
234 |
235 | # Author
236 | [Tanaike](https://tanaikech.github.io/about/)
237 |
238 | If you have any questions and commissions for me, feel free to contact me.
239 |
240 |
241 | # Update History
242 | * v1.0.0 (February 9, 2019)
243 |
244 | 1. Initial release.
245 |
246 | * v1.0.1 (February 10, 2019)
247 |
248 | 1. New method of [getExecutionTimeOfProcessType()](#getexecutiontimeofprocesstype) was added.
249 | - This method retrieves the total execution time of all functions by filtering the process type. For example, the total execution time of Web Apps can be retrieved.
250 |
251 |
252 | [TOP](#top)
253 |
--------------------------------------------------------------------------------