Skip to content

Commit

Permalink
initial carma client
Browse files Browse the repository at this point in the history
  • Loading branch information
wulkan committed Sep 7, 2018
1 parent 6de1e71 commit 25c93dc
Show file tree
Hide file tree
Showing 15 changed files with 429 additions and 0 deletions.
125 changes: 125 additions & 0 deletions carmaclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package carmaclient

import (
"fmt"
"io/ioutil"
"net/http"
"time"

"bytes"
"encoding/json"
"github.com/moonwalker/logger"
"errors"
)

const (
timeout = 30 * time.Second
carmaAuthHeader = "X-Carma-Authentication-Token"
)

type CarmaClient struct {
HTTPClient *http.Client

carmaApiToken string
carmaOrganization int64
carmaRESTURL string
carmaControllerURL string

log logger.Logger

common service
Triggers *TriggersService
Lists *ListsService
Properties *PropertiesService
}

type service struct {
client *CarmaClient
}

type carmaResponse struct {
statusCode int
data []byte
err error
msg string
}

type carmaError struct {
Error string `json:"error"`
}

func NewCarmaClient(organization int64, token, restURL, controllerURL string, log logger.Logger) (client *CarmaClient, err error) {
client = &CarmaClient{
HTTPClient: &http.Client{
Timeout: timeout,
},
carmaApiToken: token,
carmaOrganization: organization,
carmaRESTURL: restURL,
carmaControllerURL: controllerURL,
log: log,
}

client.common.client = client

client.Triggers = (*TriggersService)(&client.common)
client.Lists = (*ListsService)(&client.common)
client.Properties = (*PropertiesService)(&client.common)

return
}

func (c CarmaClient) catchError(carmaResp *carmaResponse) {
carmaError := &carmaError{}
err := json.Unmarshal(carmaResp.data, carmaError)
if err != nil {
return
}

carmaResp.err = errors.New(carmaError.Error)
}

func (c CarmaClient) carmaRequest(endpoint string, method string, body interface{}) (carmaResp carmaResponse) {
client := http.Client{
Timeout: 10 * time.Second,
}

url := fmt.Sprintf("%s/%d/%s", c.carmaRESTURL, c.carmaOrganization, endpoint)

b := new(bytes.Buffer)
if body != nil {
json.NewEncoder(b).Encode(body)
}

req, err := http.NewRequest(method, url, b)
if err != nil {
carmaResp.err = err
return
}

req.Header[carmaAuthHeader] = []string{c.carmaApiToken}
req.Header["Accept"] = []string{"application/json"}
req.Header["Content-Type"] = []string{"application/json"}

resp, err := client.Do(req)
if err != nil {
carmaResp.err = err
return
}

defer resp.Body.Close()

carmaResp.statusCode = resp.StatusCode

respBody, err := ioutil.ReadAll(resp.Body)
carmaResp.err = err
carmaResp.data = respBody
c.catchError(&carmaResp)

return
}

type RequestResponse struct {
HTTPStatusCode int
Error error
}
19 changes: 19 additions & 0 deletions dto/campaigntype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dto

type CampaignType int64

const (
CampaignTypeEmail CampaignType = 1
CampaignTypeSMS CampaignType = 2
CampaignTypeDeleted CampaignType = 4
CampaignTypeNormalApproved CampaignType = 5
CampaignTypeIncomingSMS CampaignType = 6
CampaignTypeSMSWithOADC CampaignType = 8
CampaignTypeEmailWithAttachement CampaignType = 14
CampaignTypeEmailSubdelivey CampaignType = 16
CampaignTypeEmailMasterDelivery CampaignType = 17
CampaignTypeSMSLinkMobilityDelivery CampaignType = 18
CampaignTypeAppPushAndroidDelivery CampaignType = 19
CampaignTypeAppPushIOSDelivery CampaignType = 20
CampaignTypeAppPushWindowsDelivery CampaignType = 21
)
15 changes: 15 additions & 0 deletions dto/campaignversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package dto

type CampaignVersionDTO struct {
CampaignID int64 `json:"campaignId"`
CampaignName string `json:"campaignName"`
CampaignTypeID int64 `json:"campaignTypeId"`
Active bool `json:"active"`
Locked bool `json:"locked"`
DateCreated int64 `json:"dateCreated"`
DateModified int64 `json:"dateModified"`
UserCreated string `json:"userCreated"`
UserModified string `json:"userModified"`
Stats StatDTO `json:"statDtos"`
LastActivated int64 `json:"lastActivated"`
}
11 changes: 11 additions & 0 deletions dto/channeltype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dto

type ChannelType int64

const (
ChannelTypeUnknown ChannelType = 0
ChannelTypeEmail ChannelType = 1
ChannelTypeSMS ChannelType = 2
ChannelTypePush ChannelType = 3
ChannelTypeMixed ChannelType = 4
)
36 changes: 36 additions & 0 deletions dto/contact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package dto

type ContactDTO struct {
ID int64 `json:"id,omitempty"`
ListID int64 `json:"listId"`
Country string `json:"country,omitempty"`
OriginalID string `json:"originalId"`
OriginalIDHashed int64 `json:"originalIDHashed,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
MiddleName string `json:"middleName,omitempty"`
EmailAddress string `json:"emailAddress,omitempty"`
Title string `json:"title,omitempty"`
DateOfBirth string `json:"dateOfBirth,omitempty"`
City string `json:"city,omitempty"`
ZipCode string `json:"zipcode,omitempty"`
Sex string `json:"sex,omitempty"`
MobileNumber string `json:"mobileNumber,omitempty"`
Unsubscribed bool `json:"unsubscribed"`
Bounced bool `json:"bounced"`
MobileUnsubscribed bool `json:"mobileUnsubscribed"`
AudioUnsubscribed bool `json:"audioUnsubscribed"`
PreferredContentVersionID int64 `json:"preferredContentVersionId,omitempty"`
OptOutDate int64 `json:"optOutDate"`
DateOfInvalidation int64 `json:"dateOfInvalidation"`
OptOutMobileDate int64 `json:"optOutMobileDate"`
OptOutAudioDate int64 `json:"optOutAudioDate"`
Active bool `json:"active"`
DateCreated int64 `json:"dateCreated,omitempty"`
DateModified int64 `json:"dateModified,omitempty"`
BlockedUntil int64 `json:"blockedUntil,omitempty"`
Properties map[string]string `json:"properties,omitempty"`
NamedProperties map[string]string `json:"namedProperties,omitempty"`
MobileNumberValid bool `json:"mobileNumberValid,omitempty"`
//deviceInfo (java.util.LinkedList, optional),
}
10 changes: 10 additions & 0 deletions dto/datatype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dto

type DataType string

const (
DataTypeString DataType = "STRING"
DataTypeInteger DataType = "INTEGER"
DataTypeBigInt DataType = "BIGINT"
DataTypeDateTime DataType = "DATETIME"
)
5 changes: 5 additions & 0 deletions dto/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dto

type MessageDTO struct {
Message string `json:"message"`
}
16 changes: 16 additions & 0 deletions dto/property.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dto

type PropertyDTO struct {
ID int64 `json:"id"`
PropertyTypeID PropertyType `json:"propertyTypeId"` // type of property
Name string `json:"name"`
Description string `json:"description,omitempty"`
DataType DataType `json:"dataType,omitempty"` // Data type to use for this property in Business Analytics export. Null means 'default', i.e. interpret value as a string
IncludeInBaExport bool `json:"includeInBaExport,omitempty"` // Whether this property should be included in Business Analytics export. Defaults to false
DateCreated string `json:"dateCreated"` // read only, populated by server
DateModified string `json:"dateModified"` // read only, populated by server
UserCreated string `json:"userCreated"` // read only, populated by server
UserModified string `json:"userModified"` // read only, populated by server
StaticProperty bool `json:"staticProperty"` // is this a static property
FileHeaders []string `json:"fileHeaders,omitempty"`
}
9 changes: 9 additions & 0 deletions dto/propertytype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dto

type PropertyType int64

const (
PropertyTypeEndUser PropertyType = 1
PropertyTypeEncrypted PropertyType = 1
PropertyTypeDeleted PropertyType = 1
)
12 changes: 12 additions & 0 deletions dto/sendtrigger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package dto

type SendTriggerDTO struct {
DeliveryTime string `json:"deliveryTime,omitempty"` // When is the trigger to be sent? Trigger will be sent immediately if the value is omitted, format shall be yyyy-MM-ddTHH:mm:ss-zzzz -zzzz is timezone difference from UCT sweden is +01000 , e.g. 2016-02-09T11:00:00+0100,
OptOut bool `json:"optOut,omitempty"` // if true the user will unsubscribed,
SaveProps bool `json:"saveProps,omitempty"` // True to update propertydata on the contact,
OriginalId string `json:"originalId"` // originalId of the contact the trigger is to be sent to,
CustomerId int64 `json:"customerId"`
CampaignId int64 `json:"campaignId,omitempty"` // If supplied the trigger willsend this delivery instead of the triggers active delivery,
Properties map[string]string `json:"properties"` // the data for the trigger,
ForceCreateMissingProperties bool `json:"forceCreateMissingProperties,omitempty"` // Automatically create missing properties. If false, missing property names will throw exception
}
25 changes: 25 additions & 0 deletions dto/stat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dto

type StatDTO struct {
ID int64 `json:"id"`
DeliveryID int64 `json:"deliveryId"`
Source int64 `json:"source"`
ProjectID int64 `json:"projectId"`
DeliveryTypeID int64 `json:"deliveryTypeId"`
Recipients int64 `json:"recipients"`
Sent int64 `json:"sent"`
Opened int64 `json:"opened"`
Clicked int64 `json:"clicked"`
OpenedInBrowser int64 `json:"openedInBrower"`
NonDeliverable int64 `json:"nonDeliverable"`
Unsubscribe int64 `json:"unsubscribed"`
NotBounced int64 `json:"notBounced"`
SoftBounced int64 `json:"softBounced"`
HardBounced int64 `json:"hardBounced"`
Complaints int64 `json:"complaints"`
ShareTarget int64 `json:"shareTarget"`
MailClick int64 `json:"mailClick"`
Conversions int64 `json:"conversions"`
UniqueClick int64 `json:"uniqueClick"`
Amount float64 `json:"amount"`
}
19 changes: 19 additions & 0 deletions dto/trigger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dto

type TriggerDTO struct {
ID int64 `json:"id"`
Type int64 `json:"type"`
ProjectID int64 `json:"projectId"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
ListID int64 `json:"listId"`
DateCreated int64 `json:"dateCreated,omitempty"`
DateModified int64 `json:"dateModified,omitempty"`
UserCreated string `json:"userCreated,omitempty"`
UserModified string `json:"userModified,omitempty"`
ChannelTypeID ChannelType `json:"channelTypeId"`
ActiveCampaign int64 `json:"activeCampaign"`
IgnoreOptOut bool `json:"ignoreOptOut,omitempty"`
CampaignVersions []CampaignVersionDTO `json:"campaignVersions,omitempty"`
Active bool `json:"active,omitempty"`
}
48 changes: 48 additions & 0 deletions lists.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package carmaclient

