Channel Filtering

### Channel Filters

Channel filters give the ability to intercept, modify, or cancel the broadcasting of events that are sent through channels.

### How to use it

I think it is best to explain by example. Lets say you have a chat based application where users can send messages to each other in different channels. But you want to make sure that all messages are logged.

Your controller might look something like this:

```ruby
class ChatController < WebsocketRails::BaseController

  filter_for_channels :chat_room_one

  def new_message
    # store all messages to the database
    ChatLogger.create({user: current_user, channel: event.channel, message: message})
    
    # we can even alter the event object before it is sent back out
    event[:user_nickname] = current_user.nick_name
  end
end
```
and your client facing javascript/coffeescript might look something like this:

```coffeescript
# create your main objects
dispatcher = new WebSocketRails('localhost:3000/websocket')
public_channel = dispatcher.subscribe('chat_room_one')

# listen for new chat messages
public_channel.bind 'new_message', newMessage()

# when the user clicks the send message button
$('#send_button').on 'click', sendMessage()

sendMessage: ->
    public_channel.trigger('new_message', {'message_body': $("#input_box").val()})

newMessage: (data) ->
    $('#chat_room').append("#{data.user_nickname} : #{data.message_body}")
    
```

As you can see here `filter_for_channels` gives us a "choke" point for your channel based messages. You can edit and alter the event object as you wish.

Also, `stop_event_propagation!` gives us a way to halt the channel event from being triggered back out to connected subscribers.

Lets see how that would work:

Your controller:
```ruby
class WebsocketController < WebsocketRails::BaseController
  filter_for_channels :chat_room_one
  
  def new_message
    if message[:message_body].contains?('bad words')
      current_user.wash_mouth_out_with(soap)
      ChatLogger.create({user: current_user, channel: event.channel, message: message, bad_words: true})
      stop_event_propagation!
    else
      # continue on like normal
      ChatLogger.create({user: current_user, channel: event.channel, message: message})
      message[:user_nickname] = current_user.nickname
    end
  end
end
```

### Channel Events and how to catch them all

It might be a good idea to catch all events on any given channel.

Your controller might look something like this:

```ruby
class WebsocketController < WebsocketRails::BaseController
  filter_for_channels :chat_room_one, :catch_all => :log_messages

  def log_messages
    ChatLogger.create({user: current_user, channel: event.channel, message: message})
  end
end
```

### Building your channels dynamically?

No problem, you can assign filters to channels after they're created. Similar to the `make_private` method: 
```ruby
#available anywhere in your rails app
WebsocketRails[:some_dynamic_channel].filter_with(WebsocketController)
```

And for dynamic catch all methods: 
```ruby
WebsocketRails[:some_dynamic_channel].filter_with(WebsocketController, catch_all: :log_messages)
```