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

How to send proactive message? #198

Open
josephktcheung opened this issue Sep 19, 2019 · 8 comments
Open

How to send proactive message? #198

josephktcheung opened this issue Sep 19, 2019 · 8 comments
Labels

Comments

@josephktcheung
Copy link

josephktcheung commented Sep 19, 2019

I'd like to know how can I send proactive message to a specific user.

Use case:
A dating chatbot connects 2 users to chat with each other.
When user A sends a message to the chatbot, the chatbot should forward this message to user B.

@josephktcheung
Copy link
Author

@mgomes
Copy link
Member

mgomes commented Sep 19, 2019

@josephktcheung which platform would you like to do this on?

@josephktcheung
Copy link
Author

Ideally should be platform agnostic i.e. a Facebook user can be connected to a Twilio user. Right now I’m doing it on a custom channel (I wrote a custom Stealth Service for it).

This feature would make omnichannel communication to happen much easier by allowing one session to trigger a state change in another session.

@josephktcheung
Copy link
Author

josephktcheung commented Sep 20, 2019

Right now I'm doing it this way, first I create a custom message type called trigger which would step to the flow, state and params based on the message body. Then I create a new dispatcher to dispatch the message to the target user session.

BTW I'm using PR #183 to allow me to pass params to step_to

In chat_rooms_controller.rb

class ChatRoomsController < BotController
  def get_message
    dispatcher = Stealth::Dispatcher.new(
      service: "service",
      params: {
        messages: [{
          type: "trigger",
          body: JSON.dump({
            flow: 'chat_room',
            state: 'say_forwarded_message',
            params: {
              message: current_message.message
            },
          }),
          time: Time.now.to_i,
          sender: { id: "USER_B_ID" }
        }],
      },
      headers: {}
    )
    dispatcher.coordinate
    # Loop the same state to capture message from current user
    update_session_to state: 'get_message'
  end

  def say_forwarded_message
    @message = current_session.params["message"]
    send_replies
    # Step to get_message to capture message from current user
    update_session_to state: 'get_message'
  end
end

In bot_controller.rb

def route
    if current_session.present?
      if current_message.type == 'trigger'
        json = JSON.parse(current_message.message)
        step_to flow: json['flow'],
                state: json['state'],
                params: json['params']
      else
        step_to session: current_session
      end
    else
      step_to flow: 'hello', state: 'say_hello'
    end
  end

@josephktcheung
Copy link
Author

josephktcheung commented Sep 20, 2019

Ideally we can make another session to step_to / update_session_to a specific flow / state with params in the current session without the need to make a custom message type, use Stealth::Dispatcher to dispatch it and modify route method to handle it.

chat_rooms_controller.rb

class ChatRoomsController < BotController
  def get_message
    step_to session_id: 'USER_B_ID',
            flow: 'chat_room',
            state: 'say_forwarded_message',
            params: { message: current_message.message }
    # Loop the same state to capture message from current user
    update_session_to state: 'get_message'
  end

  def say_forwarded_message
    @message = current_session.params["message"]
    send_replies
    # Step to get_message to capture message from current user
    update_session_to state: 'get_message'
  end
end

@mgomes
Copy link
Member

mgomes commented Sep 24, 2019

This is interesting and I can understand the need for it in Slack. I'd love to see your Slack driver, btw. Is it open source?

The tricky part is that for platforms like Facebook, it's actually not possible to do this without certain exceptions (message tagging). If I understand your need correctly though, I think there is simpler way for you to achieve what you're looking to do. It's still a little hacky because it requires you to create dummy message.

def move_user(session_id)
  service_message = Stealth::ServiceMessage.new(service: 'facebook')
  service_message.sender_id = session_id
  bot_controller = BotController.new(service_message: service_message)
  bot_controller.step_to(flow: :your_flow, state: :your_state)
end

@mgomes
Copy link
Member

mgomes commented Sep 24, 2019

I have been considering adding this to Stealth itself. I think it falls under the umbrella of broadcast messages. The difficulty so far has been figuring out how much to build in. For example, it seems like the developer still has to be responsible for fetching users from a database or somewhere else and then iterating through each and broadcasting the message. Or we could add a the ability to accept multiple session IDs:

broadcast_to session_ids: [], service: 'facebook', flow: flow, state: state

@josephktcheung
Copy link
Author

@mgomes Thanks for your answer. I'm not integrating Slack but Chat API which is an unofficial WhatsApp API provider. I want this feature because I want to send a private message to a group user when the bot has joined a group chat. And you're right that Slack bot would benefit from this feature too by allowing it to send message to a channel while talking to a user privately.

Adding broadcast_to would be nice because then I don't need to create move_user method in my controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants