diff --git a/signal_request.go b/signal_request.go index 4e7dde1e..9cfd8395 100644 --- a/signal_request.go +++ b/signal_request.go @@ -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) @@ -86,6 +94,25 @@ type signalOpts struct { UsePost bool QueryParam map[string]string Transport http.RoundTripper + CustomMessageType string +} + +func (o *signalOpts) isCustomMessageTypeCorrect() bool { + if len(o.CustomMessageType) == 0 { + return true + } + + if len(o.CustomMessageType) < 3 || len(o.CustomMessageType) > 50 { + return false + } + + for _, c := range o.CustomMessageType { + if !('a' <= c && 'z' >= c) && !('A' <= c && 'Z' >= c) && c != '-' && c != '_' { + return false + } + } + + return true } func (o *signalOpts) validate() error { @@ -97,6 +124,10 @@ func (o *signalOpts) validate() error { return newValidationError(o, StrMissingPubKey) } + if !o.isCustomMessageTypeCorrect() { + return newValidationError(o, StrInvalidCustomMessageType) + } + return nil } @@ -130,6 +161,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 } diff --git a/signal_request_test.go b/signal_request_test.go index faea4ea6..a01f8c03 100644 --- a/signal_request_test.go +++ b/signal_request_test.go @@ -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) @@ -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) { @@ -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()) +}