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

Feature basic chatwoot integration #13

Merged
merged 14 commits into from
Jul 31, 2023
Merged
2 changes: 1 addition & 1 deletion Procfile.dev
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
web: bin/rails server -p 3000
web: bin/rails server -p 3001
css: bin/rails tailwindcss:watch
1 change: 1 addition & 0 deletions app/assets/config/manifest.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_directory ../stylesheets/components .css

// vendor/theme
//= link_directory ../../../vendor/theme
Expand Down
9 changes: 9 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
@import "stisla/src/scss/components";
@import "stisla/node_modules/izitoast/dist/css/iziToast";
@import "./actiontext.scss";
@import "./commons/w-btn-outline.scss";
@import "./commons/w-btn-block.scss";

.btn-remove {
font-size: 12px;
Expand All @@ -17,4 +19,11 @@
color: #fff;
max-height: 30px;
margin-left: 15px;
}

.embed {
.main-content {
padding-top: 0px !important;
}
background-color: #F6F8FE;
}
10 changes: 10 additions & 0 deletions app/assets/stylesheets/commons/w-btn-block.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.w-btn-block {
color: #888599 !important;
border-radius: 5px;
border: 1.8px solid #F2F1F7;
padding: 10px !important;
i {
font-size: 15px !important;
margin: 0px !important;
}
}
17 changes: 17 additions & 0 deletions app/assets/stylesheets/commons/w-btn-outline.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.w-btn-outline {
font-weight: 600;
font-size: 12px;
line-height: 30px;
padding: 0.3rem 0.8rem;
letter-spacing: .5px;

color: #6857D9;
background-color: #FFFFFF;
border: 1.5px solid #F2F1F7;
border-radius: 5px;
}

.w-btn-outline:hover {
border-radius: 5px;
border: 1.5px solid #D9DEFF;
}
37 changes: 37 additions & 0 deletions app/assets/stylesheets/components/chatwoot_embed.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.component-chatwoot-embed{
padding: 32px;
background-color: #F6F8FE;
p {
margin-bottom: 0px;
}

input[disabled] {
background-color: #FFF;
}
button {
background: none !important;
}

.btn-clock {
border-radius: 5px;
border: 1.5px solid #FBE0D8;
background: #FAEEEB;
color: #CF4F27;
padding-left: 5px;
padding-right: 5px;
svg {
height: 16px;
}
}

.custom-btn-user {
color: #888599 !important;
border-radius: 5px;
border: 1.8px solid #F2F1F7;
padding: 10px !important;
i {
font-size: 15px !important;
margin: 0px !important;
}
}
}
30 changes: 23 additions & 7 deletions app/controllers/accounts/apps/chatwoots_controller.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
class Accounts::Apps::ChatwootsController < InternalController
before_action :set_chatwoot, only: %i[ edit disable new_connection pair_qr_code new_connection_status ]
before_action :set_chatwoot, only: %i[ edit update destroy ]

def new
current_user.account.apps_chatwoots.create(
account: current_user.account
) if current_user.account.apps_chatwoots.blank?

redirect_to edit_account_apps_chatwoot_path(current_user.account, current_user.account.apps_chatwoots.first)
if current_user.account.apps_chatwoots.blank?
@chatwoot = current_user.account.apps_chatwoots.new
else
redirect_to edit_account_apps_chatwoot_path(current_user.account, current_user.account.apps_chatwoots.first)
end
end

def edit
end

def create
@chatwoot = current_user.account.apps_chatwoots.build(chatwoot_params)
if @chatwoot.save
redirect_to edit_account_apps_chatwoot_path(current_user.account, @chatwoot)
else
render :new
end
end

def destroy
@chatwoot.destroy
redirect_to account_settings_path(current_user.account)
end

def update
@chatwoot.update(chatwoot_params)
redirect_to edit_account_apps_chatwoot_path(current_user.account, current_user.account.apps_chatwoots.first)
end

private
Expand All @@ -21,6 +37,6 @@ def set_chatwoot
end

def chatwoot_params
params.require(:apps_chatwoot).permit(:endpoint_url, :user_token)
params.require(:apps_chatwoot).permit(:chatwoot_endpoint_url, :chatwoot_account_id, :chatwoot_user_token, :active)
end
end
78 changes: 78 additions & 0 deletions app/controllers/accounts/contacts/chatwoot_embed_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
class Accounts::Contacts::ChatwootEmbedController < InternalController
layout "embed"
before_action :set_contact, only: %i[ show ]

