README
¶
HouseCall Pro API wrapper
Package provides a wrapper for interacting with the HouseCallPro API. Written in pure GoLang
go get github.com/BeelineRoutes/housecall
House Call OAuth flow
Offical documentation for the API can be found here.
First have your user go to
https://api.housecallpro.com/oauth/authorize?response_type=code&client_id=clientId&redirect_uri=https://your-url.com
This will return to your redirect url with a "code" as a url param
https://your-url.com/housecall?code=urlParamCode
Usage
import (
"github.com/BeelineRoutes/housecall"
"github.com/pkg/errors"
"log"
)
clientId := "ca96e4cd990507c2995b9633bd9caa679bee26e99f98572ba54751ab4ff24886" // your special client id
clientSecret := "1fd00f12ab1d3d13c6bf746aa1868bd591af098100d800195b56b6fa97795d73" // your secret
redirectUrl := "https://your-domain.com" // this can be whatever, you tell House Call what you want when you create your account
hc, err := housecall.NewHouseCall (clientId, clientSecret, redirectUrl) // create the hc object
if err != nil { log.Fatal (err) }
// now you can do something like convert the code you got from the url to a long-lived token and refresh token
params := r.URL.Query()
code := ""
if len(params["code"]) > 0 && len(params["code"][0]) > 0 {
code = params[term][0]
} else {
t.Fatal ("was expecting a url param 'code' to be set")
}
token, refresh, err := hc.TokensFromCode (context.TODO(), code)
// handle the error gracefully
switch errors.Cause (err) {
case housecall.ErrInvalidCode: // specific error for an invalid/expired code
log.Printf ("Code appears invalid, most likely it's expired. %s", err.Error())
case nil:
log.Printf ("Code is valid!")
default:
log.Fatalf ("Unknown error occured : %s", err.Error())
}
// token is used as the bearer for future calls
// refresh can be used to generate a new token when it expires
History
This is actively being developed and while the goal is to prevent breaking changes, this is still in an early alpha.
-
0.1 Initial version allows for validating a client OAuth token and retrieving the Token and Refresh tokens
-
0.2 Start and end dates used for filtering jobs
-
0.3 URL params for additional filtering of jobs
-
0.4 Writes updates back to HCP to update jobs and their assigned employees
Documentation
¶
Index ¶
- Variables
- type Address
- type Appointment
- type Company
- type CreateEstimateOption
- type Customer
- type DispatchedEmployee
- type Employee
- type Error
- type Estimate
- type Event
- type HouseCall
- func (this *HouseCall) Company(ctx context.Context, token string) (*Company, error)
- func (this *HouseCall) CreateCustomer(ctx context.Context, token string, customer *Customer) error
- func (this *HouseCall) CreateEstimate(ctx context.Context, token, customerId, addressId string, startTime time.Time, ...) (*Estimate, error)
- func (this *HouseCall) CreateJob(ctx context.Context, token, customerId, addressId string, startTime time.Time, ...) (*Job, error)
- func (this *HouseCall) GetEstimate(ctx context.Context, token, estId string) (*Estimate, error)
- func (this *HouseCall) GetJob(ctx context.Context, token, jobId string) (*Job, error)
- func (this *HouseCall) GetJobAppointments(ctx context.Context, token, jobId string) ([]Appointment, error)
- func (this *HouseCall) GetLineItems(ctx context.Context, token, jobId string) ([]*LineItem, error)
- func (this *HouseCall) ListEmployees(ctx context.Context, token string) ([]Employee, error)
- func (this *HouseCall) ListEstimates(ctx context.Context, token string, employeeId string, start, finish time.Time) ([]Estimate, error)
- func (this *HouseCall) ListEvents(ctx context.Context, token string, start, end time.Time) ([]Event, error)
- func (this *HouseCall) ListJobs(ctx context.Context, token string, start, finish time.Time) ([]Job, error)
- func (this *HouseCall) ListJobsFromCustomer(ctx context.Context, token string, customerId string) ([]Job, error)
- func (this *HouseCall) ListJobsFromEmployee(ctx context.Context, token string, employeeId string, start, finish time.Time) ([]Job, error)
- func (this *HouseCall) ListLeads(ctx context.Context, token string) ([]*LeadSource, error)
- func (this *HouseCall) ListMissedJobs(ctx context.Context, token string, start, finish time.Time) ([]Job, error)
- func (this *HouseCall) ListUnscheduledEstimates(ctx context.Context, token string, pageLimit int) ([]Estimate, error)
- func (this *HouseCall) ListUnscheduledJobs(ctx context.Context, token string, pageLimit int) ([]Job, error)
- func (this *HouseCall) PageCustomers(ctx context.Context, token string, page int) ([]Customer, error)
- func (this *HouseCall) Schedule(ctx context.Context, token string) (*Schedule, error)
- func (this *HouseCall) SearchCustomers(ctx context.Context, token, search string) ([]Customer, error)
- func (this *HouseCall) TokensFromCode(ctx context.Context, code string) (*OauthResponse, error)
- func (this *HouseCall) TokensFromRefresh(ctx context.Context, refresh string) (*OauthResponse, error)
- func (this *HouseCall) UpdateEstimateSchedule(ctx context.Context, token, estId, optionId string, employeeIds []string, ...) error
- func (this *HouseCall) UpdateJobAppointmentSchedule(ctx context.Context, token, jobId, apptId string, employeeIds []string, ...) error
- func (this *HouseCall) UpdateJobDispatch(ctx context.Context, token, jobId string, employeeIds ...string) error
- func (this *HouseCall) UpdateJobSchedule(ctx context.Context, token, jobId string, employeeIds []string, ...) error
- type Job
- type JobDispatch
- type JobSchedule
- type LeadSource
- type LineItem
- type OauthResponse
- type Schedule
- type WorkStatus
Constants ¶
This section is empty.
Variables ¶
Functions ¶
This section is empty.
Types ¶
type Address ¶
type Address struct { Id string `json:"id"` Type string `json:"type"` Street string `json:"street"` Street2 string `json:"street_line_2"` City string `json:"city"` State string `json:"state"` Zip string `json:"zip"` Country string `json:"country"` Latitude string `json:"latitude"` Longitude string `json:"longitude"` }
type Appointment ¶ added in v1.14.1
type Company ¶ added in v0.1.5
type Company struct { Id string `json:"id"` PhoneNumber string `json:"phone_number"` Email string `json:"support_email"` Name string `json:"name"` Logo string `json:"logo_url"` Address Address `json:"address"` Website string `json:"website"` DefaultArrivalWindow int `json:"default_arrival_window"` TimeZone string `json:"time_zone"` }
type CreateEstimateOption ¶ added in v1.4.0
type Customer ¶
type Customer struct { Id string `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Email string `json:"email"` Mobile string `json:"mobile_number"` Home string `json:"home_number"` Work string `json:"work_number"` Company string `json:"company"` Notifications bool `json:"notifications_enabled"` Tags []string `json:"tags"` Addresses []Address `json:"addresses"` LeadSource string `json:"lead_source,omitempty"` Notes string `json:"notes,omitempty"` }
type DispatchedEmployee ¶ added in v0.4.0
type DispatchedEmployee struct {
Id string `json:"employee_id"`
}
type Employee ¶ added in v0.1.2
type Employee struct { Id string `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Email string `json:"email"` Mobile string `json:"mobile_number"` Color string `json:"color_hex"` Avatar string `json:"avatar_url"` Role string `json:"role"` Tags []string `json:"tags"` }
type Error ¶
----- ERRORS ---------------------------------------------------------------------------------------------------------//
func (*Error) UnmarshalJSON ¶ added in v1.12.3
type Estimate ¶ added in v1.2.0
type Estimate struct { Id string `json:"id"` EstimateNumber string `json:"estimate_number"` WorkStatus WorkStatus `json:"work_status"` // LeadSource string `json:"lead_source,omitempty"` Customer Customer Address Address `json:"address"` WorkTimestamps struct { OnMyWay time.Time `json:"on_my_way_at"` Started time.Time `json:"started_at"` Completed time.Time `json:"completed_at"` } `json:"work_timestamps"` Schedule struct { Start time.Time `json:"scheduled_start"` End time.Time `json:"scheduled_end"` Window int `json:"arrival_window"` } AssignedEmployees []Employee `json:"assigned_employees"` Options []estimateOption }
type Event ¶ added in v1.5.0
type Event struct { Id string `json:"id"` Name string `json:"name"` Note string `json:"note"` Recurrence string `json:"recurrence_rule"` AssignedEmployees []Employee `json:"assigned_employees"` Schedule struct { Start time.Time `json:"start_time"` End time.Time `json:"end_time"` TimeZone string `json:"time_zone"` } `json:"schedule"` }
func (Event) ExtractRecurrence ¶ added in v1.6.0
creates a list of event objects based on the recurrence schedule "FREQ=WEEKLY;INTERVAL=2;UNTIL=20221128T070000Z;BYDAY=SA"
type HouseCall ¶
type HouseCall struct {
// contains filtered or unexported fields
}
func NewHouseCall ¶
func (*HouseCall) CreateCustomer ¶ added in v0.6.0
creates the customer and returns their id
func (*HouseCall) CreateEstimate ¶ added in v1.2.0
func (this *HouseCall) CreateEstimate(ctx context.Context, token, customerId, addressId string, startTime time.Time, duration, arrivalWindow time.Duration, notifyCustomer bool, employeeIds, tags []string, leadSource, note, message string, options []CreateEstimateOption) (*Estimate, error)
creates a new estimate in the system
func (*HouseCall) CreateJob ¶ added in v0.7.0
func (this *HouseCall) CreateJob(ctx context.Context, token, customerId, addressId string, startTime time.Time, duration, arrivalWindow time.Duration, employeeIds, tags []string, lineItems []LineItem, leadSource, notes string) (*Job, error)
creates a new job in the system
func (*HouseCall) GetEstimate ¶ added in v1.2.0
gets the info about a specific estimate
func (*HouseCall) GetJobAppointments ¶ added in v1.14.1
func (this *HouseCall) GetJobAppointments(ctx context.Context, token, jobId string) ([]Appointment, error)
----- APPOINTMENTS jobs can have appointments now...
func (*HouseCall) GetLineItems ¶ added in v0.8.0
returns the line items associated with the job this will include all the different "kinds"
func (*HouseCall) ListEmployees ¶ added in v0.1.4
Returns a list of the employees (pros) in asc by last name
func (*HouseCall) ListEstimates ¶ added in v1.2.0
func (this *HouseCall) ListEstimates(ctx context.Context, token string, employeeId string, start, finish time.Time) ([]Estimate, error)
returns a list of estimates for a specific employee over the target date range
func (*HouseCall) ListEvents ¶ added in v1.5.0
func (this *HouseCall) ListEvents(ctx context.Context, token string, start, end time.Time) ([]Event, error)
returns a list of events over the target date range this includes any event that overlaps the passed time
func (*HouseCall) ListJobs ¶
func (this *HouseCall) ListJobs(ctx context.Context, token string, start, finish time.Time) ([]Job, error)
returns all jobs that are within our start and finish ranges
func (*HouseCall) ListJobsFromCustomer ¶ added in v1.3.0
func (this *HouseCall) ListJobsFromCustomer(ctx context.Context, token string, customerId string) ([]Job, error)
returns a list of jobs that are associated with the customer
func (*HouseCall) ListJobsFromEmployee ¶ added in v0.4.4
func (this *HouseCall) ListJobsFromEmployee(ctx context.Context, token string, employeeId string, start, finish time.Time) ([]Job, error)
returns a list of jobs for a specific employee over the target date range
func (*HouseCall) ListMissedJobs ¶ added in v1.10.0
func (this *HouseCall) ListMissedJobs(ctx context.Context, token string, start, finish time.Time) ([]Job, error)
returns all jobs that are within our start and finish ranges
func (*HouseCall) ListUnscheduledEstimates ¶ added in v1.2.0
func (this *HouseCall) ListUnscheduledEstimates(ctx context.Context, token string, pageLimit int) ([]Estimate, error)
Returns a list of the estimates that are marked as "unscheduled".
func (*HouseCall) ListUnscheduledJobs ¶ added in v0.2.0
func (this *HouseCall) ListUnscheduledJobs(ctx context.Context, token string, pageLimit int) ([]Job, error)
Returns a list of the jobs that are marked as "unscheduled".
func (*HouseCall) PageCustomers ¶ added in v1.8.0
func (this *HouseCall) PageCustomers(ctx context.Context, token string, page int) ([]Customer, error)
used to request a specific page for customers allows us to check for newly created ones as well as move back in time.
func (*HouseCall) Schedule ¶ added in v0.3.3
Gets the companies schedule. The return from HCP is a little... tough to interpret this just returns time.Times for the start and end of the longest time during the day
func (*HouseCall) SearchCustomers ¶ added in v0.6.0
func (this *HouseCall) SearchCustomers(ctx context.Context, token, search string) ([]Customer, error)
Returns a list of the customers using a 'simple' searching keyword or short address part returns in order of most recently created. converted to page through the results, allows us to do an empty search for customers
func (*HouseCall) TokensFromCode ¶
Takes the passed code we got from the params of the redirect url and converts it to long-live token and refresh token
func (*HouseCall) TokensFromRefresh ¶
func (this *HouseCall) TokensFromRefresh(ctx context.Context, refresh string) (*OauthResponse, error)
Gets new tokens using a previously retreived refresh token
func (*HouseCall) UpdateEstimateSchedule ¶ added in v1.13.0
func (this *HouseCall) UpdateEstimateSchedule(ctx context.Context, token, estId, optionId string, employeeIds []string, startTime time.Time, duration, arrivalWindow time.Duration, notifyCustomer bool) error
updates the target estimate time for an option in the estimate at least 1 employee is required for this
func (*HouseCall) UpdateJobAppointmentSchedule ¶ added in v1.13.0
func (this *HouseCall) UpdateJobAppointmentSchedule(ctx context.Context, token, jobId, apptId string, employeeIds []string, startTime time.Time, duration, arrivalWindow time.Duration, notifyCustomer bool) error
this is how we update the "new" setup for jobs where we have an appointment now 2023-10-18 notifications don't work with this endpoint, HCP says they're working on that
func (*HouseCall) UpdateJobDispatch ¶ added in v0.4.0
func (this *HouseCall) UpdateJobDispatch(ctx context.Context, token, jobId string, employeeIds ...string) error
sets the list of all assigned employees for a job only updates the list of employees assigned to a job
func (*HouseCall) UpdateJobSchedule ¶ added in v0.1.6
func (this *HouseCall) UpdateJobSchedule(ctx context.Context, token, jobId string, employeeIds []string, startTime time.Time, duration, arrivalWindow time.Duration, notifyCustomer bool) error
updates the target scheduled time for a job at least 1 employee is required for this if startTime is zero, then this will remove the scheduled time from the job
type Job ¶
type Job struct { Id string `json:"id"` CustomerId string `json:"customer_id"` Customer Customer Address Address `json:"address"` Note string `json:"note"` WorkStatus WorkStatus `json:"work_status"` Invoice string `json:"invoice_number"` Balance int64 `json:"outstanding_balance"` Total int64 `json:"total_amount"` Tags []string `json:"tags"` Description string `json:"description"` AssignedEmployees []Employee `json:"assigned_employees"` Schedule struct { Start time.Time `json:"scheduled_start"` End time.Time `json:"scheduled_end"` Window int `json:"arrival_window"` } Appointments []Appointment `json:"appointments"` WorkTimestamps struct { OnMyWay time.Time `json:"on_my_way_at"` Started time.Time `json:"started_at"` Completed time.Time `json:"completed_at"` } `json:"work_timestamps"` LeadSource string `json:"lead_source,omitempty"` }
type JobDispatch ¶ added in v0.4.0
type JobDispatch struct {
DispatchedEmployees []DispatchedEmployee `json:"dispatched_employees"`
}
type JobSchedule ¶ added in v0.1.6
type LeadSource ¶ added in v1.17.0
type LeadSource struct {
Id, Name string
}
type OauthResponse ¶ added in v1.11.0
type OauthResponse struct { AccessToken string `json:"access_token"` TokenType string `json:"token_type"` Expires int64 `json:"expires_in"` RefreshToken string `json:"refresh_token"` Scope string `json:"scope"` Created int64 `json:"created_at"` }
func (*OauthResponse) ExpiresAt ¶ added in v1.11.0
func (this *OauthResponse) ExpiresAt() time.Time
returns a time object of when this oauth will expire
type Schedule ¶ added in v0.3.3
type Schedule struct { DailyAvailabilities struct { Data []struct { DayName string `json:"day_name"` ScheduleWindows struct { Data []struct { StartTime scheduleTime `json:"start_time"` EndTime scheduleTime `json:"end_time"` } `json:"data"` } `json:"schedule_windows"` } `json:"data"` } `json:"daily_availabilities"` }
func (*Schedule) DaySchedules ¶ added in v0.3.3
goes through all the days and returns the earliest start and end for each leaves Start and End as IsZero if there's no schedules for that day this always returns 7 items, 1 for each day of the week loc is the local timezone for this schedule, HCP has the times as a local string when returned it converts it to UTC time if the schedule seems off I'll add more time to either side depending on how close to noon the times are
type WorkStatus ¶ added in v0.3.1
type WorkStatus string
const ( WorkStatus_needsScheduling WorkStatus = "needs scheduling" WorkStatus_scheduled WorkStatus = "scheduled" WorkStatus_inProgress WorkStatus = "in progress" WorkStatus_completeUnrated WorkStatus = "complete unrated" WorkStatus_completeRated WorkStatus = "complete rated" WorkStatus_userCanceled WorkStatus = "user canceled" WorkStatus_proCanceled WorkStatus = "pro canceled" )