Skip to content

Commit

Permalink
Merge pull request #73 from Ilhasoft/feature/botdefense-whatsapp
Browse files Browse the repository at this point in the history
Feature/botdefense whatsapp
  • Loading branch information
rasoro authored Sep 1, 2021
2 parents 1abad09 + ae874cb commit b484058
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
6 changes: 4 additions & 2 deletions backends/rapidpro/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ SELECT
c.modified_on,
c.created_on,
c.name,
u.id as "urn_id"
u.id as "urn_id",
c.status
FROM
contacts_contact AS c,
contacts_contacturn AS u
Expand Down Expand Up @@ -232,7 +233,8 @@ type DBContact struct {
CreatedBy_ int `db:"created_by_id"`
ModifiedBy_ int `db:"modified_by_id"`

IsNew_ bool
IsNew_ bool
Status_ string `db:"status"`
}

// UUID returns the UUID for this contact
Expand Down
36 changes: 32 additions & 4 deletions handlers/whatsapp/whatsapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/buger/jsonparser"
"github.com/nyaruka/courier"
"github.com/nyaruka/courier/backends/rapidpro"
"github.com/nyaruka/courier/handlers"
"github.com/nyaruka/courier/utils"
"github.com/nyaruka/gocommon/rcache"
Expand Down Expand Up @@ -62,7 +63,7 @@ func newWAHandler(channelType courier.ChannelType, name string) courier.ChannelH
// Initialize is called by the engine once everything is loaded
func (h *handler) Initialize(s courier.Server) error {
h.SetServer(s)
s.AddHandlerRoute(h, http.MethodPost, "receive", h.receiveEvent)
s.AddHandlerRoute(h, http.MethodPost, "receive", h.checkBlockedContact)
return nil
}

Expand Down Expand Up @@ -159,8 +160,8 @@ type eventPayload struct {
MimeType string `json:"mime_type" validate:"required"`
Sha256 string `json:"sha256" validate:"required"`
} `json:"voice"`
Contacts []struct{
Phones []struct{
Contacts []struct {
Phones []struct {
Phone string `json:"phone"`
} `json:"phones"`
} `json:"contacts"`
Expand All @@ -173,6 +174,33 @@ type eventPayload struct {
} `json:"statuses"`
}

// checkBlockedContact is a handler middleware to prevent generate channel log from blocked contact messages
func (h *handler) checkBlockedContact(ctx context.Context, channel courier.Channel, w http.ResponseWriter, r *http.Request) ([]courier.Event, error) {

payload := &eventPayload{}
err := handlers.DecodeAndValidateJSON(payload, r)
if err != nil {
return nil, handlers.WriteAndLogRequestError(ctx, h, channel, w, r, err)
}

if len(payload.Contacts) > 0 {
if contactURN, err := urns.NewWhatsAppURN(payload.Contacts[0].WaID); err == nil {
if contact, err := h.Backend().GetContact(ctx, channel, contactURN, channel.StringConfigForKey(courier.ConfigAuthToken, ""), ""); err == nil {
c, _ := json.Marshal(contact)
var dbc rapidpro.DBContact
err2 := json.Unmarshal(c, &dbc)
if err2 == nil {
if dbc.Status_ == "B" {
return nil, errors.New("blocked contact sending message")
}
}
}
}
}

return h.receiveEvent(ctx, channel, w, r)
}

// receiveMessage is our HTTP handler function for incoming messages
func (h *handler) receiveEvent(ctx context.Context, channel courier.Channel, w http.ResponseWriter, r *http.Request) ([]courier.Event, error) {
payload := &eventPayload{}
Expand Down Expand Up @@ -245,7 +273,7 @@ func (h *handler) receiveEvent(ctx context.Context, channel courier.Channel, w h
phones = append(phones, phone.Phone)
}
text = strings.Join(phones, ", ")
}else {
} else {
// we received a message type we do not support.
courier.LogRequestError(r, channel, fmt.Errorf("unsupported message type %s", msg.Type))
}
Expand Down
14 changes: 10 additions & 4 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,21 @@ func (s *server) channelHandleWrapper(handler ChannelHandler, handlerFunc Channe

// if we received an error, write it out and report it
if err != nil {
logrus.WithError(err).WithField("channel_uuid", channel.UUID()).WithField("url", url).WithField("request", string(request)).Error("error handling request")
writeAndLogRequestError(ctx, ww, r, channel, err)
if err.Error() != "blocked contact sending message" {
logrus.WithError(err).WithField("channel_uuid", channel.UUID()).WithField("url", url).WithField("request", string(request)).Error("error handling request")
writeAndLogRequestError(ctx, ww, r, channel, err)
}
}

// if we have a channel matched but no events were created we still want to log this to the channel, do so
if channel != nil && len(events) == 0 {
if err != nil {
logs = append(logs, NewChannelLog("Channel Error", channel, NilMsgID, r.Method, url, ww.Status(), string(request), prependHeaders(response.String(), ww.Status(), w), duration, err))
librato.Gauge(fmt.Sprintf("courier.channel_error_%s", channel.ChannelType()), secondDuration)
if err.Error() == "blocked contact sending message" {
return
} else {
logs = append(logs, NewChannelLog("Channel Error", channel, NilMsgID, r.Method, url, ww.Status(), string(request), prependHeaders(response.String(), ww.Status(), w), duration, err))
librato.Gauge(fmt.Sprintf("courier.channel_error_%s", channel.ChannelType()), secondDuration)
}
} else {
logs = append(logs, NewChannelLog("Request Ignored", channel, NilMsgID, r.Method, url, ww.Status(), string(request), prependHeaders(response.String(), ww.Status(), w), duration, err))
librato.Gauge(fmt.Sprintf("courier.channel_ignored_%s", channel.ChannelType()), secondDuration)
Expand Down

0 comments on commit b484058

Please sign in to comment.