-
-
Save kevev22/74c72e56c0829d47a29c to your computer and use it in GitHub Desktop.
NationBuilder API Usage Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This Gist shows an example of how we would call the NationBuilder API to: | |
- Create an event | |
- Update an event | |
- Create a person | |
- Update a person | |
- Delete a person | |
EventService and PersonService are the classes that actually make the calls to the API. They inherit from Service. | |
PersonSamples and EventSamples call the Service classes to make the changes to the data. | |
The following classes are serialized to create the JSON requests for events: | |
- Event | |
- EventContact | |
- EventContainer | |
- EventRsvpForm | |
- EventVenue | |
- EventVenueAddress | |
The following classes are serialized to create the JSON requests for people: | |
- Person | |
- PersonContainer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class Event | |
{ | |
private int? _timeZoneOffset = (int) TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalHours; | |
[JsonIgnore] | |
public TimeZone TimeZone | |
{ | |
set { _timeZoneOffset = (int) value.GetUtcOffset(DateTime.Now).TotalHours; } | |
} | |
[JsonProperty("id", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public int? Id { get; set; } | |
[JsonProperty("status")] | |
public string Status { get; set; } | |
[JsonProperty("name")] | |
public string Name { get; set; } | |
[JsonProperty("headline")] | |
public string Headline { get; set; } | |
[JsonProperty("title")] | |
public string Title { get; set; } | |
[JsonProperty("intro")] | |
public string Intro { get; set; } | |
[JsonProperty("time_zone")] | |
public string TimeZoneDisplay | |
{ | |
get { return _timeZoneOffset != null ? _timeZoneOffset.Value.ToString("+00;-00") : null; } | |
} | |
[JsonProperty("start_time")] | |
public DateTime? StartTime { get; set; } | |
[JsonProperty("end_time")] | |
public DateTime? EndTime { get; set; } | |
[JsonProperty("contact")] | |
public EventContact Contact { get; set; } | |
[JsonProperty("rsvp_form")] | |
public EventRsvpForm RsvpForm { get; set; } | |
[JsonProperty("show_guests")] | |
public bool? ShowGuests { get; set; } | |
[JsonProperty("capacity")] | |
public short? Capacity { get; set; } | |
[JsonProperty("venue")] | |
public EventVenue Venue { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class EventContact | |
{ | |
[JsonProperty("name")] | |
public string Name { get; set; } | |
[JsonProperty("phone")] | |
public string Phone { get; set; } | |
[JsonProperty("show_phone")] | |
public bool ShowPhone { get; set; } | |
[JsonProperty("email")] | |
public string Email { get; set; } | |
[JsonProperty("show_email")] | |
public bool ShowEmail { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class EventContainer | |
{ | |
public EventContainer(Event @event) | |
{ | |
Event = @event; | |
} | |
[JsonProperty("event")] | |
public Event Event { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class EventRsvpForm | |
{ | |
[JsonProperty("phone")] | |
public string PhoneRequirementLevel { get; set; } | |
[JsonProperty("address")] | |
public string AddressRequirementLevel { get; set; } | |
[JsonProperty("allow_guests")] | |
public bool AllowGuests { get; set; } | |
[JsonProperty("accept_rsvps")] | |
public bool AcceptRsvps { get; set; } | |
[JsonProperty("gather_volunteers")] | |
public bool GatherVolunteers { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal static class EventSamples | |
{ | |
public static void RunSamples() | |
{ | |
// Create the event | |
Event createdEvent = CreateEvent(); | |
// Update the event | |
UpdateEvent(createdEvent); | |
} | |
/// <summary> | |
/// Creates a sample event using the NationBuilder API. | |
/// </summary> | |
/// <returns>The event that was created.</returns> | |
private static Event CreateEvent() | |
{ | |
Event @event = GetNewEvent(); | |
var eventService = new EventService(); | |
return eventService.CreateEvent(@event); | |
} | |
/// <summary> | |
/// Updates an event using the NationBuilder API. | |
/// </summary> | |
/// <param name="event">The event to update.</param> | |
private static void UpdateEvent(Event @event) | |
{ | |
// Set a new name | |
@event.Name = "Updated Name"; | |
var eventService = new EventService(); | |
eventService.UpdateEvent(@event); | |
} | |
/// <summary> | |
/// Creates the object that will be send to the Create Event API method. | |
/// </summary> | |
/// <returns>The EventContainer that will be sent to the API.</returns> | |
private static Event GetNewEvent() | |
{ | |
DateTime startTime = DateTime.Now.AddHours(2); | |
DateTime endTime = startTime.AddMinutes(120); | |
return new Event | |
{ | |
Capacity = 10, | |
Contact = new EventContact | |
{ | |
Email = "test@test.com", | |
Phone = "5555555555", | |
Name = "My Contact", | |
ShowEmail = true, | |
ShowPhone = true | |
}, | |
Headline = "Test Headline", | |
Intro = "Test Intro", | |
Name = "Test Name", | |
RsvpForm = new EventRsvpForm | |
{ | |
AcceptRsvps = true, | |
AddressRequirementLevel = RequirementLevel.Required, | |
AllowGuests = true, | |
GatherVolunteers = true, | |
PhoneRequirementLevel = RequirementLevel.Required | |
}, | |
ShowGuests = true, | |
StartTime = startTime, | |
EndTime = endTime, | |
Status = EventStatus.Unlisted, | |
TimeZone = TimeZone.CurrentTimeZone, | |
Title = "Test Title", | |
Venue = new EventVenue("Test venue", new EventVenueAddress("Test Address 1", "Test City", "CA")) | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class EventService : Service | |
{ | |
public Event CreateEvent(Event @event) | |
{ | |
var endpoint = EndPointProvider.GetCreateEventEndPoint(); | |
var container = new EventContainer(@event); | |
var request = new ServiceRequest<EventContainer>(endpoint, container); | |
var result = PostWithResult<EventContainer, EventContainer>(request); | |
return result.Event; | |
} | |
public void UpdateEvent(Event @event) | |
{ | |
var endpoint = EndPointProvider.GetUpdateEventEndPoint(@event.Id.Value); | |
var container = new EventContainer(@event); | |
var request = new ServiceRequest<EventContainer>(endpoint, container); | |
Put(request); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class EventVenue | |
{ | |
public EventVenue(string name, EventVenueAddress address) | |
{ | |
Name = name; | |
Address = address; | |
} | |
[JsonProperty("name")] | |
public string Name { get; set; } | |
[JsonProperty("address")] | |
public EventVenueAddress Address { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class EventVenueAddress | |
{ | |
public EventVenueAddress(string address1, string city, string state) | |
{ | |
Address1 = address1; | |
City = city; | |
State = state; | |
} | |
[JsonProperty("address1")] | |
public string Address1 { get; set; } | |
[JsonProperty("city")] | |
public string City { get; set; } | |
[JsonProperty("state")] | |
public string State { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class Person | |
{ | |
[JsonProperty("id", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public int? Id { get; private set; } | |
[JsonProperty("first_name", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public string FirstName { get; set; } | |
[JsonProperty("last_name", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public string LastName { get; set; } | |
[JsonProperty("email", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public string Email { get; set; } | |
[JsonProperty("is_deceased", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public bool? IsDeceased { get; set; } | |
[JsonProperty("mobile", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public string PhoneNumberMobile { get; set; } | |
[JsonProperty("phone", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public string PhoneNumberHome { get; set; } | |
[JsonProperty("work_phone_number", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public string PhoneNumberWork { get; set; } | |
[JsonProperty("support_level", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public int? SupportLevel { get; private set; } | |
[JsonProperty("is_volunteer", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public bool? IsVolunteer { get; set; } | |
[JsonProperty("do_not_call", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public bool? DoNotCall { get; set; } | |
[JsonProperty("do_not_contact", DefaultValueHandling = DefaultValueHandling.Ignore)] | |
public bool? DoNotContact { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class PersonContainer | |
{ | |
public PersonContainer(Person person) | |
{ | |
Person = person; | |
} | |
[JsonProperty("person")] | |
public Person Person { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal static class PersonSamples | |
{ | |
public static void RunSamples() | |
{ | |
// Create the person | |
var person = CreatePerson(); | |
// Update the person | |
UpdatePerson(person); | |
// Delete the person | |
DeletePerson(person.Id.Value); | |
} | |
private static Person CreatePerson() | |
{ | |
var person = GetNewPerson(); | |
var service = new PersonService(); | |
return service.CreatePerson(person); | |
} | |
private static void UpdatePerson(Person person) | |
{ | |
person.FirstName = "NewFirstName"; | |
person.LastName = "NewLastName"; | |
var service = new PersonService(); | |
service.UpdatePerson(person); | |
} | |
private static void DeletePerson(int id) | |
{ | |
var service = new PersonService(); | |
service.DeletePerson(id); | |
} | |
private static Person GetNewPerson() | |
{ | |
return new Person | |
{ | |
FirstName = "OrigFirstName", | |
LastName = "OrigLastName", | |
Email = "test@test.com", | |
IsVolunteer = true | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class PersonService : Service | |
{ | |
public Person CreatePerson(Person person) | |
{ | |
string endpoint = EndPointProvider.GetCreatePersonEndPoint(); | |
var container = new PersonContainer(person); | |
var request = new ServiceRequest<PersonContainer>(endpoint, container); | |
PersonContainer result = PostWithResult<PersonContainer, PersonContainer>(request); | |
return result.Person; | |
} | |
public void UpdatePerson(Person person) | |
{ | |
string endpoint = EndPointProvider.GetUpdatePersonEndPoint(person.Id.Value); | |
var container = new PersonContainer(person); | |
var request = new ServiceRequest<PersonContainer>(endpoint, container); | |
Put(request); | |
} | |
public void DeletePerson(int personId) | |
{ | |
string endpoint = EndPointProvider.GetDeletePersonEndPoint(personId); | |
Delete(endpoint); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal abstract class Service | |
{ | |
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); | |
protected void Delete(string endPoint) | |
{ | |
var request = new ServiceRequest<object>(endPoint, null); | |
SendRequest(request, client => client.DeleteAsync(endPoint)); | |
} | |
protected void Put<T>(ServiceRequest<T> request) where T : class | |
{ | |
SendRequest(request, client => client.PutAsJsonAsync(request.Endpoint, request.Payload)); | |
} | |
protected TResponse PostWithResult<TPayload, TResponse>(ServiceRequest<TPayload> request) | |
where TPayload : class | |
where TResponse : class | |
{ | |
return SendRequestWithResponse<TPayload, TResponse>(request, | |
client => client.PostAsJsonAsync(request.Endpoint, request.Payload)); | |
} | |
private void SendRequest<T>(ServiceRequest<T> request, Func<HttpClient, Task<HttpResponseMessage>> sendFunc) | |
where T : class | |
{ | |
using (var client = new HttpClient()) | |
{ | |
client.Timeout = ConfigProvider.ServiceTimeout; | |
client.DefaultRequestHeaders.Accept.Clear(); | |
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | |
Task<HttpResponseMessage> postTask = sendFunc(client); | |
Task.WaitAll(postTask); | |
HttpResponseMessage response = postTask.Result; | |
if (response.IsSuccessStatusCode) | |
{ | |
return; | |
} | |
Task<string> responseTask = response.Content.ReadAsStringAsync(); | |
Task.WaitAll(responseTask); | |
string responseText = responseTask.Result; | |
string payloadString = request.Payload != null ? JsonConvert.SerializeObject(request.Payload) : null; | |
Logger.Error("Error sending {0} to: {1}. Response: {2}", payloadString, request.Endpoint, responseText); | |
throw new InvalidOperationException("API call failed."); | |
} | |
} | |
private TResponse SendRequestWithResponse<TPayload, TResponse>(ServiceRequest<TPayload> request, | |
Func<HttpClient, Task<HttpResponseMessage>> sendFunc) where TPayload : class where TResponse : class | |
{ | |
using (var client = new HttpClient()) | |
{ | |
client.Timeout = ConfigProvider.ServiceTimeout; | |
client.DefaultRequestHeaders.Accept.Clear(); | |
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | |
Task<HttpResponseMessage> postTask = sendFunc(client); | |
Task.WaitAll(postTask); | |
HttpResponseMessage response = postTask.Result; | |
Task<string> responseTask = response.Content.ReadAsStringAsync(); | |
Task.WaitAll(responseTask); | |
string responseText = responseTask.Result; | |
if (response.IsSuccessStatusCode) | |
{ | |
return JsonConvert.DeserializeObject<TResponse>(responseText); | |
} | |
string payloadString = JsonConvert.SerializeObject(request.Payload); | |
Logger.Error("Error sending {0} to: {1}. Response: {2}", payloadString, request.Endpoint, responseText); | |
throw new InvalidOperationException("API call failed."); | |
} | |
} | |
} |
Stanley - are you still interested in this? We have a C# client that we can share out.
Hello Mike.. are you able to share that project with me... interested. Thank you! @MikeStall
I too would be interested in that project if you were able to share it. Thank you. @MikeStall
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Kevev22
We are trying to connect NationBuilder with C# application.
Can you please provide us the entire solution code of this project, we try to run your sample code, it does not work due to missing context definition (such as EndPointProvider does not exist in the current context, might be missing files).
Looking forward to your reply.
My email address is: stanleyliu1006@outlook.com
Regards
Stanley