
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
pco_api
is a Rubygem that provides a simple wrapper around our RESTful JSON API at https://api.planningcenteronline.com.
gem install pco_api
Create a new API object, passing in your credentials (either HTTP Basic or OAuth2 access token):
# authenticate with HTTP Basic:
api = PCO::API.new(basic_auth_token: 'token', basic_auth_secret: 'secret')
# ...or authenticate with an OAuth2 access token (use the 'oauth2' gem to obtain the token)
api = PCO::API.new(oauth_access_token: 'token')
Chain path elements together as method calls.
api.people.v2.households
# /people/v2/households
For IDs, treat the object like a hash (use square brackets).
api.people.v2.households[1]
# /people/v2/households/1
To execute the request, use get
, post
, patch
, or delete
, optionally passing arguments.
api.people.v2.households.get(order: 'name')
# GET /people/v2/households?order=name
To query dataset according to can_query_by
variables:
api.people.v2.people.get('where[membership]': 'Member')
# GET /people/v2/people?where[membership]=Member
require 'pco_api'
api = PCO::API.new(basic_auth_token: 'token', basic_auth_secret: 'secret')
api.people.v2.people.get(order: 'last_name')
...which returns something like:
{
"links" => {
"self" => "https://api.planningcenteronline.com/people/v2/people?order=last_name",
"next" => "https://api.planningcenteronline.com/people/v2/people?offset=25&order=last_name"
},
"data"=> [
{
"type" => "Person",
"id" => "271",
"attributes" => {
"first_name" => "Jean",
"middle_name" => nil,
"last_name" => "Abernathy",
"birthdate" => "1885-01-01",
"anniversary" => nil,
"gender" => "F",
"grade" => -1,
"child" => false,
"status" => "active",
"school_type" => nil,
"graduation_year" => nil,
"site_administrator" => false,
"people_permissions" => nil,
"created_at" => "2015-04-01T20:18:22Z",
"updated_at" => "2015-04-10T18:59:51Z",
"avatar" => nil,
},
"links" => {
"self" => "https://api.planningcenteronline.com/people/v2/people/271"
}
},
# ...
],
"meta" => {
"total_count" => 409,
"count" => 25,
"next" => {
"offset" => 25
},
"can_order_by" => [
"first_name",
"middle_name",
"last_name",
"birthdate",
"anniversary",
"gender",
"grade",
"child",
"status",
"school_type",
"graduation_year",
"site_administrator",
"people_permissions",
"created_at",
"updated_at"
],
"can_query_by" => [
"first_name",
"middle_name",
"last_name",
"birthdate",
"anniversary",
"gender",
"grade",
"child",
"status",
"school_type",
"graduation_year",
"site_administrator",
"people_permissions",
"created_at",
"updated_at"
],
"can_include" => [
"emails",
"addresses",
"phone_numbers",
"households",
"school",
"inactive_reason",
"marital_status",
"name_prefix",
"name_suffix",
"field_data",
"apps"
],
"parent" => {
"id" => "1",
"type" => "Organization"
}
}
}
get()
works for a collection (index) and a single resource (show).
# collection
api.people.v2.people.get(order: 'last_name')
# => { data: array_of_resources }
# single resource
api.people.v2.people[1].get
# => { data: resource_hash }
post()
sends a POST request to create a new resource. You must wrap your resource with
a { data: { ... } }
hash.
api.people.v2.people.post(data: { type: 'Person', attributes: { first_name: 'Tim', last_name: 'Morgan' } })
# => { data: resource_hash }
patch()
sends a PATCH request to update an existing resource. You must wrap your resource with
a { data: { ... } }
hash.
api.people.v2.people[1].patch(data: { type: 'Person', id: 1, attributes: { first_name: 'Tim', last_name: 'Morgan' } })
# => { data: resource_hash }
delete()
sends a DELETE request to delete an existing resource. This method returns true
if the delete was successful.
api.people.v2.people[1].delete
# => true
The following errors may be raised by the library, depending on the API response status code.
HTTP Status Codes | Error Class |
---|---|
400 | PCO::API::Errors::BadRequest < PCO::API::Errors::ClientError |
401 | PCO::API::Errors::Unauthorized < PCO::API::Errors::ClientError |
403 | PCO::API::Errors::Forbidden < PCO::API::Errors::ClientError |
404 | PCO::API::Errors::NotFound < PCO::API::Errors::ClientError |
405 | PCO::API::Errors::MethodNotAllowed < PCO::API::Errors::ClientError |
422 | PCO::API::Errors::UnprocessableEntity < PCO::API::Errors::ClientError |
429 | PCO::API::Errors::TooManyRequests < PCO::API::Errors::ClientError |
other 4xx errors | PCO::API::Errors::ClientError |
500 | PCO::API::Errors::InternalServerError < PCO::API::Errors::ServerError |
other 5xx errors | PCO::API::Errors::ServerError |
The exception object has the following methods:
Method | Content |
---|---|
status | HTTP status code returned by the server |
message | the message returned by the API |
detail | the full error response returned by the API |
headers | hash of HTTP headers returned by the API |
The message
should be a simple string given by the API, e.g. "Resource Not Found".
In the case of validation errors, the message
is a summary string built from the raw detail
.
Alternatively, you may rescue PCO::API::Errors::BaseError
and branch your code based on
the status code returned by calling error.status
.
By default, PCO::API::Endpoint will sleep and retry a request that fails with TooManyRequests due to rate limiting. If you would rather catch and handle such errors yourself, you can disable this behavior like this:
api = PCO::API.new(...)
api.retry_when_rate_limited = false
Copyright Ministry Centered Technologies. Licensed MIT.
FAQs
Unknown package
We found that pco_api demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.