Skip to content

Commit

Permalink
Merge pull request #3 from bold-commerce/create_single_email_custom_p…
Browse files Browse the repository at this point in the history
…roperties

create single email with custom properties
  • Loading branch information
markstgodard authored Nov 21, 2018
2 parents e923df3 + 80d8110 commit 80f92bb
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 10 deletions.
12 changes: 8 additions & 4 deletions hubspot/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,23 @@ func NewClient(baseUrl, apiKey string) *Client {
// Hubspot single send email API
// example: https://api.hubapi.com/email/public/v1/singleEmail/send?hapikey=demo
func (c *Client) SingleEmail(emailId int, emailTo string) error {

req := SingleSendEmailRequest{
req := SendEmailRequest{
EmailID: emailId,
Message: Message{
To: emailTo,
},
}
return c.Email(req)
}

body, err := json.Marshal(req)
// Hubspot send email API
// example: https://api.hubapi.com/email/public/v1/singleEmail/send?hapikey=demo
func (c *Client) Email(emailRequest SendEmailRequest) error {

body, err := json.Marshal(emailRequest)
if err != nil {
return fmt.Errorf("invalid request: %s", err.Error())
}

_, err = c.doRequest(request{
URL: fmt.Sprintf("%s/email/public/v1/singleEmail/send?hapikey=%s", c.baseUrl, c.apiKey),
Method: http.MethodPost,
Expand Down
76 changes: 76 additions & 0 deletions hubspot/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package hubspot_test

import (
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"regexp"
Expand Down Expand Up @@ -31,6 +32,7 @@ var _ = Describe("Client", func() {

BeforeEach(func() {
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
if strings.Contains(r.RequestURI, "/email/public/v1/singleEmail/send") {
w.WriteHeader(http.StatusOK)
w.Write([]byte(singleEmailResp))
Expand All @@ -54,6 +56,52 @@ var _ = Describe("Client", func() {

})

Describe("Email", func() {
var (
server *httptest.Server
)

BeforeEach(func() {
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
if strings.Contains(r.RequestURI, "/email/public/v1/singleEmail/send") {
w.WriteHeader(http.StatusOK)
w.Write([]byte(singleEmailResp))
b, err := ioutil.ReadAll(r.Body)
Expect(err).NotTo(HaveOccurred())
Expect(b).To(MatchJSON(b))
} else {
w.WriteHeader(http.StatusInternalServerError)
}
}))

client = hubspot.NewClient(server.URL, "my-api-key")
Expect(client).ToNot(BeNil())
})

AfterEach(func() {
server.Close()
})

It("sends a single customized email", func() {
email := hubspot.SendEmailRequest{
EmailID: 2853049635,
Message: hubspot.Message{
To: "example@hubspot.com",
SendID: "foobar",
},
ContactProperties: []hubspot.MergeField{
{Name: "first_name", Value: "John"},
},
CustomProperties: []hubspot.MergeField{
{Name: "item_1", Value: "something they bought"},
}}
err := client.Email(email)
Expect(err).NotTo(HaveOccurred())
})

})

Describe("CreateOrUpdateContact", func() {
var (
server *httptest.Server
Expand All @@ -63,6 +111,7 @@ var _ = Describe("Client", func() {
response, _ := json.Marshal(map[string]interface{}{"vid": 751, "isNew": true})

server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
if strings.Contains(r.RequestURI, "/contacts/v1/contact/createOrUpdate/email/") {
w.WriteHeader(http.StatusOK)
w.Write([]byte(response))
Expand Down Expand Up @@ -97,6 +146,7 @@ var _ = Describe("Client", func() {
response, _ := json.Marshal(map[string]interface{}{"updated": []int{751}, "discarded": []int{}, "invalidVids": []int{}, "invalidEmails": []string{}})

server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
match, _ := regexp.MatchString(".*contacts/v1/lists/\\d*/add\\?hapikey=.*", r.RequestURI)
if match {
w.WriteHeader(http.StatusOK)
Expand Down Expand Up @@ -131,6 +181,7 @@ var _ = Describe("Client", func() {
response, _ := json.Marshal(map[string]interface{}{"updated": []int{751}, "discarded": []int{}, "invalidVids": []int{}, "invalidEmails": []string{}})

server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
match, _ := regexp.MatchString(".*contacts/v1/lists/\\d*/remove\\?hapikey=.*", r.RequestURI)
if match {
w.WriteHeader(http.StatusOK)
Expand Down Expand Up @@ -167,6 +218,7 @@ var _ = Describe("Client", func() {

It("removes email from workflow", func() {
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
match, _ := regexp.MatchString(".*automation/v2/workflows/\\d*/enrollments/contacts/.*", r.RequestURI)
if match {
w.WriteHeader(http.StatusNoContent)
Expand All @@ -184,6 +236,7 @@ var _ = Describe("Client", func() {

It("returns an error if the contact email is not found", func() {
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
match, _ := regexp.MatchString(".*automation/v2/workflows/\\d*/enrollments/contacts/.*", r.RequestURI)
if match {
w.WriteHeader(http.StatusNotFound)
Expand Down Expand Up @@ -211,6 +264,7 @@ var _ = Describe("Client", func() {

It("removes email from workflow", func() {
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
match, _ := regexp.MatchString(".*automation/v2/workflows/\\d*/enrollments/contacts/.*", r.RequestURI)
if match {
w.WriteHeader(http.StatusNoContent)
Expand All @@ -228,6 +282,7 @@ var _ = Describe("Client", func() {

It("returns an error if the contact email is not found", func() {
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer GinkgoRecover()
match, _ := regexp.MatchString(".*automation/v2/workflows/\\d*/enrollments/contacts/.*", r.RequestURI)
if match {
w.WriteHeader(http.StatusNotFound)
Expand All @@ -253,3 +308,24 @@ const singleEmailResp = `{
"created":1513626117453
}
}`
const emailRequest = `
{
"emailId": 2853049635,
"message": {
"to": "example@hubspot.com",
"sendId": "foobar"
},
"contactProperties": [
{
"name": "first_name",
"value": "John"
}
],
"customProperties": [
{
"name": "item_1",
"value": "something they bought"
}
]
}
`
22 changes: 16 additions & 6 deletions hubspot/email.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package hubspot

type Message struct {
To string `json:"to"`
Cc []string `json:"cc"`
Bcc []string `json:"bcc"`
To string `json:"to"`
From string `json:"from,omitempty"`
SendID string `json:"sendId,omitempty"`
ReplyTo string `json:"replyTo,omitempty"`
ReplyToList []string `json:"replyToList,omitempty"`
Cc []string `json:"cc,omitempty"`
Bcc []string `json:"bcc,omitempty"`
}
type SingleSendEmailRequest struct {
EmailID int `json:"emailId"`
Message Message `json:"message"`
type MergeField struct {
Name string `json:"name"`
Value string `json:"value"`
}
type SendEmailRequest struct {
EmailID int `json:"emailId"`
Message Message `json:"message"`
ContactProperties []MergeField `json:"contactProperties,omitempty"`
CustomProperties []MergeField `json:"customProperties,omitempty"`
}

0 comments on commit 80f92bb

Please sign in to comment.