import (
"encoding/json"
"errors"
"fmt"
"github.com/moonwalker/carmaclient/dto"
"net/http"
"net/url"
)

type ListsService service

func (s *ListsService) GetContact(listID int64, originalID string) (*dto.ContactDTO, error) {
response := s.client.carmaRequest(fmt.Sprintf("lists/%d/contacts/%s", listID, url.QueryEscape(originalID)), http.MethodGet, nil)
if response.err != nil {
return nil, response.err
}

if response.statusCode == http.StatusNotFound {
return nil, errors.New(http.StatusText(response.statusCode))
}

responseDTO := &dto.ContactDTO{}

err := json.Unmarshal(response.data, responseDTO)
if err != nil {
return nil, err
}

return responseDTO, nil
}

func (s *ListsService) PutContactUpdate(listID int64, originalID string, contact dto.ContactDTO) (*dto.ContactDTO, error) {
response := s.client.carmaRequest(fmt.Sprintf("lists/%d/contacts/%s/update?force=true", listID, url.QueryEscape(originalID)), http.MethodPut, contact)
if response.err != nil {
return nil, response.err
}

responseDTO := &dto.ContactDTO{}

err := json.Unmarshal(response.data, responseDTO)
if err != nil {
return nil, err
}

return responseDTO, nil
}
29 changes: 29 additions & 0 deletions properties.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package carmaclient

import (
"fmt"
"net/http"
"encoding/json"

"github.com/moonwalker/carmaclient/dto"
)

type PropertiesService service

func (s *PropertiesService) GetProperties() (*[]dto.PropertyDTO, error) {
response := s.client.carmaRequest("properties", http.MethodGet, nil)
if response.err != nil {
return nil, response.err
}

fmt.Println(string(response.data))

responseDTO := &[]dto.PropertyDTO{}

err := json.Unmarshal(response.data, responseDTO)
if err != nil {
return nil, err
}

return responseDTO, nil
}
Loading

0 comments on commit 25c93dc

Please sign in to comment.