PCO API & Java

How to use the Planning Center (PCO) API with Java

by Ray Forlin

Planning Center, like many organisations today, exposes a robust API framework to enable access to the data related to your organisation. To connect to the PCO API using the Java development language, I have put together the following steps that work for me, and may help others. I found some information regarding connected to PCO using Java on the web, but it took a lot of time to determine the correct process. Hopefully this will help you.

To get started, establish your client application through the normal process at https://api.planningcenteronline.com/oauth/applications. This will generate a client id and a secret id which I suggest you store in your Java code. I also encourage you to familiarise yourself with the API documentation found at https://developer.planning.center/docs/. This will be critical as you start sending queries to the API.

The method that I have found the easiest to implement and run on an ongoing basis without issue is to use the client id and secret id and refresh_token to generate a new access_token and refresh_token each time my application starts. This may not be the method you use depending on how your application is deployed, however, this works very well in my situation.

In order to get the refresh token, you need to make a call to the PCO oauth URL as follows (replace the CLIENT_ID with your client id and the redirect_uri with your redirect uri):

https://api.planningcenteronline.com/oauth/authorize?client_id=CLIENT_ID&redirect_uri=https://example.com/auth/complete&response_type=code&scope=people

The response you get back will contain your refresh_token. For example:

{
  "access_token": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
  "token_type": "bearer",
  "expires_in": 7200,
  "refresh_token": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
  "scope": "people",
  "created_at": 1469553476
}

All of this information for making these oauth calls is available at https://developer.planning.center/docs/#/overview/authentication.

Once you have your refresh_token, paste it into a file called “refreshToken.txt”. Then use the following code to generate an access_token and a new refresh_token for next use.

private static final String BASE_URL = "https://api.planningcenteronline.com/";
private static final String CLIENT_ID = "YOUR_CLIENT_ID";
private static final String SECRET_ID = "YOUR_SECRET_ID";

private static String accessToken = null;
private static OkHttpClient okClient = new OkHttpClient();

public void refreshToken() throws Exception
{
	String refreshToken = null;
	Scanner myReader = new Scanner(new File("refreshToken.txt"));

        // read the previous refresh_token from the file
	if (myReader.hasNextLine())
	{
		refreshToken = myReader.nextLine();
	}

	myReader.close();

	System.out.println("Refresh Token to use to get new access token is: " + refreshToken);

        // make a call to generate an access_token using your refresh_token
	RequestBody formBody = new FormBody.Builder().add("grant_type", "refresh_token").add("refresh_token", refreshToken)
			.add("client_id", CLIENT_ID).add("client_secret", SECRET_ID).build();
	Request request = new Request.Builder().url("https://api.planningcenteronline.com/oauth/token").
			post(formBody).build();
	Call call = okClient.newCall(request);
	Response response = call.execute();
	JSONObject json = new JSONObject(response.body().string());
	accessToken = json.getString("access_token");
	System.out.println("New access token: " + accessToken);

        // The response also contains a refresh_token which you store int the file for next use
	String newRefreshToken = json.getString("refresh_token");
	FileWriter myWriter = new FileWriter("refreshToken.txt");
	myWriter.write(newRefreshToken);
	myWriter.close();
	System.out.println("Stored refresh token for next use");
	System.out.println("---------------------------------\n");

	json.clear();
}

HTML gets, posts, patches and deletes are then defined as follows:

public String get(String endpoint) throws IOException
{
	Request request = new Request.Builder().url(BASE_URL + endpoint).addHeader(
			"Authorization", "Bearer " + accessToken).build();

	try (Response response = okClient.newCall(request).execute())
	{
		String result = response.body().string();
		return result;
	}
}

public String post(String endpoint, JSONObject data) throws Exception
{
	String payload = data.toString();
	HttpClient client = HttpClient.newHttpClient();

	HttpRequest request = HttpRequest.newBuilder(URI.create(BASE_URL + endpoint)).header(
			"Authorization", "Bearer " + accessToken)
			.header("content-type", "application/json").POST(
					HttpRequest.BodyPublishers.ofString(payload)).build();

	HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

	String body = response.body();

	client.close();

	return body;
}

public String patch(String endpoint, JSONObject data) throws Exception
{
	String payload = data.toString();
	HttpClient client = HttpClient.newHttpClient();

	HttpRequest request = HttpRequest.newBuilder(URI.create(BASE_URL + endpoint)).header(
			"Authorization", "Bearer " + accessToken)
			.header("content-type", "application/json").method(
					"PATCH", HttpRequest.BodyPublishers.ofString(payload)).build();

	HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

	return response.body();
}

public String delete(String endpoint, JSONObject data) throws Exception
{
	String payload = data.toString();
	HttpClient client = HttpClient.newHttpClient();

	HttpRequest request = HttpRequest.newBuilder(URI.create(BASE_URL + endpoint)).
			header("Authorization", "Bearer " + accessToken)
			.header("content-type", "application/json").method("DELETE", 
					HttpRequest.BodyPublishers.ofString(payload)).build();

	HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

	return response.body();
}

An example main class would then be as follows:

public static void main(String args[])
{
	refreshToken();
	
	String query = get("people/v2/people?where[search_name_or_email]=" + 
			URLEncoder.encode("emailtosearchfor@gmail.com", "UTF-8"));
	JSONObject json = new JSONObject(query);
			
	System.out.println(json.toString(4));
}

Hopefully you find this helpful! If you have any queries about this code, leave a comment below or email me at support@church4kids.com.

Leave a Comment

Your email address will not be published. Required fields are marked *