Skip to content

darrenparkinson/planhat

Repository files navigation

Go Planhat - A simple Planhat Go Library

Status GitHub tag (latest SemVer) GitHub GoDoc Go Report Card

This repository is intended as a simple to use library for the Go language to interact with the Planhat API.

In order to use this library you will need a planhat subscription.

Installing

You can install the library in the usual way as follows:

$ go get github.com/darrenparkinson/planhat

Usage

In your code, import the library:

import "github.com/darrenparkinson/planhat"

You can then construct a new Planhat client, and use the various services on the client to access different parts of the API. For example:

ph, _ := planhat.NewClient(apikey, cluster, nil)
companies, err := ph.CompanyService.List(context.Background())

Some API methods have optional parameters that can be passed, for example:

ph, _ := planhat.NewClient(apikey, cluster, nil)
opts := &planhat.CompanyListOptions{Limit: planhat.Int(10), Offset: planhat.Int(0)}
companies, err := ph.CompanyService.List(context.Background(), opts)

The services of a client divide the API into logical areas and correspond to the structure of the Planhat API documentation at https://docs.planhat.com/

NOTE: Using the context package, one can easily pass cancelation signals and deadlines to various services of the client for handling a request. In case there is no context available, then context.Background() can be used as a starting point.

Authentication

Authentication is provided by an API Key as outlined in the documentation. You are able to provide the API Key as part of initialisation using NewClient.

You can obtain an API key by navigating to "Service Accounts" and adding a new service account user that has the permissions you require, followed by clicking the "Generate New Token" button.

If you receive a planhat: unauthorized request message, you may be using an incorrect region.

Region

Planhat supports various regions and cluster as outlined in the documentation. You must provide the cluster you are using to NewClient on initialisation. Ask your planhat representative or check the docs to see which one you need to use. If there is no specified cluster, you may pass an empty string.

Examples:

  • "" becomes api,
  • eu becomes api-eu,
  • eu2 becomes api-eu2,
  • eu3 becomes api-eu3,
  • us2 becomes api-us2

Helper Functions

Most structs for resources use pointer values. This allows distinguishing between unset fields and those set to a zero value. Some helper functions have been provided to easily create these pointers for string, bool and int values as you saw above and here, for example:

opts := &planhat.CompanyListOptions{
	Limit:  planhat.Int(10),
	Offset: planhat.Int(0),
	Sort:   planhat.String("name"),
}

This can cause challenges when receiving results since you may encounter a panic if you access a nil pointer, e.g:

company, _ := ph.CompanyService.GetCompany(ctx, "123123123abcabcabc")
log.Println(*company.ExternalID)

In this case, if the external id has no value, you would receive a panic: runtime error: invalid memory address or nil pointer dereference error. Clearly this isn't a very nice user experience, so where appropriate, "getter" accessor functions are generated automatically for structs with pointer fields to enable you to safely retrieve values:

company, _ := ph.CompanyService.GetCompany(ctx, "123123123abcabcabc")
log.Println(company.GetExternalID())

Pagination

Where pagination is provided, Planhat provides the Offset and Limit query parameters as part of the request parameters for a given endpoint. These can be passed via options to the command:

companies, err := c.CompanyService.List(ctx, &planhat.CompanyListOptions{Limit: planhat.Int(10), Offset: planhat.Int(0)})

By way of an example, you might use the following to work through multiple pages:

var allCompanies []*planhat.Company
limit, offset := 10, 0
for {
    companies, _ := ph.CompanyService.List(ctx, &planhat.CompanyListOptions{Limit: planhat.Int(limit), Offset: planhat.Int(offset)})
    log.Println("Retrieved", len(companies), "companies")
    offset += limit
    if len(companies) == 0 {
	    break
    }
    allCompanies = append(allCompanies, companies...)
}
log.Println("Found total", len(allCompanies), "companies.")

As you can see, planhat doesn't provide a mechanism to check if there are more values, so we keep going until there are no results.

Sorting

Where sorting is provided, Planhat provides the Sort query parameter as part of the request parameters for a given endpoint. This can also be passed via the options to the command and is used in conjuntion with pagination:

companies, err := c.CompanyService.List(ctx, &planhat.CompanyListOptions{Limit: planhat.Int(10), Offset: planhat.Int(0), Sort: planhat.String("name")})

Note that the sort string appears to be case sensitive and must currently use the Planhat object name.

Errors

In the documentation, Planhat identifies the following returned errors. Additionally, Planhat returns an undocumented error (404) when an entity is not found. These are provided as constants so that you may check against them:

Code Error Constant
400 Bad Request ErrBadRequest
401 Unauthorized Request ErrUnauthorized
404 Not Found ErrNotFound
403 Forbidden ErrForbidden
500 Internal Error ErrInternalError

All other errors are returned as ErrUnknown

As an example:

companies, err := ph.CompanyService.List(ctx)
if errors.Is(err, planhat.ErrUnauthorized) {
	log.Fatal("Sorry, you're not allowed to do that.")
}

Services

The following outlines the planhat models and their implementation status:

Model Service Implementation Status
Asset AssetService Complete
Churn ChurnService Not Implemented
Company CompanyService Complete
Conversation ConversationService Not Implemented
Custom Field CustomFieldService Not Implemented
Enduser EnduserService Not Implemented
Invoice InvoiceService Not Implemented
Issue IssueService Not Implemented
License LicenseService Not Implemented
Note NoteService Not Implemented
NPS NPSService Not Implemented
Opportunity OpportunityService Not Implemented
Project ProjectService Not Implemented
Sale SaleService Not Implemented
Task TaskService Not Implemented
Ticket TicketService Not Implemented
User UserService Partial

In addition to the Planhat Models, there are some additional endpoints in the documentation as outlined below:

Section Service Implementation Status
User Activities UserActivityService Not Implemented
Metrics MetricsService Complete

Contributing

Since all endpoints would ideally be covered, contributions are always welcome. Adding new methods should be relatively straightforward.

Versioning

In general this planhat library follows semver for tagging releases of the package. As yet, it is still in development and has not had a tag added, but will in due course. Since it is still in development, you may expect some changes.

License

This library is distributed under the MIT license found in the LICENSE file.

About

Simple Go library for Planhat

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages