You are here

Working with PHP and the NationBuilder API

Submitted by Nicole on August 5, 2014 - 1:43pm

Last year, NationBuilder released their API to the world, allowing applications to interact with Nations. You can find NationBuilder's API documentation here. This blog post will discuss how to create objects through the API.

The first step is understanding how the API and OAuth2 work. When working with OAuth2, the first request your client makes is to obtain an authorization token. Using that token, you can then make other requests through your application. It's important to note this two step process, as other APIs which use requests such as a RESTful or XML-RPC are generally one step processes. 

The first step is to simply include the PHP-OAuth2 library. 

  1. // Define our current directory as root
  2. define('ROOT', getcwd());
  3.  
  4. // OAuth 2 Library
  5. require_once ROOT . '/OAuth2/Client.php';
  6. require_once ROOT . '/OAuth2/GrantType/IGrantType.php';
  7. require_once ROOT . '/OAuth2/GrantType/AuthorizationCode.php';

Now we need to set up some constants for use later in the application. The CLIENT_ID and CLIENT_SECRET can be obtained from your NationBuilder control panel under the "Settings" and then the "apps" submenu. The REDIRECT_URI is where NationBuilder should return with the valid authorization token. For this application, it returns to the same file that called it. Though, it is certainly possible to redirect to another script. For the last three, replace the api-richir portion with the slug of the nation you want the application to interact with.

  1. // Client ID and Secret from Nation Builder
  2. const CLIENT_ID = 'clientid';
  3. const CLIENT_SECRET = 'secret';
  4.  
  5. // Constants we need to talk to Nation Builder
  6. const REDIRECT_URI 			= "http://archive.richiroutreach.com/NB/create_blog_post.php";
  7. const AUTHORIZATION_ENDPOINT 	= "https://api-richir.nationbuilder.com/oauth/authorize";
  8. const TOKEN_ENDPOINT 		= "https://api-richir.nationbuilder.com/oauth/token";
  9. const REQUEST_ENDPOINT 		= "https://api-richir.nationbuilder.com/api/v1";

Next, we need to request an authorization code. The first time you run this script, it should take you to your NationBuilder control panel to authorize this app. NationBuilder will go to whatever you have set as the OAuth Callback URL when you authorize the app. In this case, it's the same file that called the script.

  1. // Check if we have an authorize code, if not obtain one
  2. if (!isset($_GET['code'])) {
  3. 	// Generate the URL we need to go to get the token
  4. 	$auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT, REDIRECT_URI);
  5.  
  6. 	// Redirect to that URL (which then sends us back to the REDIRECT_URI with a code, IE this page)
  7. 	header('Location: ' . $auth_url);
  8.  
  9. 	// End this process
  10. 	die('Redirect');
  11. }

The next step is to request an access token. We should only get this far if we have an authorization code. Note that we need to set our token type in order for create requests to work.

  1. // We have a code, so generate the parameters we need to get an access token
  2. $params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
  3.  
  4. // Obtain our access token
  5. $response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', $params);
  6.  
  7. // See if we got a valid token back or an error
  8. if (isset($response['result']['error'])) {
  9. 	switch($response['result']['error']) {
  10. 		case 'invalid_grant':
  11.  			$error = "<b>ERROR</b>: Invalid Grant. This code is invalid, expired, or revoked.<br>";
  12. 			break;
  13.  
  14. 		default:
  15. 			$error = "<b>Unknown error:</b> " . $response['result']['error'] . " - " 
  16. 				. $response['result']['error_description'] . "<br>";
  17. 			break;
  18. 	}
  19.  
  20. 	// End execution and display error message.
  21. 	die($error);
  22. }
  23.  
  24. // Parse out the token from the response 
  25. $token = $response['result']['access_token'];
  26.  
  27. // Set our token type (ACCESS_TOKEN_BEARER)
  28. $client->setAccessTokenType(1);
  29.  
  30. // Set our token
  31. $client->setAccessToken($token);

In order to make a create request, we need to set up some HTML headers so that NationBuilder knows what data to expect. The header also includes our authorization token.

  1. // Set the headers for the request
  2. $header = array(
  3. 	'Authorization' => $token,
  4. 	'Content-Type' => 'application/json', 
  5. 	'Accept' => 'application/json'
  6. 	);

Finally, make our request! This example makes a blog post to the blog with the ID of 123. Alter the request to be whatever you need.

  1. $params = array(
  2. 	"blog_post" => array(
  3. 			"name" => "Testing API",
  4. 			"slug" => "blog_test_api",
  5. 			"status" => "published",
  6. 			"content_before_flip" => "<p>Before the flip</p>",
  7. 			"content_after_flip" => "<p>After the flip</p>",
  8. 			"tags" => "test_tag_1, test_tag_2",
  9. 			"published_at" => "2014-01-01T1012:00:00-07:00",
  10. 		),
  11. 	);
  12.  
  13. // Send our request to the create blog post endpoint for blog #123
  14. $response = $client->fetch(REQUEST_ENDPOINT . "/sites/api/pages/blogs/123/posts", $token, $params, "POST", $header);
  15.  
  16. echo"<hr><h2>Response:</h2>";
  17. print_r($response);

