Professional Documents
Culture Documents
Cloud Code Guide - Parse
Cloud Code Guide - Parse
Cloud Code
Guide Browse
Getting Started
Getting Started
Cloud Code is built into Parse Server. The default
entry point for your Cloud Code is at ./cloud/main.js .
https://docs.parseplatform.org/cloudcode/guide/ 1/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Cloud Functions
Let’s look at a slightly more complex example where
Cloud Code is useful. One reason to do computation in
the cloud is so that you don’t have to send a huge list of
objects down to a device if you only want a little bit of
information. For example, let’s say you’re writing an app
that lets people review movies. A single Review object
could look like:
{ 📋
"movie": "The Matrix",
"stars": 5,
"comment": "Too bad they never made any
sequels."
}
Parse.Cloud.define("averageStars", async 📋
(request) => {
const query = new Parse.Query("Review");
query.equalTo("movie",
request.params.movie);
const results = await query.find();
let sum = 0;
for (let i = 0; i < results.length; ++i) {
sum += results[i].get("stars");
}
https://docs.parseplatform.org/cloudcode/guide/ 2/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
// Objective-C 📋
[PFCloud
callFunctionInBackground:@"averageStars"
withParameters:@{@"movie":
@"The Matrix"}
block:^(NSNumber
*ratings, NSError *error) {
if (!error) {
// ratings is 4.5
}
}];
// Swift 📋
PFCloud.callFunction(inBackground:
"averageRatings", withParameters:
["movie":"The Matrix"]) {
(response, error) in
let ratings = response as? Float
https://docs.parseplatform.org/cloudcode/guide/ 3/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
// ratings is 4.5
}
$ratings = ParseCloud::run("averageRatings", 📋
["movie" => "The Matrix"]);
// $ratings is 4.5
You can also call Cloud functions using the REST API:
curl -X POST \ 📋
-H "X-Parse-Application-Id:
${APPLICATION_ID}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-H "Content-Type: application/json" \
-d '{ "movie": "The Matrix" }' \
https://YOUR.PARSE-
SERVER.HERE/parse/functions/averageStars
https://docs.parseplatform.org/cloudcode/guide/ 4/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.run("averageStars", params);
// ratings should be 4.5
{ "result": 4.8 } 📋
{ 📋
"code": 141,
"error": "movie lookup failed"
}
https://docs.parseplatform.org/cloudcode/guide/ 5/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.define("averageStars", async 📋
(request) => {
const query = new Parse.Query("Review");
query.equalTo("movie",
request.params.movie);
const results = await query.find();
let sum = 0;
for (let i = 0; i < results.length; ++i) {
sum += results[i].get("stars");
}
return sum / results.length;
},{
fields : ['movie'],
requireUser: true
});
Parse.Cloud.define("averageStars", async 📋
(request) => {
const query = new Parse.Query("Review");
query.equalTo("movie",
request.params.movie);
const results = await query.find();
let sum = 0;
for (let i = 0; i < results.length; ++i) {
sum += results[i].get("stars");
}
return sum / results.length;
},{
https://docs.parseplatform.org/cloudcode/guide/ 6/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
fields : {
movie : {
required: true,
type: String,
options: val => {
return val.length < 20;
},
error: "Movie must be less than 20
characters"
}
},
requireUserKeys: {
accType : {
options: 'reviewer',
error: 'Only reviewers can get average
stars'
}
}
});
request.params.movie is defined
request.params.movie is a String
request.user is defined
request.user.get('accType') is defined
request.user.get('accType') is equal to
‘reviewer’
Parse.Cloud.beforeSave(Parse.User, () => { 📋
// any additional beforeSave logic here
}, {
fields: {
accType: {
https://docs.parseplatform.org/cloudcode/guide/ 7/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
default: 'viewer',
constant: true
},
},
});
https://docs.parseplatform.org/cloudcode/guide/ 8/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.define('adminFunctionTwo', request
=> {
// do admin code here, confident that
request.user.id is masterUser, or masterKey is
provided
},validationRules)
CONSIDERATIONS
Cloud Jobs
https://docs.parseplatform.org/cloudcode/guide/ 9/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Define a Job
Running a Job
Calling jobs is done via the REST API and is protected
by the master key.
📋
curl -X POST -H 'X-Parse-Application-Id: appId'
-H 'X-Parse-Master-Key: masterKey' https://my-
parse-server.com/parse/jobs/myJob
You can pass some data alongside the call if you want
to customize the job execution.
Scheduling a Job
We don’t support at the moment job scheduling and
highly recommend to use a 3rd party system for
scheduling your jobs.
https://docs.parseplatform.org/cloudcode/guide/ 10/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
On Heroku
Viewing Jobs
Viewing jobs is supported on parse-dashboard starting
version 1.0.19, but you can also query the _JobStatus
class with a masterKey call to fetch your recent jobs.
Save Triggers
beforeSave
IMPLEMENTING DATA VALIDATION
https://docs.parseplatform.org/cloudcode/guide/ 11/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
One useful tip is that even if your mobile app has many
different versions, the same version of Cloud Code
applies to all of them. Thus, if you launch an application
that doesn’t correctly check the validity of input data,
you can still fix this problem by adding a validation with
beforeSave .
PREDEFINED CLASSES
Parse.Cloud.beforeSave(Parse.User, async 📋
(request) => {
// code here
},
https://docs.parseplatform.org/cloudcode/guide/ 12/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
// Validation Object or Validation Function
)
afterSave
In some cases, you may want to perform some action,
such as a push, after an object has been saved. You can
do this by registering a handler with the afterSave
method. For example, suppose you want to keep track
of the number of comments on a blog post. You can do
that by writing a function like this:
ASYNC BEHAVIOR
PREDEFINED CLASSES
https://docs.parseplatform.org/cloudcode/guide/ 13/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.afterSave(Parse.User, async 📋
(request) => {
// code here
})
Context
When saving a Parse.Object you may pass a context
dictionary that is accessible in the Cloud Code Save
Triggers. More info in the JavaScript Guide.
📋
const beforeSave = function beforeSave(request )
{
const { object: role } = request;
// Get users that will be added to the users
relation.
const usersOp = role.op('users');
if (usersOp && usersOp.relationsToAdd.length
> 0) {
// add the users being added to the request
context
request.context = { buyers:
usersOp.relationsToAdd };
}
};
https://docs.parseplatform.org/cloudcode/guide/ 14/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
context.buyers.length);
promises.push(item.save(null, {
useMasterKey: true }));
Promise.all(promises).catch(request.log.error.bin
}
};
Delete Triggers
beforeDelete
You can run custom Cloud Code before an object is
deleted. You can do this with the beforeDelete
method. For instance, this can be used to implement a
restricted delete policy that is more sophisticated than
what can be expressed through ACLs. For example,
suppose you have a photo album app, where many
photos are associated with each album, and you want
to prevent the user from deleting an album if it still has
a photo in it. You can do that by writing a function like
this:
Parse.Cloud.beforeDelete("Album", async 📋
(request) => {
const query = new Parse.Query("Photo");
query.equalTo("album", request.object);
const count = await
query.count({useMasterKey:true})
if (count > 0) {
throw "Can't delete album if it still has
photos.";
}
});
PREDEFINED CLASSES
https://docs.parseplatform.org/cloudcode/guide/ 15/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.beforeDelete(Parse.User, async 📋
(request) => {
// code here
})
afterDelete
In some cases, you may want to perform some action,
such as a push, after an object has been deleted. You
can do this by registering a handler with the
afterDelete method. For example, suppose that after
deleting a blog post, you also want to delete all
associated comments. You can do that by writing a
function like this:
PREDEFINED CLASSES
https://docs.parseplatform.org/cloudcode/guide/ 16/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.afterDelete(Parse.User, async 📋
(request) => {
// code here
})
File Triggers
beforeSaveFile
With the beforeSaveFile method you can run custom
Cloud Code before any file is saved. Returning a new
Parse.File will save the new file instead of the one
sent by the client.
EXAMPLES
https://docs.parseplatform.org/cloudcode/guide/ 17/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
return newFile;
});
afterSaveFile
The afterSaveFile method is a great way to keep
track of all of the files stored in your app. For example:
beforeDeleteFile
You can run custom Cloud Code before any file gets
deleted. For example, lets say you want to add logic
that only allows files to be deleted by the user who
https://docs.parseplatform.org/cloudcode/guide/ 18/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.beforeDeleteFile(async (request)
=> {
const { file, user } = request;
const query = new Parse.Query('FileObject');
query.equalTo('fileName', file.name());
const fileObject = await query.first({
useMasterKey: true });
if (fileObject.get('createdBy').id !==
user.id) {
throw 'You do not have permission to delete
this file';
}
});
afterDeleteFile
In the above beforeDeleteFile example the
FileObject collection is used to keep track of saved
files in your app. The afterDeleteFile trigger is a
good place to clean up these objects once a file has
been successfully deleted.
📋
Parse.Cloud.afterDeleteFile(async (request) =>
{
const { file } = request;
const query = new Parse.Query('FileObject');
query.equalTo('fileName', file.name());
const fileObject = await query.first({
useMasterKey: true });
await fileObject.destroy({ useMasterKey:
https://docs.parseplatform.org/cloudcode/guide/ 19/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
true });
});
Find Triggers
beforeFind
Available only on parse-server cloud code starting
2.2.20
EXAMPLES
// Properties available 📋
Parse.Cloud.beforeFind('MyObject', (req) => {
let query = req.query; // the Parse.Query
let user = req.user; // the user
let triggerName = req.triggerName; //
beforeFind
let isMaster = req.master; // if the query is
run with masterKey
let isCount = req.count; // if the query is a
count operation (available on parse-server
2.4.0 or up)
let logger = req.log; // the logger
let installationId = req.installationId; //
The installationId
});
// Selecting keys
Parse.Cloud.beforeFind('MyObject', (req) => {
let query = req.query; // the Parse.Query
// Force the selection on some keys
query.select(['key1', 'key2']);
});
// Asynchronous support
Parse.Cloud.beforeFind('MyObject', (req) => {
let query = req.query;
return aPromise().then((results) => {
// do something with the results
query.containedIn('key', results);
});
});
// Rejecting a query
Parse.Cloud.beforeFind('MyObject', (req) => {
// throw an error
throw new Parse.Error(101, 'error');
// rejecting promise
return Promise.reject('error');
});
PREDEFINED CLASSES
Parse.Cloud.beforeFind(Parse.User, async 📋
(request) => {
// code here
})
afterFind
Available only on parse-server cloud code starting
2.2.25
Parse.Cloud.afterFind('MyCustomClass', async 📋
(request) => {
https://docs.parseplatform.org/cloudcode/guide/ 21/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
// code here
})
PREDEFINED CLASSES
Parse.Cloud.afterFind(Parse.User, async 📋
(request) => {
// code here
})
Session Triggers
beforeLogin
Available only on parse-server cloud code starting 3.3.0
CONSIDERATIONS
https://docs.parseplatform.org/cloudcode/guide/ 22/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
THE TRIGGER WILL RUN…
On authProvider logins
On sign up
afterLogout
Available only on parse-server cloud code starting
3.10.0
CONSIDERATIONS
https://docs.parseplatform.org/cloudcode/guide/ 23/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
LiveQuery Triggers
beforeConnect
Available only on parse-server cloud code starting 4.3.0
Parse.Cloud.beforeConnect(request => { 📋
if (!request.user) {
throw "Please login before you attempt to
connect."
}
});
beforeSubscribe
Available only on parse-server cloud code starting 4.3.0
https://docs.parseplatform.org/cloudcode/guide/ 24/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.beforeSubscribe('MyObject', 📋
request => {
if (!request.user.get('Admin')) {
throw new Parse.Error(101, 'You are not
authorized to subscribe to MyObject.');
}
let query = request.query; // the
Parse.Query
query.select("name","year")
});
afterLiveQueryEvent
Available only on parse-server cloud code starting 4.4.0
EXAMPLES
https://docs.parseplatform.org/cloudcode/guide/ 25/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
CONSIDERATIONS
onLiveQueryEvent
Available only on parse-server cloud code starting 2.6.2
https://docs.parseplatform.org/cloudcode/guide/ 26/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.onLiveQueryEvent(({ 📋
event,
client,
sessionToken,
useMasterKey,
installationId,
clients,
subscriptions,
error
}) => {
if (event !== 'ws_disconnect') {
return;
}
// Do your magic
});
Events
connect
subscribe
unsubscribe
ws_connect
ws_disconnect
ws_disconnect_error
https://docs.parseplatform.org/cloudcode/guide/ 27/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Security
Master Key
To override object and class access permissions, you
can set useMasterKey: true if the request accepts the
master key option.
EXAMPLES
Parse.Object.saveAll(objects, { useMasterKey:📋
true });
CONSIDERATIONS
Networking
httpRequest
You can use your favorite npm module to make HTTP
requests, such as axios. Parse Server also supports
Parse.Cloud.httpRequest for legacy reasons. It allows
you to send HTTP requests to any HTTP Server. This
function takes an options object to configure the call.
https://docs.parseplatform.org/cloudcode/guide/ 28/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.httpRequest({ 📋
url: 'https://www.awesomewebsite.com/'
}).then(function(httpResponse) {
// success
console.log(httpResponse.text);
},function(httpResponse) {
// error
console.error('Request failed with response
code ' + httpResponse.status);
});
Parse.Cloud.httpRequest({ 📋
url: 'https://www.awesomewebsite.com:8080/'
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
Valid port numbers are 80, 443, and all numbers from
1025 through 65535.
Parse.Cloud.httpRequest({ 📋
url: 'https://www.awesomewebsite.com/',
followRedirects: true
}).then(function(httpResponse) {
https://docs.parseplatform.org/cloudcode/guide/ 29/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
QUERY PARAMETERS
Parse.Cloud.httpRequest({ 📋
url: 'http://www.google.com/search',
params: {
q : 'Sean Plott'
}
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
Parse.Cloud.httpRequest({ 📋
url: 'http://www.google.com/search',
params: 'q=Sean Plott'
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
SETTING HEADERS
https://docs.parseplatform.org/cloudcode/guide/ 30/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
Parse.Cloud.httpRequest({ 📋
url: 'http://www.example.com/',
headers: {
'Content-Type':
'application/json;charset=utf-8'
}
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
Parse.Cloud.httpRequest({ 📋
method: 'POST',
url: 'http://www.example.com/create_post',
body: {
title: 'Vote for Pedro',
body: 'If you vote for Pedro, your wildest
dreams will come true'
}
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
Parse.Cloud.httpRequest({ 📋
method: 'POST',
url: 'http://www.example.com/create_post',
https://docs.parseplatform.org/cloudcode/guide/ 31/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
headers: {
'Content-Type':
'application/json;charset=utf-8'
},
body: {
title: 'Vote for Pedro',
body: 'If you vote for Pedro, your wildest
dreams will come true'
}
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
FOLLOWING REDIRECTS
Parse.Cloud.httpRequest({ 📋
url: 'http://www.example.com/',
followRedirects: true
}).then(function(httpResponse) {
console.log(httpResponse.text);
}, function(httpResponse) {
console.error('Request failed with response
code ' + httpResponse.status);
});
https://docs.parseplatform.org/cloudcode/guide/ 32/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
https://docs.parseplatform.org/cloudcode/guide/ 33/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
def index
# Ensure the request is authorized. You can
find this key on your app's settings page
# and you should ALWAYS validate it in your
request.
if request.headers['X-Parse-Webhook-Key'] !==
@webhook_key
return render :json => { :error => "Request
Unauthorized"}
end
// Sent to webhook 📋
{
https://docs.parseplatform.org/cloudcode/guide/ 34/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
"master": false,
"user": {
"createdAt": "2015-03-24T20:19:00.542Z",
"objectId": "lValKpphWN",
"sessionToken":
"orU3ClA7sqMIN8g4KtmLe7eDM",
"updatedAt": "2015-03-24T20:19:00.542Z",
"username": "Matt"
},
"installationId": "b3ab24c6-2282-69fa-eeea-
c1b36ea497c2",
"params": {},
"functionName": "helloWorld"
}
Once the webhook is set, you can call it from any of our
SDKs or from the REST API, the same way you would a
normal Cloud function.
def index
# Ensure the request is validated
if request.headers['X-Parse-Webhook-Key'] !==
@webhook_key
return render :json => { :error => "Request
Unauthorized"}
end
// Sent to webhook 📋
{
"master": true,
"installationId": "b3ab24c6-2282-69fa-eeea-
c1b36ea497c2",
"params": { "userObjectId": "6eaI2sTgH6" },
"functionName": "chargeCustomer"
}
https://docs.parseplatform.org/cloudcode/guide/ 36/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
beforeSave Webhooks
Let’s write a beforeSave trigger to truncate movie
review comments that are more than 140 characters
long using our own Rails server and a webhook.
triggerName: “beforeSave”
{ 📋
"className": "AwesomeClass",
"existingColumn": "sneakyChange",
"newColumn": "sneakyAddition"
}
https://docs.parseplatform.org/cloudcode/guide/ 37/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
def reviews
if request.headers['X-Parse-Webhook-Key'] !=
@webhook_key
return render :json => { :error => "Request
Unauthorized"}
end
review = params[:object]
if params[:triggerName] == "beforeSave" &&
review["className"] == "Review"
# truncate the object and return the new
data
if review["comment"].length > 140
review["comment"] =
review["comment"].truncate(140)
return render :json => { :success =>
review }
end
// Sent to webhook 📋
{
"master": false,
"user": {
"createdAt": "2015-03-24T20:19:00.542Z",
"objectId": "lValKpphWN",
"sessionToken":
"orU3ClA7sqMIN8g4KtmLe7eDM",
"updatedAt": "2015-03-24T20:19:00.542Z",
"username": "Matt"
},
"installationId": "b3ab24c6-2282-69fa-eeea-
https://docs.parseplatform.org/cloudcode/guide/ 38/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
c1b36ea497c2",
"triggerName": "beforeSave",
"object": {
"className": "Comment",
"comment": "A very long comment that will
be truncated to be just 140 characters. I sure
love using Parse, it's just so easy to get
started :)! Hopefully that part doesn't get
truncated :/"
}
}
afterSave Webhooks
Like we’ve seen in Cloud Code, it’s also possible to run
some code after an object has been saved using a
webhook. The parameters sent to your webhook are
the same as for beforeSave triggers but we’ll repeat
them here for clarity.
triggerName: “afterSave”
https://docs.parseplatform.org/cloudcode/guide/ 39/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
def comments
if request.headers['X-Parse-Webhook-Key'] !=
@webhook_key
return render :nothing => true
end
comment = params[:object]
if params[:triggerName] == "afterSave" &&
comment["className"] == "Comment"
post = comment["post"]
@post_model = Post.where("id = #
{post["objectId"]}")
@post_model.increment(:comments_count, 1)
@post_model.save!
return render :nothing => true
end
// Sent to webhook 📋
{
"master": false,
"user": {
"createdAt": "2015-03-24T20:19:00.542Z",
"objectId": "lValKpphWN",
"sessionToken":
"orU3ClA7sqMIN8g4KtmLe7eDM",
"updatedAt": "2015-03-24T20:19:00.542Z",
"username": "Matt"
},
"installationId": "b3ab24c6-2282-69fa-eeea-
c1b36ea497c2",
"triggerName": "afterSave",
https://docs.parseplatform.org/cloudcode/guide/ 40/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
"object": {
"objectId": "zPnDyvj0vd",
"className": "Comment",
"createdAt": "2015-03-25T00:00:57.055Z",
"updatedAt": "2015-03-25T00:00:57.055Z",
"post": {
"__type": "Pointer",
"className": "Post",
"objectId": "jsUd72Sd2l"
}
}
}
beforeDelete Webhooks
You also use webhooks for beforeDelete triggers. The
parameters sent to your webhook are the same as for
beforeSave and afterSave triggers but we’ll repeat
them here for clarity.
triggerName: “beforeDelete”
https://docs.parseplatform.org/cloudcode/guide/ 41/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
def posts
if request.headers['X-Parse-Webhook-Key'] !=
@webhook_key
return render :json => { :error => "Request
Unauthorized"}
end
post = params[:object]
if (params[:triggerName] == "beforeDelete" ||
params[:triggerName] == "beforeSave") &&
post["className"] == "Post"
@user = User.find(post['user'])
if !@user.paid_up
return render :json => { :error => "You
have outstanding charges on your account.
Please update your credit card information
before proceeding." }
end
// Sent to webhook 📋
{
"master": false,
"user": {
"createdAt": "2015-03-24T20:19:00.542Z",
"objectId": "lValKpphWN",
"sessionToken":
"orU3ClA7sqMIN8g4KtmLe7eDM",
"updatedAt": "2015-03-24T20:19:00.542Z",
"username": "Matt"
},
"installationId": "b3ab24c6-2282-69fa-eeea-
c1b36ea497c2",
"triggerName": "beforeDelete",
"object": {
"objectId": "jsUd72Sd2l",
https://docs.parseplatform.org/cloudcode/guide/ 42/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
"className": "Post",
"createdAt": "2015-03-25T00:00:57.055Z",
"updatedAt": "2015-03-25T00:00:57.055Z"
}
}
afterDelete Webhooks
The afterDelete trigger is also accessible via
webhooks. The parameters sent to your webhook are
the same as for other triggers but we’ll repeat them
here for clarity.
triggerName: “afterDelete”
https://docs.parseplatform.org/cloudcode/guide/ 43/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
def comments
if request.headers['X-Parse-Webhook-Key'] !=
@webhook_key
return render :nothing => true
end
comment = params[:object]
if params[:triggerName] == "afterDelete" &&
comment["className"] == "Comment"
@post_model = Post.where("id = #
{comment['post']}")
@post_model.decrement(:comments_count, 1)
@post_model.save!
return render :nothing => true
end
// Sent to webhook 📋
{
"master": false,
"user": {
"createdAt": "2015-03-24T20:19:00.542Z",
"objectId": "lValKpphWN",
"sessionToken":
"orU3ClA7sqMIN8g4KtmLe7eDM",
"updatedAt": "2015-03-24T20:19:00.542Z",
"username": "Matt"
},
"installationId": "b3ab24c6-2282-69fa-eeea-
c1b36ea497c2",
"triggerName": "afterDelete",
"object": {
"objectId": "zPnDyvj0vd",
"className": "Comment",
"createdAt": "2015-03-25T00:00:57.055Z",
"updatedAt": "2015-03-25T00:00:57.055Z",
"post": {
"__type": "Pointer",
"className": "Post",
https://docs.parseplatform.org/cloudcode/guide/ 44/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
"objectId": "jsUd72Sd2l"
}
}
}
Config
Parse Config offers a convenient way to configure
parameters in Cloud Code.
https://docs.parseplatform.org/cloudcode/guide/ 45/46
1/23/23, 9:26 AM Cloud Code Guide | Parse
https://docs.parseplatform.org/cloudcode/guide/ 46/46