Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add custom message type #167

Merged
merged 8 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions files_send_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,18 @@ func (b *sendFileBuilder) QueryParam(queryParam map[string]string) *sendFileBuil
// Transport sets the Transport for the sendFile request.
func (b *sendFileBuilder) Transport(tr http.RoundTripper) *sendFileBuilder {
b.opts.Transport = tr

return b
}

// CustomMessageType sets the User-specified message type string - limited by 3-50 case-sensitive alphanumeric characters
// with only `-` and `_` special characters allowed.
func (b *sendFileBuilder) CustomMessageType(messageType string) *sendFileBuilder {
b.opts.CustomMessageType = messageType

return b
}

// Execute runs the sendFile request.
func (b *sendFileBuilder) Execute() (*PNSendFileResponse, StatusResponse, error) {
rawJSON, status, err := executeRequest(b.opts)
Expand All @@ -110,19 +119,24 @@ func (b *sendFileBuilder) Execute() (*PNSendFileResponse, StatusResponse, error)
type sendFileOpts struct {
endpointOpts

Channel string
Name string
Message string
File *os.File
CipherKey string
TTL int
Meta interface{}
ShouldStore bool
QueryParam map[string]string
Channel string
Name string
Message string
File *os.File
CipherKey string
TTL int
Meta interface{}
ShouldStore bool
QueryParam map[string]string
CustomMessageType string

Transport http.RoundTripper
}

func (o *sendFileOpts) isCustomMessageTypeCorrect() bool {
return isCustomMessageTypeValid(o.CustomMessageType)
}

func (o *sendFileOpts) validate() error {
if o.config().SubscribeKey == "" {
return newValidationError(o, StrMissingSubKey)
Expand All @@ -135,6 +149,11 @@ func (o *sendFileOpts) validate() error {
if o.Name == "" {
return newValidationError(o, StrMissingFileName)
}

if !o.isCustomMessageTypeCorrect() {
return newValidationError(o, StrInvalidCustomMessageType)
}

return nil
}

Expand All @@ -149,6 +168,10 @@ func (o *sendFileOpts) buildQuery() (*url.Values, error) {

SetQueryParam(q, o.QueryParam)

if len(o.CustomMessageType) > 0 {
q.Set("custom_message_type", o.CustomMessageType)
}

return q, nil
}

Expand Down
14 changes: 14 additions & 0 deletions files_send_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func AssertSendFile(t *testing.T, checkQueryParam, testContext bool) {
channel := "chan"
o.Channel(channel)
o.QueryParam(queryParam)
o.CustomMessageType("custom")

path, err := o.opts.buildPath()
assert.Nil(err)
Expand All @@ -45,6 +46,7 @@ func AssertSendFile(t *testing.T, checkQueryParam, testContext bool) {
u, _ := o.opts.buildQuery()
assert.Equal("v1", u.Get("q1"))
assert.Equal("v2", u.Get("q2"))
assert.Equal("custom", u.Get("custom_message_type"))
}

}
Expand All @@ -66,3 +68,15 @@ func TestSendFileResponseValueError(t *testing.T) {
_, _, err := newPNSendFileResponse(jsonBytes, opts, StatusResponse{})
assert.Equal("pubnub/parsing: Error unmarshalling response: {s}", err.Error())
}

func TestSendFileCustomMessageTypeValidation(t *testing.T) {
assert := assert.New(t)
pn := NewPubNub(NewDemoConfig())
opts := newSendFileOpts(pn, pn.ctx)
opts.CustomMessageType = "custom-message_type"
assert.True(opts.isCustomMessageTypeCorrect())
opts.CustomMessageType = "a"
assert.False(opts.isCustomMessageTypeCorrect())
opts.CustomMessageType = "!@#$%^&*("
assert.False(opts.isCustomMessageTypeCorrect())
}
1 change: 1 addition & 0 deletions listener_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ type PNMessage struct {
Subscription string
Publisher string
Timetoken int64
CustomMessageType string
Error error
}

Expand Down
24 changes: 23 additions & 1 deletion publish_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ type publishOpts struct {
DoNotReplicate bool
QueryParam map[string]string

CustomMessageType string

Transport http.RoundTripper

// nil hacks
// nil hacks
setTTL bool
setShouldStore bool
}
Expand Down Expand Up @@ -168,6 +170,14 @@ func (b *publishBuilder) QueryParam(queryParam map[string]string) *publishBuilde
return b
}

// CustomMessageType sets the User-specified message type string - limited by 3-50 case-sensitive alphanumeric characters
// with only `-` and `_` special characters allowed.
func (b *publishBuilder) CustomMessageType(messageType string) *publishBuilder {
b.opts.CustomMessageType = messageType

return b
}

// Execute runs the Publish request.
func (b *publishBuilder) Execute() (*PublishResponse, StatusResponse, error) {
rawJSON, status, err := executeRequest(b.opts)
Expand All @@ -178,6 +188,10 @@ func (b *publishBuilder) Execute() (*PublishResponse, StatusResponse, error) {
return newPublishResponse(rawJSON, status)
}

func (o *publishOpts) isCustomMessageTypeCorrect() bool {
return isCustomMessageTypeValid(o.CustomMessageType)
}

func (o *publishOpts) validate() error {
if o.config().PublishKey == "" {
return newValidationError(o, StrMissingPubKey)
Expand All @@ -195,6 +209,10 @@ func (o *publishOpts) validate() error {
return newValidationError(o, StrMissingMessage)
}

if !o.isCustomMessageTypeCorrect() {
return newValidationError(o, StrInvalidCustomMessageType)
}

return nil
}

Expand Down Expand Up @@ -324,6 +342,10 @@ func (o *publishOpts) buildQuery() (*url.Values, error) {
o.pubnub.Config.Log.Println("seqn:", seqn)
q.Set("seqn", seqn)

if len(o.CustomMessageType) > 0 {
q.Set("custom_message_type", o.CustomMessageType)
}

SetQueryParam(q, o.QueryParam)

if o.DoNotReplicate == true {
Expand Down
17 changes: 17 additions & 0 deletions publish_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func AssertSuccessPublishGet(t *testing.T, expectedString string, message interf
assert.Equal(10, o.opts.TTL)
assert.Equal(true, o.opts.ShouldStore)
assert.Equal(true, o.opts.DoNotReplicate)
assert.Equal("", o.opts.CustomMessageType)
}

func AssertSuccessPublishGetContext(t *testing.T, expectedString string, message interface{}) {
Expand All @@ -48,6 +49,7 @@ func AssertSuccessPublishGetContext(t *testing.T, expectedString string, message
o.TTL(10)
o.ShouldStore(true)
o.DoNotReplicate(true)
o.CustomMessageType("custom")

path, err := o.opts.buildPath()
assert.Nil(err)
Expand All @@ -63,6 +65,7 @@ func AssertSuccessPublishGetContext(t *testing.T, expectedString string, message
assert.Equal(10, o.opts.TTL)
assert.Equal(true, o.opts.ShouldStore)
assert.Equal(true, o.opts.DoNotReplicate)
assert.Equal("custom", o.opts.CustomMessageType)
}

func AssertSuccessPublishGet2(t *testing.T, expectedString string, message interface{}) {
Expand All @@ -77,6 +80,7 @@ func AssertSuccessPublishGet2(t *testing.T, expectedString string, message inter
o.TTL(10)
o.ShouldStore(false)
o.DoNotReplicate(true)
o.CustomMessageType("custom")

path, err := o.opts.buildPath()
assert.Nil(err)
Expand All @@ -96,6 +100,7 @@ func AssertSuccessPublishGet2(t *testing.T, expectedString string, message inter
expected.Set("pnsdk", Version)
expected.Set("norep", "true")
expected.Set("store", "0")
expected.Set("custom_message_type", "custom")

h.AssertQueriesEqual(t, expected, query,
[]string{"seqn", "pnsdk", "uuid", "store"}, []string{})
Expand Down Expand Up @@ -529,3 +534,15 @@ func TestPublishValidateSubscribeKey(t *testing.T) {

assert.Equal("pubnub/validation: pubnub: Publish: Missing Subscribe Key", opts.validate().Error())
}

func TestPublishValidateCustomMessageType(t *testing.T) {
assert := assert.New(t)
pn := NewPubNub(NewDemoConfig())
opts := newPublishOpts(pn, pn.ctx)
opts.CustomMessageType = "custom-message_type"
assert.True(opts.isCustomMessageTypeCorrect())
opts.CustomMessageType = "a"
assert.False(opts.isCustomMessageTypeCorrect())
opts.CustomMessageType = "!@#$%^&*("
assert.False(opts.isCustomMessageTypeCorrect())
}
2 changes: 2 additions & 0 deletions pubnub.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ const (
StrMissingFileName = "Missing File Name"
// StrMissingToken shows `Missing PAMv3 token` message
StrMissingToken = "Missing PAMv3 token"
// StrInvalidCustomMessageType shows `Invalid CustomMessageType` message
StrInvalidCustomMessageType = "Invalid CustomMessageType: size different than 3-50 or contains invalid characters"
)

// PubNub No server connection will be established when you create a new PubNub object.
Expand Down
21 changes: 21 additions & 0 deletions signal_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ func (b *signalBuilder) QueryParam(queryParam map[string]string) *signalBuilder
return b
}

// CustomMessageType sets the User-specified message type string - limited by 3-50 case-sensitive alphanumeric characters
// with only `-` and `_` special characters allowed.
func (b *signalBuilder) CustomMessageType(messageType string) *signalBuilder {
b.opts.CustomMessageType = messageType

return b
}

// Execute runs the Signal request.
func (b *signalBuilder) Execute() (*SignalResponse, StatusResponse, error) {
rawJSON, status, err := executeRequest(b.opts)
Expand All @@ -86,6 +94,11 @@ type signalOpts struct {
UsePost bool
QueryParam map[string]string
Transport http.RoundTripper
CustomMessageType string
}

func (o *signalOpts) isCustomMessageTypeCorrect() bool {
return isCustomMessageTypeValid(o.CustomMessageType)
}

func (o *signalOpts) validate() error {
Expand All @@ -97,6 +110,10 @@ func (o *signalOpts) validate() error {
return newValidationError(o, StrMissingPubKey)
}

if !o.isCustomMessageTypeCorrect() {
return newValidationError(o, StrInvalidCustomMessageType)
}

return nil
}

Expand Down Expand Up @@ -130,6 +147,10 @@ func (o *signalOpts) buildQuery() (*url.Values, error) {

SetQueryParam(q, o.QueryParam)

if len(o.CustomMessageType) > 0 {
q.Set("custom_message_type", o.CustomMessageType)
}

return q, nil
}

Expand Down
15 changes: 14 additions & 1 deletion signal_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func AssertSuccessSignalGet(t *testing.T, channel string, checkQueryParam bool)
opts.Channel = channel
opts.Message = msgMap
opts.QueryParam = queryParam
opts.CustomMessageType = "custom"

path, err := opts.buildPath()
assert.Nil(err)
Expand All @@ -43,8 +44,8 @@ func AssertSuccessSignalGet(t *testing.T, channel string, checkQueryParam bool)
u, _ := opts.buildQuery()
assert.Equal("v1", u.Get("q1"))
assert.Equal("v2", u.Get("q2"))
assert.Equal("custom", u.Get("custom_message_type"))
}

}

func TestSignalPath(t *testing.T) {
Expand Down Expand Up @@ -144,3 +145,15 @@ func TestSignalResponseValuePass(t *testing.T) {
_, _, err := newSignalResponse(jsonBytes, opts, StatusResponse{})
assert.Nil(err)
}

func TestSignalCustomMessageTypeValidation(t *testing.T) {
assert := assert.New(t)
pn := NewPubNub(NewDemoConfig())
opts := newSignalOpts(pn, pn.ctx)
opts.CustomMessageType = "custom-message_type"
assert.True(opts.isCustomMessageTypeCorrect())
opts.CustomMessageType = "a"
assert.False(opts.isCustomMessageTypeCorrect())
opts.CustomMessageType = "!@#$%^&*("
assert.False(opts.isCustomMessageTypeCorrect())
}
8 changes: 5 additions & 3 deletions subscription_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ type subscribeMessage struct {
UserMetadata interface{} `json:"u"`
MessageType PNMessageType `json:"e"`
SequenceNumber int `json:"s"`
CustomMessageType string `json:"ctm"`

PublishMetaData publishMetadata `json:"p"`
}
Expand Down Expand Up @@ -638,7 +639,7 @@ func processNonPresencePayload(m *SubscriptionManager, payload subscribeMessage,

switch payload.MessageType {
case PNMessageTypeSignal:
pnMessageResult := createPNMessageResult(payload.Payload, actualCh, subscribedCh, channel, subscriptionMatch, payload.IssuingClientID, payload.UserMetadata, timetoken, /*no error*/nil)
pnMessageResult := createPNMessageResult(payload.Payload, actualCh, subscribedCh, channel, subscriptionMatch, payload.IssuingClientID, payload.UserMetadata, timetoken, payload.CustomMessageType, /*no error*/nil)
m.pubnub.Config.Log.Println("announceSignal,", pnMessageResult)
m.listenerManager.announceSignal(pnMessageResult)
case PNMessageTypeObjects:
Expand Down Expand Up @@ -693,7 +694,7 @@ func processNonPresencePayload(m *SubscriptionManager, payload subscribeMessage,
m.listenerManager.announceStatus(pnStatus)

}
pnMessageResult := createPNMessageResult(messagePayload, actualCh, subscribedCh, channel, subscriptionMatch, payload.IssuingClientID, payload.UserMetadata, timetoken, err)
pnMessageResult := createPNMessageResult(messagePayload, actualCh, subscribedCh, channel, subscriptionMatch, payload.IssuingClientID, payload.UserMetadata, timetoken, payload.CustomMessageType, err)
m.pubnub.Config.Log.Println("announceMessage,", pnMessageResult)
m.listenerManager.announceMessage(pnMessageResult)
}
Expand Down Expand Up @@ -934,7 +935,7 @@ func createPNObjectsResult(objPayload interface{}, m *SubscriptionManager, actua
return pnUUIDEvent, pnChannelEvent, pnMembershipEvent, eventType
}

func createPNMessageResult(messagePayload interface{}, actualCh, subscribedCh, channel, subscriptionMatch, issuingClientID string, userMetadata interface{}, timetoken int64, error error) *PNMessage {
func createPNMessageResult(messagePayload interface{}, actualCh, subscribedCh, channel, subscriptionMatch, issuingClientID string, userMetadata interface{}, timetoken int64, CustomMessageType string, error error) *PNMessage {

pnMessageResult := &PNMessage{
Message: messagePayload,
Expand All @@ -945,6 +946,7 @@ func createPNMessageResult(messagePayload interface{}, actualCh, subscribedCh, c
Timetoken: timetoken,
Publisher: issuingClientID,
UserMetadata: userMetadata,
CustomMessageType: CustomMessageType,
Error: error,
}

Expand Down
Loading
Loading