Note: At the moment, this script will create a new app in the NationBuilder back end every time it's executed.

Full Source to create 10 blog posts:

  1. define('ROOT', getcwd());
  2.  
  3. // Useful Functions
  4. require_once "toolbox.php";
  5.  
  6. // OAuth 2 Library
  7. require_once ROOT . '/OAuth2/Client.php';
  8. require_once ROOT . '/OAuth2/GrantType/IGrantType.php';
  9. require_once ROOT . '/OAuth2/GrantType/AuthorizationCode.php';
  10.  
  11. // Client ID and Secret from Nation Builder
  12. const CLIENT_ID	= 'id';
  13. const CLIENT_SECRET	= 'secret';
  14.  
  15. // Constants we need to talk to Nation Builder
  16. const REDIRECT_URI 			= "http://archive.richiroutreach.com/NB/create_blog_post.php";
  17. const AUTHORIZATION_ENDPOINT	= "https://api-richir.nationbuilder.com/oauth/authorize";
  18. const TOKEN_ENDPOINT		= "https://api-richir.nationbuilder.com/oauth/token";
  19. const REQUEST_ENDPOINT		= "https://api-richir.nationbuilder.com/api/v1";
  20.  
  21. // Start a new OAuth2 Client
  22. $client = new OAuth2\Client(CLIENT_ID, CLIENT_SECRET);
  23.  
  24. // Check if we have an authorize code, if not obtain one
  25. if (!isset($_GET['code'])) {
  26.  
  27. 	// Generate the URL we need to go to get the token
  28. 	$auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT, REDIRECT_URI);
  29.  
  30. 	// Redirect to that URL (which then sends us back to the REDIRECT_URI with a code, IE this page)
  31. 	header('Location: ' . $auth_url);
  32.  
  33. 	// End this process
  34. 	die('Redirect');
  35. }
  36.  
  37. // We have a code, so generate the parameters we need to get an access token
  38. $params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
  39.  
  40. // Obtain our access token
  41. $response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', $params);
  42.  
  43. // See if we got a valid token back or an error
  44. if (isset($response['result']['error'])) {
  45. 	switch($response['result']['error']) {
  46. 		case 'invalid_grant':
  47. 			// We can just redirect back to the URI to get a new code in this case. 
  48. 			//NOT RECOMMENDED FOR PRODUCTION USE. 
  49. 			header('Location: ' . REDIRECT_URI);
  50.  
  51.  			$error = "<b>ERROR</b>: Invalid Grant. This code is invalid, expired, or revoked.<br>";
  52. 			break;
  53.  
  54. 		default:
  55. 			$error = "<b>Unknown error:</b> " . $response['result']['error'] . " - " . 
  56. 				$response['result']['error_description'] . "<br>";
  57. 			break;
  58. 	}
  59.  
  60. 	// End execution and display error message.
  61. 	die($error);
  62. }
  63.  
  64. // Parse out the token from the response 
  65. $token = $response['result']['access_token'];
  66.  
  67. // Set our token type (ACCESS_TOKEN_BEARER)
  68. $client->setAccessTokenType(1);
  69.  
  70. // Set our token
  71. $client->setAccessToken($token);
  72.  
  73. // Set the headers for the request
  74. $header = array(
  75. 	'Authorization' => $token,
  76. 	'Content-Type' => 'application/json', 
  77. 	'Accept' => 'application/json'
  78. 	);
  79.  
  80.  
  81. for($i = 1; $i < 11; $i++) {
  82. 	// Set the parameters of our request
  83. 	$params = array(
  84. 		"blog_post" => array(
  85. 				"name" => "Testing API - " . ($i + 1),
  86. 				"slug" => "blog_test_" . ($i + 1),
  87. 				"status" => "published",
  88. 				"content_before_flip" => "<p>Before the flip</p>",
  89. 				"content_after_flip" => "<p>After the flip</p>",
  90. 				"tags" => "test_tag_" . ($i + 1) . ", test_tag_" . ($i - 1),
  91. 				"published_at" => "2014-01-01T1012:00:00-07:00",
  92. 			),
  93. 		);
  94.  
  95. 	// Send our request to the create blog post endpoint for blog #123
  96. 	$response = $client->fetch(REQUEST_ENDPOINT . "/sites/api/pages/blogs/123/posts",
  97. 		json_encode($params), "POST", $header);
  98.  
  99. 	echo"<hr><h2>Response:</h2>";
  100. 	print_r($response);
  101. }