├── PubsubAppREADME.pdf
├── README.md
├── examples
├── Async-Response-Processing
│ ├── Form-Collector
│ │ ├── code.gs
│ │ └── index.html
│ └── Form-Processor
│ │ └── code.gs
└── Gmail-Notifications
│ └── GmailNotifications.gs
└── src
├── PublishingApp.gs
├── PubsubApp.gs
├── SubscriptionApp.gs
└── policyBuilder.gs
/PubsubAppREADME.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Spencer-Easton/Apps-Script-PubSubApp-Library/babfae1a8771e49f9cf45b89f312b9730804f452/PubsubAppREADME.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apps-Script-PubSubApp-Library
2 | An Apps Script library for the Google Cloud Pub/Sub Service
3 | View the documentation [here](https://drive.google.com/open?id=0B_j9_-NbJQQDdm9BMWtVeDNhM28)
4 |
--------------------------------------------------------------------------------
/examples/Async-Response-Processing/Form-Collector/code.gs:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Spencer Easton
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | function doGet(e) {
18 | return HtmlService.createHtmlOutputFromFile('index').setSandboxMode(HtmlService.SandboxMode.IFRAME);
19 | }
20 |
21 |
22 | function handleResponse(response){
23 | try{
24 | PubSubApp.setTokenService(getTokenService());
25 | var pub = PubSubApp.PublishingApp('api-project-665...208');
26 | var message = pub.newMessage();
27 | message.data = Utilities.base64Encode(response);
28 | pub.getTopic('response').publish(message);
29 | return true;
30 | }catch(e){throw new Error(e)}
31 |
32 | }
33 |
34 |
35 | function getTokenService(){
36 | var jsonKey = JSON.parse(PropertiesService.getScriptProperties().getProperty("jsonKey"));
37 | var privateKey = jsonKey.private_key;
38 | var serviceAccountEmail = jsonKey.client_email;
39 | var sa = GSApp.init(privateKey, ['https://www.googleapis.com/auth/pubsub'], serviceAccountEmail);
40 | sa.addUser(serviceAccountEmail)
41 | .requestToken();
42 | return sa.tokenService(serviceAccountEmail);
43 | }
44 |
--------------------------------------------------------------------------------
/examples/Async-Response-Processing/Form-Collector/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Enter your name:
8 |
9 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/Async-Response-Processing/Form-Processor/code.gs:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Spencer Easton
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | function doPost(e) {
18 | var postBody = JSON.parse(e.postData.getDataAsString());
19 | var messageData = Utilities.newBlob(Utilities.base64Decode(postBody.message.data)).getDataAsString();
20 | Utilities.sleep(10000);
21 | var ss = SpreadsheetApp.openById('1DGHH-j8MaHx1UijIxHZcffLpMG_NDkf_LsGKL0GVWR8').getSheetByName("Log");
22 | ss.appendRow([new Date(), messageData, JSON.stringify(postBody,undefined,2)])
23 | return 200;
24 | }
25 |
--------------------------------------------------------------------------------
/examples/Gmail-Notifications/GmailNotifications.gs:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Spencer Easton
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | var PROJECTID = 'api-project-3...9';
18 | var WEBHOOK_URL = 'https://script.google.com/a/macros/ccsknights.org/s/AKfycbw_RzzP6WiptJ9T9EQKiW9I5AaZfhXAiWYrkcx9OOvc11s0_J8e/exec'
19 |
20 | function doPost(e){
21 | var postBody = JSON.parse(e.postData.getDataAsString());
22 | var messageData = Utilities.newBlob(Utilities.base64Decode(postBody.message.data)).getDataAsString();
23 | var ss = SpreadsheetApp.openById('1URu5nXCHLHYz5bEhMoRSb3reFdvrfb5Sl3zP0Rc00s8').getSheetByName("Log");
24 | ss.appendRow([new Date(), messageData, JSON.stringify(postBody,undefined,2)])
25 | return 200;
26 | }
27 |
28 | function setupPubSub(){
29 | var newTopic = CreateTopic("mailTrigger");
30 | newTopic.setIamPolicy(addGmailPolicy());
31 | Logger.log(newTopic.getName());
32 | var newSub = CreateSubscription("mailTrigger",newTopic.getName(),WEBHOOK_URL);
33 | }
34 |
35 | function enrollEmail(){
36 | PubSubApp.setTokenService(getTokenService())
37 | var topicName = PubSubApp.PublishingApp(PROJECTID).getTopicName("mailTrigger")
38 | Logger.log(watchEmail(topicName,{labelIds:["INBOX"]}));
39 | }
40 |
41 | function disEnrollEmail(){
42 | var res = UrlFetchApp.fetch("https://www.googleapis.com/gmail/v1/users/me/stop",{method:"POST",headers:{authorization:"Bearer "+ScriptApp.getOAuthToken()}});
43 | Logger.log(res.getContentText());
44 | }
45 |
46 |
47 | function addGmailPolicy(Policy){
48 | return PubSubApp.policyBuilder()
49 | [(Policy)?"editPolicy":"newPolicy"](Policy)
50 | .addPublisher("SERVICEACCOUNT", 'gmail-api-push@system.gserviceaccount.com')
51 | .getPolicy();
52 | }
53 |
54 | function addDomainSubs(Domain,Policy){
55 | return PubSubApp.policyBuilder()
56 | [(Policy)?"editPolicy":"newPolicy"](Policy)
57 | .addPublisher("DOMAIN", Domain)
58 | .getPolicy();
59 | }
60 |
61 | function getSubscriptionPolicy(){
62 | return PubSubApp.policyBuilder()
63 | .newPolicy()
64 | .addSubscriber("DOMAIN","ccsknights.org")
65 | }
66 |
67 | function watchEmail(fullTopicName,watchOptions){
68 | var options = {email:"me",token:ScriptApp.getOAuthToken(),labelIds:[]};
69 |
70 | for(var option in watchOptions){
71 | if(option in options){
72 | options[option] = watchOptions[option];
73 | }
74 | }
75 | Logger.log(options);
76 | var url = "https://www.googleapis.com/gmail/v1/users/"+options.email+"/watch"
77 |
78 | var payload = {
79 | topicName: fullTopicName,
80 | labelIds: options.labelIds
81 | }
82 |
83 | var params = {
84 | method:"POST",
85 | contentType: "application/json",
86 | payload: JSON.stringify(payload),
87 | headers:{Authorization: "Bearer "+ options.token
88 | },
89 | muteHttpExceptions:true
90 | }
91 |
92 | var results = UrlFetchApp.fetch(url, params);
93 |
94 | if(results.getResponseCode() != 200){
95 | throw new Error(results.getContentText())
96 | }else{
97 | return JSON.parse(results.getContentText());
98 | }
99 |
100 | }
101 |
102 | function CreateTopic(topicName) {
103 | var topic;
104 | PubSubApp.setTokenService(getTokenService());
105 | var pubservice = PubSubApp.PublishingApp(PROJECTID);
106 | try{topic = pubservice.newTopic(topicName)}
107 | catch(e){topic = pubservice.getTopic(topicName);}
108 | return topic;
109 | }
110 |
111 | function CreateSubscription(subscriptionName,topicName,webhookUrl){
112 | var sub;
113 | PubSubApp.setTokenService(getTokenService());
114 | var subService = PubSubApp.SubscriptionApp(PROJECTID);
115 | try{sub = subService.newSubscription(subscriptionName,topicName,webhookUrl)}
116 | catch(e){sub = subService.getSubscription(subscriptionName,topicName,webhookUrl)}
117 | return sub;
118 | }
119 |
120 |
121 | function getTokenService(){
122 | var jsonKey = JSON.parse(PropertiesService.getScriptProperties().getProperty("jsonKey"));
123 | var privateKey = jsonKey.private_key;
124 | var serviceAccountEmail = jsonKey.client_email;
125 | var sa = GSApp.init(privateKey, ['https://www.googleapis.com/auth/pubsub'], serviceAccountEmail);
126 | sa.addUser(serviceAccountEmail)
127 | .requestToken();
128 | return sa.tokenService(serviceAccountEmail);
129 | }
130 |
131 |
132 | function requestGmailScope_(){GmailApp.getAliases()}
133 |
--------------------------------------------------------------------------------
/src/PublishingApp.gs:
--------------------------------------------------------------------------------
1 | /*
2 | PubSubApp - PublishingApp.gs
3 |
4 | Copyright (c) 2015 Spencer Easton
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 |
19 | /*global tokenService_*/
20 | /*global CALLPAGE_*/
21 | /*global CALL_*/
22 |
23 |
24 | /********************************************
25 | * The constructor for the PublishingApp service
26 | * @param {string} projectId The API project ID of the pub/sub service.
27 | * @return {object} The PublishingApp service
28 | *********************************************/
29 | function PublishingApp(projectId) {
30 | return new ProjectTopic_(projectId);
31 | }
32 |
33 |
34 | /********************************************
35 | *********************************************/
36 | function ProjectTopic_(projectId) {
37 |
38 | if (!tokenService_) {
39 | throw new Error("You must set a token service first");
40 | }
41 | var self = this;
42 | self.project = projectId;
43 |
44 |
45 | /********************************************
46 | *********************************************/
47 | self.getTopics = function() {
48 | var path = 'projects/' + self.project + '/topics',
49 | options = {
50 | method: "GET"
51 | },
52 | topics = CALLPAGE_(path, options, "topics");
53 | return topics;
54 | };
55 |
56 | /********************************************
57 | *********************************************/
58 | self.getTopicName = function(topic) {
59 | var path = "projects/" + self.project + "/topics/" + topic,
60 | options = {
61 | method: "GET"
62 | },
63 | topicName = CALL_(path, options).name;
64 | return topicName;
65 | };
66 |
67 | /********************************************
68 | *********************************************/
69 | self.getTopic = function(topic) {
70 | return new Topic(self.getTopicName(topic));
71 | };
72 |
73 | /********************************************
74 | *********************************************/
75 | self.newTopic = function(topic) {
76 |
77 | // check for valid topic naming
78 | var expression = new RegExp(/^(?!goog)[a-z][a-z0-9-_\.~+%]{2,254}$/i);
79 | if (!expression.test(topic)) {
80 | throw new Error("Invalid Topic Name");
81 | }
82 |
83 | var path = 'projects/' + self.project + '/topics/' + topic,
84 | options = {
85 | method: "PUT"
86 | },
87 | topicName = CALL_(path, options).name;
88 | return new Topic(topicName);
89 | };
90 |
91 | /********************************************
92 | *********************************************/
93 |
94 | self.deleteTopic = function(topic) {
95 | var topicName = self.getTopicName(topic),
96 | path = 'projects/' + self.project + '/topics/' + topicName,
97 | options = {
98 | method: "DELETE"
99 | };
100 | CALL_(path, options);
101 | return self;
102 | };
103 |
104 | /********************************************
105 | *
106 | *********************************************/
107 | function Topic(topicName) {
108 | var topicObj = this;
109 | topicObj.topicName_ = topicName;
110 |
111 |
112 | /********************************************
113 | *********************************************/
114 | topicObj.setIamPolicy = function(policyResource) {
115 | var postBody = JSON.stringify({
116 | policy: policyResource
117 | }),
118 | path = topicObj.topicName_ + ":setIamPolicy",
119 | options = {
120 | method: "POST",
121 | payload: postBody
122 | };
123 | return CALL_(path, options);
124 | };
125 |
126 | /********************************************
127 | *********************************************/
128 | topicObj.getIamPolicy = function() {
129 | var path = topicObj.topicName_ + ":getIamPolicy",
130 | options = {
131 | method: "GET"
132 | };
133 | return CALL_(path, options);
134 | };
135 |
136 | /********************************************
137 | *********************************************/
138 | topicObj.testIamPolicy = function(permissionsArray) {
139 |
140 | var path = topicObj.topicName_ + ":testIamPermissions",
141 | options = {
142 | method: "POST",
143 | payload: JSON.stringify({
144 | "permissions": permissionsArray
145 | })
146 | };
147 |
148 | return CALL_(path, options);
149 | };
150 | /********************************************
151 | *********************************************/
152 | topicObj.getSubscriptions = function() {
153 | var path = topicObj.topicName_ + "/subscriptions",
154 | options = {
155 | method: "GET"
156 | },
157 | subscriptions = CALLPAGE_(path, options, "subscriptions");
158 | return subscriptions;
159 | };
160 |
161 | /********************************************
162 | *********************************************/
163 | topicObj.publish = function(Message) {
164 |
165 | var postBody = JSON.stringify({
166 | messages: [Message]
167 | }),
168 | path = topicObj.topicName_ + ":publish",
169 | options = {
170 | method: "POST",
171 | payload: postBody
172 | };
173 | return CALL_(path, options);
174 | };
175 |
176 | /********************************************
177 | *********************************************/
178 | topicObj.getName = function() {
179 | return topicObj.topicName_
180 | };
181 | return topicObj;
182 | }
183 |
184 | /********************************************
185 | *********************************************/
186 | self.newMessage = function() {
187 | var message = {};
188 | message.data = "";
189 | message.attributes = {};
190 | return JSON.parse(JSON.stringify(message));
191 | };
192 | return self;
193 | }
--------------------------------------------------------------------------------
/src/PubsubApp.gs:
--------------------------------------------------------------------------------
1 | /*
2 | PubSubApp - PubSubApp.gs
3 |
4 | Copyright (c) 2015 Spencer Easton
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 |
19 |
20 |
21 | var BASEURL_ = 'https://pubsub.googleapis.com/v1/';
22 | var tokenService_;
23 |
24 | /*
25 | * Stores the function passed that is invoked to get a OAuth2 token;
26 | * @param {function} service The function used to get the OAuth2 token;
27 | *
28 | */
29 | function setTokenService(service) {
30 | tokenService_ = service;
31 | }
32 |
33 |
34 | function CALL_(path, options) {
35 | var fetchOptions = {
36 | method: "",
37 | muteHttpExceptions: true,
38 | contentType: "application/json",
39 | headers: {
40 | Authorization: "Bearer " + tokenService_()
41 | }
42 | },
43 | url = BASEURL_ + path;
44 |
45 | for (var option in options) {
46 | fetchOptions[option] = options[option];
47 | }
48 |
49 | /*global UrlFetchApp*/
50 | var response = UrlFetchApp.fetch(url, fetchOptions);
51 | if (response.getResponseCode() != 200) {
52 | throw new Error(response.getContentText());
53 | }
54 | else {
55 | return JSON.parse(response.getContentText());
56 | }
57 | }
58 |
59 | function CALLPAGE_(path, options, returnParamPath) {
60 | var fetchOptions = {
61 | method: "",
62 | muteHttpExceptions: true,
63 | contentType: "application/json",
64 | headers: {
65 | Authorization: "Bearer " + tokenService_()
66 | }
67 | };
68 | for (var option in options) {
69 | fetchOptions[option] = options[option];
70 | }
71 |
72 | var url = BASEURL_ + path,
73 | returnArray = [],
74 | nextPageToken;
75 | do {
76 | if (nextPageToken) {
77 | url += "?pageToken=" + nextPageToken;
78 | }
79 | var results = UrlFetchApp.fetch(url, fetchOptions);
80 | if (results.getResponseCode() != 200) {
81 | throw new Error(results.getContentText());
82 | }
83 | else {
84 | var resp = JSON.parse(results.getContentText());
85 | nextPageToken = resp.nextPageToken;
86 | returnArray = returnArray.concat(resp[returnParamPath]);
87 | }
88 |
89 | } while (nextPageToken);
90 | return returnArray;
91 | }
--------------------------------------------------------------------------------
/src/SubscriptionApp.gs:
--------------------------------------------------------------------------------
1 | /*
2 | PubSubApp - SubscriptionApp.gs
3 |
4 | Copyright (c) 2015 Spencer Easton
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 |
19 | /*global tokenService_*/
20 | /*global CALLPAGE_*/
21 | /*global CALL_*/
22 |
23 | /********************************************
24 | * Construtor for the SubscriptionApp service
25 | * @param {string} projectId The API project ID of the pub/sub service
26 | * @return {object} The SubscriptionApp service
27 | *********************************************/
28 | function SubscriptionApp(projectId) {
29 | return new ProjectSubscription_(projectId)
30 | }
31 |
32 | /********************************************
33 | *********************************************/
34 | function ProjectSubscription_(projectId) {
35 | var self_ = this;
36 | self_.project = projectId;
37 |
38 | /********************************************
39 | *********************************************/
40 | self_.getSubscriptions = function() {
41 | var path = 'projects/' + self_.project + '/subscriptions',
42 | options = {
43 | method: "GET"
44 | },
45 | subscriptions = CALLPAGE_(path, options, "subscriptions");
46 | return subscriptions;
47 | };
48 |
49 | /********************************************
50 | *********************************************/
51 | self_.getSubscription = function(subscriptionName) {
52 | var path = "projects/" + self_.project + "/subscriptions/" + subscriptionName,
53 | options = {
54 | method: "GET"
55 | },
56 | subResource = CALL_(path, options);
57 | return new Subscription(subResource);
58 | };
59 |
60 | /********************************************
61 | *********************************************/
62 | self_.deleteSubscription = function(subscriptionName) {
63 | var path = "projects/" + self_.project + "/subscriptions/" + subscriptionName,
64 | options = {
65 | method: "DELETE"
66 | };
67 | CALL_(path, options);
68 | return self_;
69 | };
70 |
71 | /********************************************
72 | *********************************************/
73 | self_.newSubscription = function(subscriptionName, topicName, endPoint) {
74 | var expression = new RegExp(/^(?!goog)[a-z][a-z0-9\-_\.~+%]{2,254}$/i);
75 | if (!expression.test(subscriptionName)) {
76 | throw new Error("Invalid Subscription Name");
77 | }
78 | var path = "projects/" + self_.project + "/subscriptions/" + subscriptionName,
79 | subOptions = {
80 | topic: topicName,
81 | pushConfig: {},
82 | ackDeadlineSeconds: 30
83 | };
84 |
85 | if (endPoint) {
86 | subOptions.pushConfig.pushEndpoint = endPoint;
87 | }
88 | var options = {
89 | method: "PUT",
90 | payload: JSON.stringify(subOptions)
91 | },
92 | subResource = CALL_(path, options);
93 | return new Subscription(subResource);
94 | };
95 |
96 | /********************************************
97 | *********************************************/
98 | function Subscription(subResource) {
99 | var selfSub = this;
100 | selfSub.resource = subResource;
101 |
102 | /******************************************/
103 | /******************************************/
104 | selfSub.getResource = function() {
105 | return selfSub.resource
106 | };
107 |
108 | /******************************************/
109 | /******************************************/
110 | selfSub.setIamPolicy = function(policyResource) {
111 | var path = selfSub.resource.name + ":setIamPolicy",
112 | options = {
113 | method: "POST",
114 | payload: JSON.stringify({
115 | policy: policyResource
116 | })
117 | };
118 | return CALL_(path, options);
119 | };
120 |
121 | /******************************************/
122 | /******************************************/
123 | selfSub.getIamPolicy = function() {
124 | var path = selfSub.resource.name + ":getIamPolicy",
125 | options = {
126 | method: "GET"
127 | };
128 | return CALL_(path, options);
129 | };
130 |
131 | /******************************************/
132 | /******************************************/
133 | selfSub.testIamPolicy = function(permissionsArray) {
134 | var path = selfSub.resource.name + ":testIamPermissions",
135 | options = {
136 | method: "POST",
137 | payload: JSON.stringify({
138 | "permissions": permissionsArray
139 | })
140 | };
141 | return CALL_(path, options);
142 | };
143 |
144 | /******************************************/
145 | /******************************************/
146 | selfSub.pull = function(maxCount, autoAck) {
147 | var autoAck = autoAck !== false,
148 | returnMessages = [],
149 | ackIds = [],
150 | maxCount = maxCount || 1,
151 | payload = {
152 | "returnImmediately": true,
153 | "maxMessages": maxCount,
154 | },
155 | path = selfSub.resource.name + ":pull",
156 | options = {
157 | method: "POST",
158 | payload: JSON.stringify(payload)
159 | },
160 | messages = CALL_(path, options).receivedMessages;
161 | if (autoAck) {
162 | for (var i in messages) {
163 | ackIds.push(messages[i].ackId);
164 | }
165 | if (ackIds.length > 0) {
166 | selfSub.ack(ackIds);
167 | }
168 | }
169 | return messages;
170 | };
171 |
172 | /******************************************/
173 | /******************************************/
174 | selfSub.modifyAckDeadline = function(ackIds, seconds) {
175 | var payload = {
176 | ackIds: ackIds,
177 | "ackDeadlineSeconds": seconds
178 | },
179 | path = selfSub.resource.name + ":modifyAckDeadline",
180 | options = {
181 | method: "POST",
182 | payload: JSON.stringify(payload)
183 | };
184 | CALL_(path, options);
185 | return selfSub;
186 | };
187 |
188 | /******************************************/
189 | /******************************************/
190 | selfSub.ack = function(ackIds) {
191 | var payload = {
192 | ackIds: ackIds
193 | },
194 | path = selfSub.resource.name + ":acknowledge",
195 | options = {
196 | method: "POST",
197 | payload: JSON.stringify(payload)
198 | };
199 | CALL_(path, options);
200 | return selfSub;
201 | };
202 | }
203 | return self_;
204 | }
--------------------------------------------------------------------------------
/src/policyBuilder.gs:
--------------------------------------------------------------------------------
1 | /*
2 | PubSubApp - policyBuilder.gs
3 |
4 | Copyright (c) 2015 Spencer Easton
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 |
19 | /********************************************
20 | * The constructor of the policyBuilder service
21 | * @return {object} The policyBuilder service
22 | *********************************************/
23 | function policyBuilder() {
24 | return new policyBuilder_();
25 | }
26 |
27 | function policyBuilder_() {
28 | var policyBuilder = this,
29 | POLICY = JSON.stringify({
30 | bindings: []
31 | }),
32 | ROLES = Object.freeze({
33 | Viewer: "roles/viewer",
34 | Editor: "roles/editor",
35 | Owner: "roles/owner",
36 | Publisher: "roles/pubsub.publisher",
37 | Subscriber: "roles/pubsub.subscriber"
38 | }),
39 | MEMBERTYPE = Object.freeze({
40 | ALLUSERS: "allAuthenticatedUsers",
41 | USER: "user:",
42 | SERVICEACCOUNT: "serviceAccount:",
43 | GROUP: "group:",
44 | DOMAIN: "domain:"
45 | });
46 |
47 |
48 | /********************************************
49 | * Creates a Policy object from an existing IAM policy resource
50 | * @param {object} policyResource The policy resource to edit
51 | * @return {object} new Policy object
52 | *********************************************/
53 | policyBuilder.editPolicy = function(policyResource) {
54 | var policyMap = {},
55 | policy = policyResource.bindings;
56 | for (var i in policy) {
57 | if (!(policy[i].role in policyMap)) {
58 | policyMap[policy[i].role] = [];
59 | }
60 | for (var ii in policy[i].members) {
61 | policyMap[policy[i].role].push(policy[i].members[ii]);
62 | }
63 | }
64 | return new Policy_(policyMap);
65 | };
66 |
67 | /********************************************
68 | * Creates a new Policy object
69 | * @return {object} new Policy object
70 | *********************************************/
71 | policyBuilder.newPolicy = function() {
72 | return new Policy_();
73 | };
74 |
75 | function Policy_(policyMap) {
76 | var policyMapper = policyMap || {};
77 | var thisPolicy = this;
78 |
79 | for (var role in ROLES) {
80 | /********************************************
81 | * Add member to policy role
82 | * @param {string} memberRole The role defined in MEMBERTYPE object
83 | * @param {string} Name The name, usually the email, of the user
84 | * @return {object} this Policy object
85 | *********************************************/
86 | thisPolicy["add" + role] = (function(myRole) {
87 | return function(memberType, Name) {
88 | addMember_(myRole, memberType.toUpperCase(), Name);
89 | return thisPolicy;
90 | };
91 | })(role);
92 |
93 | /********************************************
94 | * remove member from policy role
95 | * @param {string} Name The name, usually the email, of the user
96 | * @return {object} this Policy object
97 | *********************************************/
98 | thisPolicy["remove" + role] = (function(myRole) {
99 | return function(Name) {
100 | removeMember_(myRole, Name);
101 | return thisPolicy;
102 | };
103 | })(role);
104 |
105 | }
106 |
107 | /******************************************/
108 | /******************************************/
109 | function addMember_(role, memberType, name) {
110 | var name = name || "";
111 | if (!(ROLES[role] in policyMapper)) {
112 | policyMapper[ROLES[role]] = [];
113 | }
114 | policyMapper[ROLES[role]].push(MEMBERTYPE[memberType] + name);
115 | }
116 |
117 | /******************************************/
118 | /******************************************/
119 | function removeMember_(role, name) {
120 | var name = name || "";
121 | for (var i = 0; i < policyMapper[ROLES[role]].length; i++) {
122 | if (policyMapper[ROLES[role]][i].indexOf(name) != -1) {
123 | policyMapper[ROLES[role]].splice(i, 1);
124 | }
125 | }
126 | }
127 | /********************************************
128 | * Return this poliocy as a IAM PolicyResource
129 | * @return {object} IAM policy resource object
130 | *********************************************/
131 | thisPolicy.getPolicy = function() {
132 | var returnPolicy = JSON.parse(POLICY),
133 | members;
134 | for (var policy in policyMapper) {
135 | returnPolicy.bindings.push({
136 | role: policy,
137 | members: policyMapper[policy]
138 | });
139 | }
140 | return returnPolicy;
141 | };
142 | return thisPolicy;
143 | }
144 | return policyBuilder;
145 | }
--------------------------------------------------------------------------------