Chore: Routine Bugfixes and enhancements (#979)
- Fix slack scopes - Docs for authentication Fixes: #704 , #973
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
55
app/services/base/send_on_channel_service.rb
Normal file
55
app/services/base/send_on_channel_service.rb
Normal 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
|
||||
@@ -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) },
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user