def search
contact = contact_search

if contact.present?
redirect_to account_chatwoot_embed_path(current_user.account, contact)
else
redirect_to new_account_chatwoot_embed_path(current_user.account, chatwoot_contact: params['chatwoot_contact'])
end
end

def show
end

def new
chatwoot_contact = JSON.parse(params['chatwoot_contact'])
@contact = current_user.account.contacts.new({
full_name: chatwoot_contact['name'],
email: chatwoot_contact['email'],
phone: chatwoot_contact['phone_number'],
additional_attributes: {'chatwoot_id': chatwoot_contact['id']}
})
end

def create
@contact = current_user.account.contacts.new(contact_params)

if @contact.save
redirect_to account_chatwoot_embed_path(current_user.account, @contact), notice: "Contact was successfully created."
else
render :new, status: :unprocessable_entity
end
end

private
def set_contact
@contact = Contact.find(params[:id])
end

def contact_params
params.require(:contact).permit(:full_name, :phone, :email, additional_attributes: {})
end

def chatwoot_contact
@chatwoot_contact ||= JSON.parse(params['chatwoot_contact'])
end

def contact_search()
if chatwoot_contact['email'].present? && chatwoot_contact['phone_number'].present?
return current_user.account.contacts.where(
":chatwoot_id <@ additional_attributes OR email LIKE :email OR phone LIKE :phone",
chatwoot_id: { chatwoot_id: "#{chatwoot_contact['id']}" }.to_json,
email: "#{chatwoot_contact['email']}",
phone: "#{chatwoot_contact['phone_number']}"
).first
elsif chatwoot_contact['email'].present?
return current_user.account.contacts.where(
":chatwoot_id <@ additional_attributes OR email LIKE :email",
chatwoot_id: { chatwoot_id: "#{chatwoot_contact['id']}" }.to_json,
email: "#{chatwoot_contact['email']}"
).first
elsif chatwoot_contact['phone_number'].present?
return current_user.account.contacts.where(
":chatwoot_id <@ additional_attributes OR phone LIKE :phone",
chatwoot_id: { chatwoot_id: "#{chatwoot_contact['id']}" }.to_json,
phone: "#{chatwoot_contact['phone_number']}"
).first
else
return current_user.account.contacts.where(
":chatwoot_id <@ additional_attributes",
chatwoot_id: { chatwoot_id: "#{chatwoot_contact['id']}" }.to_json
).first
end
end
end
40 changes: 40 additions & 0 deletions app/controllers/apps/chatwoots_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Apps::ChatwootsController < ActionController::Base
before_action :load_chatwoot, execpt: :webhooks
before_action :authenticate_by_token, if: -> { current_user.blank? }
skip_before_action :verify_authenticity_token, execpt: :embedding
layout "embed"

def webhooks
render json: { ok: true }, status: 200
end

def embedding
end

def embedding_init_authenticate
@token = params['token']
end

def embedding_authenticate
event = JSON.parse(params['event'])
user_email = event['data']['currentAgent']['email']
user = User.find_by(email: user_email, account_id: @chatwoot.account_id)
return render plain: "User not found", status: 400 if user.blank?
sign_in(user)
redirect_to embedding_apps_chatwoots_path()
end

private

def authenticate_by_token
if @chatwoot.present? && action_name == 'embedding'
redirect_to embedding_init_authenticate_apps_chatwoots_path(token: params['token']) if action_name != 'embedding_authenticate'
else
render plain: "Unauthorized", status: 400 if @chatwoot.blank?
end
end

def load_chatwoot
@chatwoot = Apps::Chatwoot.find_by(embedding_token: params['token'])
end
end
2 changes: 2 additions & 0 deletions app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import "@hotwired/turbo-rails"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
import "controllers"
import lucide from "lucide/dist/umd/lucide"

Rails.start()
ActiveStorage.start()
Expand All @@ -19,6 +20,7 @@ require("@nathanvda/cocoon")
require("./stisla_scripts")

$(document).on("turbo:load", () => {
lucide.createIcons();
// Daterangepicker
if(jQuery().daterangepicker) {
if($(".datetimepicker").length) {
Expand Down
Loading