Hello - I am having some issues with sending a PUT request to FreshService for adding a private note to a ticket. Every time I try to send either PUT or POST, the Body introduces some sort of Reader:
key. This is especially troublesome when according to their documentation all that should be included in the body is the note itself: https://api.freshservice.com/#create_a_note.
Here is the error specifically I am getting:
{"code":"invalid_json","message":"Request body has invalid json format"}
Here is the code I’m working with:
https://play.golang.org/p/nte_4rYDcbb
package main
// PUTRequest sends a PUT request to /api/v2/ at the specified endpoint
func PUTRequest(endpoint, apiKey string, jsonStr []byte) ([]byte, error) {
url := "https://example.freshservice.com/api/v2/"
req, _ := http.NewRequest(http.MethodPut, url+endpoint, bytes.NewBuffer(jsonStr))
log.Printf("[req:] %+v\n", req)
key := base64.URLEncoding.EncodeToString([]byte(apiKey + ":X"))
req.Header.Set("Content-Type", "application/json")
req.Header.Add("Authorization", "Basic "+key)
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("could not client.Do:\n%v", err)
}
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
return body, nil
}
// CreateNote creates a private note on *TicketList with the message specified
func (ticketList *TicketList) CreateNote(message, apiKey string) ([]byte, error) {
payload, _ := json.Marshal(message)
var responses []byte
for i := range ticketList.Tickets {
ticketUrl := fmt.Sprintf("tickets/%v", ticketList.Tickets[i].ID)
resp, err := PUTRequest(ticketUrl, apiKey, payload)
if err != nil {
return nil, fmt.Errorf("could not update ticket:\n%v", err)
}
responses = append(responses, resp...)
}
return responses, nil
}
func main() {
response, err := ticketList.CreateNote("This is a test", "<ApiKey>")
if err != nil {
log.Fatal(err)
}
log.Printf("[response:] %s", response)
}
With the log.Printf
s here is the output:
2021/09/03 09:20:07 [resp:] &{Method:GET URL:https://example.freshservice.com/api/v2/tickets/<Ticket#>/requested_items Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[Authorization:[Basic <base64Key>=] Content-Type:[application/json]] Body:{} GetBody:0x11f37c0 ContentLength:0 TransferEncoding:[] Close:false Host:example.freshservice.com Form:map[] PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr: RequestURI: TLS:<nil> Cancel:<nil> Response:<nil> ctx:0xc00001e0b8}
2021/09/03 09:20:07 [reqlist:] {RequestedItems:[{OnboardingItems:{StartDate:2021-08-25 FirstName:test LastName:UserMan Address:1234 Main ST, nowhere USA PhoneNumber:123-456-7890 OfficeLocation:Remote Department:Engineering LaptopType:Mac LaptopExceptions: ReportingManagerEmail:manager.name@example.com IsManager:false IsContractor:false Monitor:false KeyboardAndMouse:false Mouse:false}}]}
2021/09/03 09:20:07 [req:] &{Method:PUT URL:https://example.freshservice.com/api/v2/tickets/<ticket#> Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[] Body:{Reader:"This is a test"} GetBody:0x11dc8a0 ContentLength:16 TransferEncoding:[] Close:false Host:example.freshservice.com Form:map[] PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr: RequestURI: TLS:<nil> Cancel:<nil> Response:<nil> ctx:0xc00001e0b8}
2021/09/03 09:20:07 [response:] {"code":"invalid_json","message":"Request body has invalid json format"}
As you can see on line 3 ([req:]
), somehow Body is Body:{Reader:"This is a test"}
. All I want is to send Body{"this is a test"}
. My current theory is that in http.NewRequest
it uses body io.Reader
and io.Reader
is somehow adding Reader
to the body.
This hasn’t been an issue if I create a user in FreshService, which uses POST, and still includes the Body: {Reader: {key:value}}
as well. But with PUT, for some reason having Body:{Reader:}
proves to be an issue.
I have also tried running:
payload, _ := json.Marshal(map[string]string{"body": message})
within PUTRequest
, however that still proves to be an issue regardless. Here is the request that it sends:
Body:{Reader:{"body":"This is a test"}}
However, still gets the same error:
{"code":"invalid_json","message":"Request body has invalid json format"}
Let me know what else I can try, still learning Go as I go.