# Qismo Ruby A Ruby API wrapper for Qiscus Omnichannel API ## Installation Install the gem and add to the application's Gemfile by executing: ```bash bundle add qismo ``` ## Usage ```ruby client = Qismo::Client.new(app_id: "QISCUS_APP_ID", secret_key: "QISCUS_SECRET_KEY") params = { channel: [{ channel_id: 12345, source: "wa" }], status: "unresolved", serve_status: "served", is_handled_by_bot: true, } pp client.list_rooms(params) # [ # # # ] ``` ## Client optional configuration Qismo ruby also provide some optional configuration that you can pass, they are: **url** Defaultly, Qismo ruby will use your QISCUS_OMNICHANNEL_URL env as base url. If its nil, it will use https://qismo.qiscus.com. If you need to customize URL other than that, you can pass it at client initialization ```ruby client.url = "https://qismo.qiscus.com" ``` **logger** You can also log the request and response the any HTTP request you make in Qismo ruby by using this configuration ```ruby require "logger" client.logger = Logger.new($stdout) ``` **instrumentation** For advanced logging, you can also use laverage ActiveSupport instrumentation. If you are using Rails, you can use ActiveSupport without installing the gem by your self. ```ruby ActiveSupport::Notifications.subscribe('start_request.http') do |name, start, finish, id, payload| pp name: name, start: start.to_f, finish: finish.to_f, id: id, payload: payload end client.instrumentation = { instrumenter: ActiveSupport::Notifications.instrumenter } ``` You can also customize the instrumentation's namespace by using this configuration ```ruby client.instrumentation = { instrumenter: ActiveSupport::Notifications.instrumenter, namespace: "qiscus.http_request" } ``` **timeout** By default, the Qismo ruby gem does not enforce timeout on a request. You can enable per operation timeouts (each read/write/connect call) or global timeouts (sum of all read/write/connect calls) by configuring them through the chaining API. Per operation timeouts are what `Net::HTTP` and the majority of HTTP clients do: ```ruby client.timeout = { connect: 5, write: 2, read: 10 } ``` Global timeouts let you set an upper bound of how long a request can take ```ruby client.timeout = 5 # in seconds ``` **proxy** Making request behind proxy is as simple as making them directly. Just specify hostname (or IP address) of your proxy server and its port, and here you go ```ruby client.proxy = ["proxy-hostname.local", 8080] ``` Proxy needs authentication? ```ruby client.proxy = ["proxy-hostname.local", 8080, "username", "password"] ``` ## Handling pagination Some of the Qiscus Omnichannel API will return list of data with pagination. To handle the pagination, you can to that like this example: ```ruby all_rooms = [] rooms = client.list_rooms all_rooms.append(rooms) while rooms.next_page.present? rooms = client.list_rooms(cursor_after: rooms.next_page) all_rooms.append(rooms) end ``` ## Handling error Qismo ruby raise error while getting non successful http code from Qiscus Omnichannel API. To handle it, you follow this example: ```ruby begin client.list_rooms rescue Qismo::BadRequestError => e puts e.message puts e.status_code puts e.response_body rescue Qismo::UnauthorizedError => e puts e.message puts e.status_code puts e.response_body rescue Qismo::PaymentRequiredError => e puts e.message puts e.status_code puts e.response_body rescue Qismo::ForbiddenError => e puts e.message puts e.status_code puts e.response_body rescue Qismo::NotFoundError => e puts e.message puts e.status_code puts e.response_body rescue Qismo::TooManyRequestError => e puts e.message puts e.status_code puts e.response_body rescue Qismo::InternalServerError => e puts e.message puts e.status_code puts e.response_body end ``` ## Handle incoming webhook request Qiscus Omnichannel provide webhooks that triggered from various action on your account. Qismo ruby gem provide convenient way to handle the request. ```ruby class QiscusWebhooksController < ApplicationController skip_before_action :verify_authenticity_token def handle_agent_allocation_webhook webhook = Qismo::WebhookRequests::OnAgentAllocationNeeded.new(JSON.parse(request.raw_body)) # Do any action you want using payload that has been objectified if webhook.candidate_agent.present? client = Qismo::Client.new(app_id: "", secret_key: "") client.assign_agent( room_id: webhook.room_id, agent_id: webhook.candidate_agent.id ) end end def handle_custom_button_webhook webhook = Qismo::WebhookRequests::OnCustomButtonClicked.new(JSON.parse(request.raw_body)) # Do any action you want using payload that has been objectified. The # following example assuming you want to create Zendesk ticket # everytime your agent click custom button "Create Ticket". We are # assuming, you have setup Zendesk ruby client zendesk_ticket_subject = webhook.additional_info.find do |info| info.key == "Zendesk Ticket Subject" end if zendesk_ticket_subject.present? ZendeskAPI::Ticket.create!( zendesk_client, subject: zendesk_ticket_subject.value, submitter_id: webhook.agent.email, priority: "urgent" ) end end def handle_custom_channel_webhook webhook = Qismo::WebhookRequests::OnCustomChannelMessageSent.new(JSON.parse(request.raw_body)) # Do any action you want # The following example assuming you want to reply customer's message from Twitter # Assuming that you have installed and setup twitter ruby client # Fetch customer from room participants customer = webhook.payload.room.participants.find { |participant| participant.email.start_with?("twitter_customer_") } if customer.present? twitter_rest_client.create_direct_message(customer.email, webhook.payload.message.text) end end def handle_bot_webhook webhook = Qismo::WebhookRequests::OnMessageForBotSent.new(JSON.parse(request.raw_body)) # Do any action you want. The following example assuming you want to use # Dialogflow as bot engine # Detect intent for customer's message response = dialogflow_client.detect_intent( session: "session_#{webhook.payload.room.id}", query_input: { text: { text: webhook.payload.message.text, language_code: "en-US" } } ) # Parse bot message which will be sent back to customer bot_message = response.query_result.fulfillment_text # Send message to Qismo room client = Qismo::Client.new(app_id: "", secret_key: "") client.send_bot_message( room_id: webhook.payload.room.id, message: bot_message ) end end ```