Chore: Routine Bugfixes and enhancements (#979)

- Fix slack scopes
- Docs for authentication
Fixes: #704 , #973
This commit is contained in:
Sojan Jose
2020-06-25 23:35:16 +05:30
committed by GitHub
parent 0aab717bb3
commit 4f83d5451e
32 changed files with 254 additions and 147 deletions

View File

@@ -14,7 +14,7 @@ class Api::V1::Accounts::LabelsController < Api::V1::Accounts::BaseController
end
def update
@label.update(permitted_params)
@label.update!(permitted_params)
end
def destroy

View File

@@ -59,11 +59,19 @@ class ApplicationController < ActionController::Base
render json: exception.to_hash, status: exception.http_status
end
def locale_from_params
I18n.available_locales.map(&:to_s).include?(params[:locale]) ? params[:locale] : nil
end
def locale_from_account(account)
I18n.available_locales.map(&:to_s).include?(account.locale) ? account.locale : nil
end
def switch_locale(account)
# priority is for locale set in query string (mostly for widget/from js sdk)
locale ||= (I18n.available_locales.map(&:to_s).include?(params[:locale]) ? params[:locale] : nil)
locale ||= locale_from_params
# if local is not set in param, lets try account
locale ||= (I18n.available_locales.map(&:to_s).include?(account.locale) ? account.locale : nil)
locale ||= locale_from_account(account)
I18n.locale = locale || I18n.default_locale
end

View File

@@ -4,6 +4,7 @@ class WidgetsController < ActionController::Base
before_action :set_token
before_action :set_contact
before_action :build_contact
after_action :allow_iframe_requests
def index; end
@@ -50,4 +51,8 @@ class WidgetsController < ActionController::Base
def permitted_params
params.permit(:website_token, :cw_conversation)
end
def allow_iframe_requests
response.headers.delete('X-Frame-Options')
end
end

View File

@@ -62,7 +62,7 @@ class ConversationFinder
def find_all_conversations
@conversations = current_account.conversations.includes(
:assignee, :contact, :inbox
:assignee, :inbox, contact: [:avatar_attachment]
).where(inbox_id: @inbox_ids)
end

View File

@@ -1,6 +1,6 @@
import { required, minLength } from 'vuelidate/lib/validators';
export const validLabelCharacters = (str = '') => /^[\w-_]+$/g.test(str);
export const validLabelCharacters = (str = '') => !!str && !str.includes(' ');
export default {
title: {

View File

@@ -4,7 +4,7 @@ class HookJob < ApplicationJob
def perform(hook, message)
return unless hook.slack?
Integrations::Slack::OutgoingMessageBuilder.perform(hook, message)
Integrations::Slack::SendOnSlackService.new(message: message, hook: hook).perform
rescue StandardError => e
Raven.capture_exception(e)
end

View File

@@ -138,11 +138,11 @@ class Message < ApplicationRecord
def send_reply
channel_name = conversation.inbox.channel.class.to_s
if channel_name == 'Channel::FacebookPage'
::Facebook::SendReplyService.new(message: self).perform
::Facebook::SendOnFacebookService.new(message: self).perform
elsif channel_name == 'Channel::TwitterProfile'
::Twitter::SendReplyService.new(message: self).perform
::Twitter::SendOnTwitterService.new(message: self).perform
elsif channel_name == 'Channel::TwilioSms'
::Twilio::OutgoingMessageService.new(message: self).perform
::Twilio::SendOnTwilioService.new(message: self).perform
end
end

View File

@@ -0,0 +1,55 @@
#######################################
# To create an external channel reply service
# - Inherit this as the base class.
# - Implement `channel_class` method in your child class.
# - Implement `perform_reply` method in your child class.
# - Implement additional custom logic for your `perform_reply` method.
# - When required override the validation_methods.
# - Use Childclass.new.perform.
######################################
class Base::SendOnChannelService
pattr_initialize [:message!]
def perform
validate_target_channel
return unless outgoing_message?
return if invalid_message?
perform_reply
end
private
delegate :conversation, to: :message
delegate :contact, :contact_inbox, :inbox, to: :conversation
delegate :channel, to: :inbox
def channel_class
raise 'Overwrite this method in child class'
end
def perform_reply
raise 'Overwrite this method in child class'
end
def outgoing_message_originated_from_channel?
# TODO: we need to refactor this logic as more integrations comes by
# chatwoot messages won't have source id at the moment
# outgoing messages may be created in slack which should be send to the channel
message.source_id.present? && !message.source_id.starts_with?('slack_')
end
def outgoing_message?
message.outgoing? || message.template?
end
def invalid_message?
# private notes aren't send to the channels
# we should also avoid the case of message loops, when outgoing messages are created from channel
message.private? || outgoing_message_originated_from_channel?
end
def validate_target_channel
raise 'Invalid channel service was called' if inbox.channel.class != channel_class
end
end

View File

@@ -1,37 +1,14 @@
class Facebook::SendReplyService
pattr_initialize [:message!]
def perform
return if message.private
return if inbox.channel.class.to_s != 'Channel::FacebookPage'
return unless outgoing_message_from_chatwoot?
FacebookBot::Bot.deliver(delivery_params, access_token: message.channel_token)
end
class Facebook::SendOnFacebookService < Base::SendOnChannelService
private
delegate :contact, to: :conversation
def inbox
@inbox ||= message.inbox
def channel_class
Channel::FacebookPage
end
def conversation
@conversation ||= message.conversation
def perform_reply
FacebookBot::Bot.deliver(delivery_params, access_token: message.channel_token)
end
def outgoing_message_from_chatwoot?
# messages sent directly from chatwoot won't have source_id.
(message.outgoing? || message.template?) && !message.source_id
end
# def reopen_lock
# if message.incoming? && conversation.locked?
# conversation.unlock!
# end
# end
def fb_text_message_params
{
recipient: { id: contact.get_source_id(inbox.id) },

View File

@@ -1,22 +1,15 @@
class Twilio::OutgoingMessageService
pattr_initialize [:message!]
class Twilio::SendOnTwilioService < Base::SendOnChannelService
private
def perform
return if message.private
return if message.source_id
return if inbox.channel.class.to_s != 'Channel::TwilioSms'
return unless outgoing_message?
def channel_class
Channel::TwilioSms
end
def perform_reply
twilio_message = client.messages.create(message_params)
message.update!(source_id: twilio_message.sid)
end
private
delegate :conversation, to: :message
delegate :contact, to: :conversation
delegate :contact_inbox, to: :conversation
def message_params
params = {
body: message.content,

View File

@@ -1,16 +1,17 @@
class Twitter::SendReplyService
class Twitter::SendOnTwitterService < Base::SendOnChannelService
pattr_initialize [:message!]
def perform
return if message.private
return if message.source_id
return if inbox.channel.class.to_s != 'Channel::TwitterProfile'
return unless outgoing_message_from_chatwoot?
private
send_reply
delegate :additional_attributes, to: :contact
def channel_class
Channel::TwitterProfile
end
private
def perform_reply
conversation_type == 'tweet' ? send_tweet_reply : send_direct_message
end
def twitter_client
Twitty::Facade.new do |config|
@@ -50,19 +51,4 @@ class Twitter::SendReplyService
Rails.logger.info 'TWITTER_TWEET_REPLY_ERROR' + response.body
end
end
def send_reply
conversation_type == 'tweet' ? send_tweet_reply : send_direct_message
end
def outgoing_message_from_chatwoot?
(message.outgoing? || message.template?)
end
delegate :additional_attributes, to: :contact
delegate :contact, to: :conversation
delegate :contact_inbox, to: :conversation
delegate :conversation, to: :message
delegate :inbox, to: :conversation
delegate :channel, to: :inbox
end

View File

@@ -12,7 +12,7 @@ json.id conversation.display_id
if conversation.unread_incoming_messages.count.zero?
json.messages [conversation.messages.last.try(:push_event_data)]
else
json.messages conversation.unread_messages.map(&:push_event_data)
json.messages conversation.unread_messages.includes([:user, :attachments]).map(&:push_event_data)
end
json.inbox_id conversation.inbox_id