Qismo Ruby
A Ruby API wrapper for Qiscus Omnichannel API
Installation
Install the gem and add to the application's Gemfile by executing:
bundle add qismo
Usage
qismo = 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 qismo.list_rooms(params)
# [
# #<Qismo::Objects::CustomerRoom
# channel_id=126392
# contact_id=21608346
# id=68303333
# is_handled_by_bot=true
# is_resolved=false
# is_waiting=false
# last_comment_sender="[email protected]"
# last_comment_sender_type="system"
# last_comment_text="bayu joined this conversation"
# last_comment_timestamp="2022-12-22T06:37:58Z"
# last_customer_comment_text=nil
# last_customer_timestamp="2022-12-19T13:32:51Z"
# name="Oyis"
# room_badge="https://d1edrlpyc25xu0.cloudfront.net/ods-cc6rmwouax2thbow3/image/upload/5sYxRCGJl_/qiscus_badge.svg"
# room_id=103513607
# room_type="individual"
# source="qiscus"
# user_avatar_url="https://d1edrlpyc25xu0.cloudfront.net/kiwari-prod/image/upload/wMWsDZP6ta/1516689726-ic_qiscus_client.png"
# user_id="[email protected]">
# ]
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
qismo.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
require "logger"
qismo.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.
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
qismo.instrumentation = { instrumenter: ActiveSupport::Notifications.instrumenter }
You can also customize the instrumentation's namespace by using this configuration
qismo.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:
qismo.timeout = { connect: 5, write: 2, read: 10 }
Global timeouts let you set an upper bound of how long a request can take
qismo.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
qismo.proxy = ["proxy-hostname.local", 8080]
Proxy needs authentication?
qismo.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:
all_rooms = []
rooms = qismo.list_rooms
all_rooms.append(rooms)
while rooms.next_page.present?
rooms = qismo.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:
begin
qismo.list_rooms
rescue Qismo::BadRequestError => e
puts e.
puts e.status_code
puts e.response_body
rescue Qismo::UnauthorizedError => e
puts e.
puts e.status_code
puts e.response_body
rescue Qismo::PaymentRequiredError => e
puts e.
puts e.status_code
puts e.response_body
rescue Qismo::ForbiddenError => e
puts e.
puts e.status_code
puts e.response_body
rescue Qismo::NotFoundError => e
puts e.
puts e.status_code
puts e.response_body
rescue Qismo::TooManyRequestError => e
puts e.
puts e.status_code
puts e.response_body
rescue Qismo::InternalServerError => e
puts e.
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.
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?
qismo = Qismo::Client.new(app_id: "", secret_key: "")
qismo.assign_agent(
room_id: webhook.room_id,
agent_id: webhook.candidate_agent.id
)
end
end
def
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.(customer.email, webhook.payload..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..text,
language_code: "en-US"
}
}
)
# Parse bot message which will be sent back to customer
= response.query_result.fulfillment_text
# Send message to Qismo room
qismo = Qismo::Client.new(app_id: "", secret_key: "")
qismo.(
room_id: webhook.payload.room.id,
message:
)
end
end
Developer Experience
TODO documentation