Develop
This commit is contained in:
parent
7ca5f2d45a
commit
f901f203b0
302 changed files with 9897 additions and 10332 deletions
|
|
@ -9,12 +9,12 @@
|
|||
"lint": "eslint index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.22.5",
|
||||
"@babel/preset-env": "7.22.5",
|
||||
"@babel/core": "7.22.9",
|
||||
"@babel/preset-env": "7.22.9",
|
||||
"@babel/preset-typescript": "7.22.5"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.43.0"
|
||||
"eslint": "^8.45.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,26 +10,26 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@rushstack/eslint-patch": "^1.3.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
||||
"@typescript-eslint/parser": "^5.60.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.1.0",
|
||||
"@typescript-eslint/parser": "^6.1.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-xo-space": "^0.34.0",
|
||||
"eslint-plugin-cypress": "^2.13.3",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jest": "^27.2.2",
|
||||
"eslint-plugin-jest": "^27.2.3",
|
||||
"eslint-plugin-no-use-extend-native": "^0.5.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-unicorn": "47.0.0",
|
||||
"@babel/eslint-parser": "7.22.5"
|
||||
"eslint-plugin-unicorn": "48.0.0",
|
||||
"@babel/eslint-parser": "7.22.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.32.0",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.43.0",
|
||||
"jest": "^29.5.0",
|
||||
"typescript": "^5.1.3"
|
||||
"eslint": "^8.45.0",
|
||||
"jest": "^29.6.1",
|
||||
"typescript": "^5.1.6"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"private": false,
|
||||
"devDependencies": {
|
||||
"@hapi/basic": "^7.0.2",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/jest": "^29.5.3",
|
||||
"babel-preset-link": "*",
|
||||
"eslint-config-link": "*",
|
||||
"jest-config-link": "*",
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
"node": ">=14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/jest": "^29.5.2",
|
||||
"jest": "^29.5.0",
|
||||
"@types/jest": "^29.5.3",
|
||||
"jest": "^29.6.1",
|
||||
"jest-junit": "^16.0.0"
|
||||
},
|
||||
"peerDependencies": {}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
"pg-monitor": "^2.0.0",
|
||||
"tsc-watch": "^6.0.4",
|
||||
"typedoc": "^0.24.8",
|
||||
"typescript": "^5.1.3"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@digiresilience/hapi-nextauth": "*",
|
||||
|
|
@ -39,13 +39,13 @@
|
|||
"@promster/hapi": "^8.0.6",
|
||||
"@promster/server": "^7.0.8",
|
||||
"@promster/types": "^3.2.5",
|
||||
"@types/convict": "^6.1.2",
|
||||
"@types/convict": "^6.1.3",
|
||||
"@types/hapi__glue": "^6.1.6",
|
||||
"@types/hapi__hapi": "^20.0.13",
|
||||
"@types/hapi__inert": "^5.2.6",
|
||||
"@types/hapi__vision": "^5.5.4",
|
||||
"@types/hapipal__schmervice": "^2.0.3",
|
||||
"chalk": "^5.2.0",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^11.0.0",
|
||||
"convict": "^6.2.4",
|
||||
"decamelcase-keys": "^1.1.1",
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
"next-auth": "^4.22.1",
|
||||
"pg-promise": "^11.5.0",
|
||||
"pino": "^8.14.1",
|
||||
"pino-pretty": "^10.0.0",
|
||||
"pino-pretty": "^10.0.1",
|
||||
"prom-client": "^14.x.x",
|
||||
"uuid": "^9.0.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,16 +10,16 @@
|
|||
"@digiresilience/montar": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.22.5",
|
||||
"@babel/preset-env": "7.22.5",
|
||||
"@babel/core": "7.22.9",
|
||||
"@babel/preset-env": "7.22.9",
|
||||
"@babel/preset-typescript": "7.22.5",
|
||||
"eslint": "^8.43.0",
|
||||
"pino-pretty": "^10.0.0",
|
||||
"prettier": "^2.8.8",
|
||||
"eslint": "^8.45.0",
|
||||
"pino-pretty": "^10.0.1",
|
||||
"prettier": "^3.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsc-watch": "^6.0.4",
|
||||
"typedoc": "^0.24.8",
|
||||
"typescript": "^5.1.3"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"files": [
|
||||
"build",
|
||||
|
|
|
|||
|
|
@ -16,19 +16,19 @@
|
|||
"pg-promise": "^11.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.22.5",
|
||||
"@babel/preset-env": "7.22.5",
|
||||
"@babel/core": "7.22.9",
|
||||
"@babel/preset-env": "7.22.9",
|
||||
"@babel/preset-typescript": "7.22.5",
|
||||
"@types/jest": "^29.5.2",
|
||||
"eslint": "^8.43.0",
|
||||
"jest": "^29.5.0",
|
||||
"@types/jest": "^29.5.3",
|
||||
"eslint": "^8.45.0",
|
||||
"jest": "^29.6.1",
|
||||
"jest-junit": "^16.0.0",
|
||||
"pino-pretty": "^10.0.0",
|
||||
"prettier": "^2.8.8",
|
||||
"pino-pretty": "^10.0.1",
|
||||
"prettier": "^3.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsc-watch": "^6.0.4",
|
||||
"typedoc": "^0.24.8",
|
||||
"typescript": "^5.1.3"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
"node": ">=14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/jest": "^29.5.3",
|
||||
"babel-preset-link": "*",
|
||||
"eslint-config-link": "*",
|
||||
"jest-config-link": "*",
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
"backoff": "^2.5.0",
|
||||
"camelcase-keys": "^8.0.2",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"snakecase-keys": "^5.4.5",
|
||||
"snakecase-keys": "^5.4.6",
|
||||
"ts-custom-error": "^3.3.1",
|
||||
"uuid": "^9.0.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CommunicateCdrSignalJob < ApplicationJob
|
||||
retry_on StandardError, attempts: 4, wait: lambda { |executions|
|
||||
executions * 120.seconds
|
||||
}
|
||||
|
||||
def perform(article_id)
|
||||
article = Ticket::Article.find(article_id)
|
||||
|
||||
# set retry count
|
||||
article.preferences['delivery_retry'] ||= 0
|
||||
article.preferences['delivery_retry'] += 1
|
||||
|
||||
ticket = Ticket.lookup(id: article.ticket_id)
|
||||
unless ticket.preferences
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_signal']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_signal'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_signal']['bot_token']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_signal']['bot_token'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_signal']['chat_id']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_signal']['chat_id'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
channel = ::CdrSignal.bot_by_bot_token(ticket.preferences['cdr_signal']['bot_token'])
|
||||
channel ||= ::Channel.lookup(id: ticket.preferences['channel_id'])
|
||||
unless channel
|
||||
log_error(article,
|
||||
"No such channel for bot #{ticket.preferences['cdr_signal']['bot_token']} or channel id #{ticket.preferences['channel_id']}")
|
||||
end
|
||||
if channel.options[:bot_token].blank?
|
||||
log_error(article,
|
||||
"Channel.find(#{channel.id}) has no cdr signal api token!")
|
||||
end
|
||||
|
||||
has_error = false
|
||||
|
||||
begin
|
||||
result = channel.deliver(
|
||||
to: ticket.preferences[:cdr_signal][:chat_id],
|
||||
body: article.body
|
||||
)
|
||||
rescue StandardError => e
|
||||
log_error(article, e.message)
|
||||
has_error = true
|
||||
end
|
||||
|
||||
Rails.logger.debug { "send result: #{result}" }
|
||||
|
||||
if result.nil? || result[:error].present?
|
||||
log_error(article, 'Delivering signal message failed!')
|
||||
has_error = true
|
||||
end
|
||||
|
||||
return if has_error
|
||||
|
||||
article.to = result['result']['recipient']
|
||||
article.from = result['result']['source']
|
||||
|
||||
message_id = format('%<source>s@%<timestamp>s', source: result['result']['source'],
|
||||
timestamp: result['result']['timestamp'])
|
||||
article.preferences['cdr_signal'] = {
|
||||
timestamp: result['result']['timestamp'],
|
||||
message_id: message_id,
|
||||
from: result['result']['source'],
|
||||
to: result['result']['recipient']
|
||||
}
|
||||
|
||||
# set delivery status
|
||||
article.preferences['delivery_status_message'] = nil
|
||||
article.preferences['delivery_status'] = 'success'
|
||||
article.preferences['delivery_status_date'] = Time.zone.now
|
||||
|
||||
article.message_id = "cdr_signal.#{message_id}"
|
||||
|
||||
article.save!
|
||||
|
||||
Rails.logger.info "Sent signal message to: '#{article.to}' (from #{article.from})"
|
||||
|
||||
article
|
||||
end
|
||||
|
||||
def log_error(local_record, message)
|
||||
local_record.preferences['delivery_status'] = 'fail'
|
||||
local_record.preferences['delivery_status_message'] =
|
||||
message.encode!('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
|
||||
local_record.preferences['delivery_status_date'] = Time.zone.now
|
||||
local_record.save
|
||||
Rails.logger.error message
|
||||
|
||||
if local_record.preferences['delivery_retry'] > 3
|
||||
Ticket::Article.create(
|
||||
ticket_id: local_record.ticket_id,
|
||||
content_type: 'text/plain',
|
||||
body: "Unable to send cdr signal message: #{message}",
|
||||
internal: true,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: Ticket::Article::Type.find_by(name: 'note'),
|
||||
preferences: {
|
||||
delivery_article_id_related: local_record.id,
|
||||
delivery_message: true
|
||||
},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1
|
||||
)
|
||||
end
|
||||
|
||||
raise message
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CommunicateCdrWhatsappJob < ApplicationJob
|
||||
retry_on StandardError, attempts: 4, wait: lambda { |executions|
|
||||
executions * 120.seconds
|
||||
}
|
||||
|
||||
def perform(article_id)
|
||||
article = Ticket::Article.find(article_id)
|
||||
|
||||
# set retry count
|
||||
article.preferences['delivery_retry'] ||= 0
|
||||
article.preferences['delivery_retry'] += 1
|
||||
|
||||
ticket = Ticket.lookup(id: article.ticket_id)
|
||||
unless ticket.preferences
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_whatsapp']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_whatsapp'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_whatsapp']['bot_token']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_whatsapp']['bot_token'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_whatsapp']['chat_id']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_whatsapp']['chat_id'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
channel = ::CdrSignal.bot_by_bot_token(ticket.preferences['cdr_whatsapp']['bot_token'])
|
||||
channel ||= ::Channel.lookup(id: ticket.preferences['channel_id'])
|
||||
unless channel
|
||||
log_error(article,
|
||||
"No such channel for bot #{ticket.preferences['cdr_whatsapp']['bot_token']} or channel id #{ticket.preferences['channel_id']}")
|
||||
end
|
||||
if channel.options[:bot_token].blank?
|
||||
log_error(article,
|
||||
"Channel.find(#{channel.id}) has no cdr whatsapp api token!")
|
||||
end
|
||||
|
||||
has_error = false
|
||||
|
||||
begin
|
||||
result = channel.deliver(
|
||||
to: ticket.preferences[:cdr_whatsapp][:chat_id],
|
||||
body: article.body
|
||||
)
|
||||
rescue StandardError => e
|
||||
log_error(article, e.message)
|
||||
has_error = true
|
||||
end
|
||||
|
||||
Rails.logger.debug { "send result: #{result}" }
|
||||
|
||||
if result.nil? || result[:error].present?
|
||||
log_error(article, 'Delivering whatsapp message failed!')
|
||||
has_error = true
|
||||
end
|
||||
|
||||
return if has_error
|
||||
|
||||
article.to = result['result']['recipient']
|
||||
article.from = result['result']['source']
|
||||
|
||||
message_id = format('%<source>s@%<timestamp>s', source: result['result']['source'],
|
||||
timestamp: result['result']['timestamp'])
|
||||
article.preferences['cdr_whatsapp'] = {
|
||||
timestamp: result['result']['timestamp'],
|
||||
message_id: message_id,
|
||||
from: result['result']['source'],
|
||||
to: result['result']['recipient']
|
||||
}
|
||||
|
||||
# set delivery status
|
||||
article.preferences['delivery_status_message'] = nil
|
||||
article.preferences['delivery_status'] = 'success'
|
||||
article.preferences['delivery_status_date'] = Time.zone.now
|
||||
|
||||
article.message_id = "cdr_whatsapp.#{message_id}"
|
||||
|
||||
article.save!
|
||||
|
||||
Rails.logger.info "Sent whatsapp message to: '#{article.to}' (from #{article.from})"
|
||||
|
||||
article
|
||||
end
|
||||
|
||||
def log_error(local_record, message)
|
||||
local_record.preferences['delivery_status'] = 'fail'
|
||||
local_record.preferences['delivery_status_message'] =
|
||||
message.encode!('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
|
||||
local_record.preferences['delivery_status_date'] = Time.zone.now
|
||||
local_record.save
|
||||
Rails.logger.error message
|
||||
|
||||
if local_record.preferences['delivery_retry'] > 3
|
||||
Ticket::Article.create(
|
||||
ticket_id: local_record.ticket_id,
|
||||
content_type: 'text/plain',
|
||||
body: "Unable to send cdr whatsapp message: #{message}",
|
||||
internal: true,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: Ticket::Article::Type.find_by(name: 'note'),
|
||||
preferences: {
|
||||
delivery_article_id_related: local_record.id,
|
||||
delivery_message: true
|
||||
},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1
|
||||
)
|
||||
end
|
||||
|
||||
raise message
|
||||
end
|
||||
end
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Observer::Ticket::Article::CommunicateCdrSignal < ActiveRecord::Observer
|
||||
observe 'ticket::_article'
|
||||
|
||||
def after_create(record)
|
||||
# return if we run import mode
|
||||
return true if Setting.get('import_mode')
|
||||
|
||||
# if sender is customer, do not communicate
|
||||
return true unless record.sender_id
|
||||
|
||||
sender = Ticket::Article::Sender.lookup(id: record.sender_id)
|
||||
return true if sender.nil?
|
||||
return true if sender.name == 'Customer'
|
||||
|
||||
# only apply on signal messages
|
||||
return true unless record.type_id
|
||||
|
||||
type = Ticket::Article::Type.lookup(id: record.type_id)
|
||||
return true if type.name !~ /\Acdr_signal/i
|
||||
|
||||
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateCdrSignal::BackgroundJob.new(record.id))
|
||||
end
|
||||
end
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Observer
|
||||
module Ticket
|
||||
module Article
|
||||
class CommunicateCdrSignal
|
||||
class BackgroundJob
|
||||
def initialize(id)
|
||||
@article_id = id
|
||||
end
|
||||
|
||||
def perform
|
||||
article = ::Ticket::Article.find(@article_id)
|
||||
|
||||
# set retry count
|
||||
article.preferences['delivery_retry'] ||= 0
|
||||
article.preferences['delivery_retry'] += 1
|
||||
|
||||
ticket = ::Ticket.lookup(id: article.ticket_id)
|
||||
Rails.logger.debug { 'Signal background job' }
|
||||
Rails.logger.debug { ticket.inspect }
|
||||
Rails.logger.debug { article.inspect }
|
||||
unless ticket.preferences
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_signal']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_signal'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_signal']['chat_id']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_signal']['chat_id'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_signal']['bot_token']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_signal']['bot_token'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
|
||||
channel = ::CdrSignal.bot_by_bot_token(ticket.preferences['cdr_signal']['bot_token'])
|
||||
Rails.logger.debug { "signal got channel for #{channel.inspect}" }
|
||||
|
||||
channel ||= ::Channel.lookup(id: ticket.preferences['channel_id'])
|
||||
unless channel
|
||||
log_error(article,
|
||||
"No such channel for bot #{ticket.preferences['cdr_signal']['bot_token']} or channel id #{ticket.preferences['channel_id']}")
|
||||
end
|
||||
if channel.options[:bot_token].blank?
|
||||
log_error(article,
|
||||
"Channel.find(#{channel.id}) has no signal api token!")
|
||||
end
|
||||
|
||||
begin
|
||||
result = channel.deliver(
|
||||
to: ticket.preferences[:cdr_signal][:chat_id],
|
||||
body: article.body
|
||||
)
|
||||
rescue StandardError => e
|
||||
log_error(article, e.message)
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.debug { "send result: #{result}" }
|
||||
|
||||
if result.nil? || result[:error].present?
|
||||
log_error(article, 'Delivering signal message failed!')
|
||||
return
|
||||
end
|
||||
|
||||
article.to = result['result']['recipient']
|
||||
article.from = result['result']['source']
|
||||
|
||||
message_id = format('%<source>s@%<timestamp>s', source: result['result']['source'],
|
||||
timestamp: result['result']['timestamp'])
|
||||
article.preferences['cdr_signal'] = {
|
||||
timestamp: result['result']['timestamp'],
|
||||
message_id: message_id,
|
||||
from: result['result']['source'],
|
||||
to: result['result']['recipient']
|
||||
}
|
||||
|
||||
# set delivery status
|
||||
article.preferences['delivery_status_message'] = nil
|
||||
article.preferences['delivery_status'] = 'success'
|
||||
article.preferences['delivery_status_date'] = Time.zone.now
|
||||
|
||||
article.message_id = "cdr_signal.#{message_id}"
|
||||
|
||||
article.save!
|
||||
|
||||
Rails.logger.info "Sent signal message to: '#{article.to}' (from #{article.from})"
|
||||
|
||||
article
|
||||
end
|
||||
|
||||
def log_error(local_record, message)
|
||||
local_record.preferences['delivery_status'] = 'fail'
|
||||
local_record.preferences['delivery_status_message'] =
|
||||
message.encode('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
|
||||
local_record.preferences['delivery_status_date'] = Time.zone.now
|
||||
local_record.save
|
||||
Rails.logger.error message
|
||||
|
||||
if local_record.preferences['delivery_retry'] > 3
|
||||
::Ticket::Article.create(
|
||||
ticket_id: local_record.ticket_id,
|
||||
content_type: 'text/plain',
|
||||
body: "Unable to send signal message: #{message}",
|
||||
internal: true,
|
||||
sender: ::Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: ::Ticket::Article::Type.find_by(name: 'note'),
|
||||
preferences: {
|
||||
delivery_article_id_related: local_record.id,
|
||||
delivery_message: true
|
||||
},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1
|
||||
)
|
||||
end
|
||||
|
||||
raise message
|
||||
end
|
||||
|
||||
def max_attempts
|
||||
4
|
||||
end
|
||||
|
||||
def reschedule_at(current_time, attempts)
|
||||
return current_time + attempts * 120.seconds if Rails.env.production?
|
||||
|
||||
current_time + 5.seconds
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Observer::Ticket::Article::CommunicateCdrWhatsapp < ActiveRecord::Observer
|
||||
observe 'ticket::_article'
|
||||
|
||||
def after_create(record)
|
||||
# return if we run import mode
|
||||
return true if Setting.get('import_mode')
|
||||
|
||||
# if sender is customer, do not communicate
|
||||
return true unless record.sender_id
|
||||
|
||||
sender = Ticket::Article::Sender.lookup(id: record.sender_id)
|
||||
return true if sender.nil?
|
||||
return true if sender.name == 'Customer'
|
||||
|
||||
# only apply on whatsapp messages
|
||||
return true unless record.type_id
|
||||
|
||||
type = Ticket::Article::Type.lookup(id: record.type_id)
|
||||
return true if type.name !~ /\Acdr_whatsapp/i
|
||||
|
||||
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateCdrWhatsapp::BackgroundJob.new(record.id))
|
||||
end
|
||||
end
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Observer
|
||||
module Ticket
|
||||
module Article
|
||||
class CommunicateCdrWhatsapp
|
||||
class BackgroundJob
|
||||
def initialize(id)
|
||||
@article_id = id
|
||||
end
|
||||
|
||||
def perform
|
||||
article = ::Ticket::Article.find(@article_id)
|
||||
|
||||
# set retry count
|
||||
article.preferences['delivery_retry'] ||= 0
|
||||
article.preferences['delivery_retry'] += 1
|
||||
|
||||
ticket = ::Ticket.lookup(id: article.ticket_id)
|
||||
Rails.logger.debug { 'Whatsapp background job' }
|
||||
Rails.logger.debug { ticket.inspect }
|
||||
Rails.logger.debug { article.inspect }
|
||||
unless ticket.preferences
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_whatsapp']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_whatsapp'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_whatsapp']['chat_id']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_whatsapp']['chat_id'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
unless ticket.preferences['cdr_whatsapp']['bot_token']
|
||||
log_error(article,
|
||||
"Can't find ticket.preferences['cdr_whatsapp']['bot_token'] for Ticket.find(#{article.ticket_id})")
|
||||
end
|
||||
|
||||
channel = ::CdrWhatsapp.bot_by_bot_token(ticket.preferences['cdr_whatsapp']['bot_token'])
|
||||
Rails.logger.debug { "whatsapp got channel for #{channel.inspect}" }
|
||||
|
||||
channel ||= ::Channel.lookup(id: ticket.preferences['channel_id'])
|
||||
unless channel
|
||||
log_error(article,
|
||||
"No such channel for bot #{ticket.preferences['cdr_whatsapp']['bot_token']} or channel id #{ticket.preferences['channel_id']}")
|
||||
end
|
||||
if channel.options[:bot_token].blank?
|
||||
log_error(article,
|
||||
"Channel.find(#{channel.id}) has no whatsapp api token!")
|
||||
end
|
||||
|
||||
begin
|
||||
result = channel.deliver(
|
||||
to: ticket.preferences[:cdr_whatsapp][:chat_id],
|
||||
body: article.body
|
||||
)
|
||||
rescue StandardError => e
|
||||
log_error(article, e.message)
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.debug { "send result: #{result}" }
|
||||
|
||||
if result.nil? || result[:error].present?
|
||||
log_error(article, 'Delivering whatsapp message failed!')
|
||||
return
|
||||
end
|
||||
|
||||
article.to = result['result']['recipient']
|
||||
article.from = result['result']['source']
|
||||
|
||||
message_id = format('%<source>s@%<timestamp>s', source: result['result']['source'],
|
||||
timestamp: result['result']['timestamp'])
|
||||
article.preferences['cdr_whatsapp'] = {
|
||||
timestamp: result['result']['timestamp'],
|
||||
message_id: message_id,
|
||||
from: result['result']['source'],
|
||||
to: result['result']['recipient']
|
||||
}
|
||||
|
||||
# set delivery status
|
||||
article.preferences['delivery_status_message'] = nil
|
||||
article.preferences['delivery_status'] = 'success'
|
||||
article.preferences['delivery_status_date'] = Time.zone.now
|
||||
|
||||
article.message_id = "cdr_whatsapp.#{message_id}"
|
||||
|
||||
article.save!
|
||||
|
||||
Rails.logger.info "Sent whatsapp message to: '#{article.to}' (from #{article.from})"
|
||||
|
||||
article
|
||||
end
|
||||
|
||||
def log_error(local_record, message)
|
||||
local_record.preferences['delivery_status'] = 'fail'
|
||||
local_record.preferences['delivery_status_message'] =
|
||||
message.encode('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
|
||||
local_record.preferences['delivery_status_date'] = Time.zone.now
|
||||
local_record.save
|
||||
Rails.logger.error message
|
||||
|
||||
if local_record.preferences['delivery_retry'] > 3
|
||||
::Ticket::Article.create(
|
||||
ticket_id: local_record.ticket_id,
|
||||
content_type: 'text/plain',
|
||||
body: "Unable to send whatsapp message: #{message}",
|
||||
internal: true,
|
||||
sender: ::Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: ::Ticket::Article::Type.find_by(name: 'note'),
|
||||
preferences: {
|
||||
delivery_article_id_related: local_record.id,
|
||||
delivery_message: true
|
||||
},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1
|
||||
)
|
||||
end
|
||||
|
||||
raise message
|
||||
end
|
||||
|
||||
def max_attempts
|
||||
4
|
||||
end
|
||||
|
||||
def reschedule_at(current_time, attempts)
|
||||
return current_time + attempts * 120.seconds if Rails.env.production?
|
||||
|
||||
current_time + 5.seconds
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ticket::Article::EnqueueCommunicateCdrSignalJob
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
after_create :ticket_article_enqueue_communicate_cdr_signal_job
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ticket_article_enqueue_communicate_cdr_signal_job
|
||||
# return if we run import mode
|
||||
return true if Setting.get('import_mode')
|
||||
|
||||
# if sender is customer, do not communicate
|
||||
return true unless sender_id
|
||||
|
||||
sender = Ticket::Article::Sender.lookup(id: sender_id)
|
||||
return true if sender.nil?
|
||||
return true if sender.name == 'Customer'
|
||||
|
||||
# only apply on cdr signal messages
|
||||
return true unless type_id
|
||||
|
||||
type = Ticket::Article::Type.lookup(id: type_id)
|
||||
return true unless type.name.match?(/\Acdr_signal/i)
|
||||
|
||||
CommunicateCdrSignalJob.perform_later(id)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ticket::Article::EnqueueCommunicateCdrWhatsappJob
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
after_create :ticket_article_enqueue_communicate_cdr_whatsapp_job
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ticket_article_enqueue_communicate_cdr_whatsapp_job
|
||||
# return if we run import mode
|
||||
return true if Setting.get('import_mode')
|
||||
|
||||
# if sender is customer, do not communicate
|
||||
return true unless sender_id
|
||||
|
||||
sender = Ticket::Article::Sender.lookup(id: sender_id)
|
||||
return true if sender.nil?
|
||||
return true if sender.name == 'Customer'
|
||||
|
||||
# only apply on cdr whatsapp messages
|
||||
return true unless type_id
|
||||
|
||||
type = Ticket::Article::Type.lookup(id: type_id)
|
||||
return true unless type.name.match?(/\Acdr_whatspp/i)
|
||||
|
||||
CommunicateCdrWhatsappJob.perform_later(id)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.config.after_initialize do
|
||||
Ticket::Article.add_observer Observer::Ticket::Article::CommunicateCdrSignal.instance
|
||||
# Ticket::Article.add_observer Observer::Ticket::Article::CommunicateCdrSignal.instance
|
||||
|
||||
icon = File.read('public/assets/images/icons/cdr_signal.svg')
|
||||
doc = File.open('public/assets/images/icons.svg') { |f| Nokogiri::XML(f) }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.config.after_initialize do
|
||||
Ticket::Article.add_observer Observer::Ticket::Article::CommunicateCdrWhatsapp.instance
|
||||
# Ticket::Article.add_observer Observer::Ticket::Article::CommunicateCdrWhatsapp.instance
|
||||
|
||||
icon = File.read('public/assets/images/icons/cdr_whatsapp.svg')
|
||||
doc = File.open('public/assets/images/icons.svg') { |f| Nokogiri::XML(f) }
|
||||
|
|
|
|||
|
|
@ -44,13 +44,17 @@ class PGP < ActiveRecord::Migration[5.2]
|
|||
frontend: true
|
||||
)
|
||||
|
||||
create_table :pgp_keypairs do |t|
|
||||
t.string :fingerprint, limit: 250, null: false
|
||||
t.binary :public_key, limit: 10.megabytes, null: false
|
||||
t.binary :private_key, limit: 10.megabytes, null: true
|
||||
t.string :private_key_secret, limit: 500, null: true
|
||||
t.timestamps limit: 3, null: false
|
||||
begin
|
||||
create_table :pgp_keypairs do |t|
|
||||
t.string :fingerprint, limit: 250, null: false
|
||||
t.binary :public_key, limit: 10.megabytes, null: false
|
||||
t.binary :private_key, limit: 10.megabytes, null: true
|
||||
t.string :private_key_secret, limit: 500, null: true
|
||||
t.timestamps limit: 3, null: false
|
||||
end
|
||||
add_index :pgp_keypairs, [:fingerprint], unique: true
|
||||
rescue StandardError => e
|
||||
puts "NOTICE: #{e.message}"
|
||||
end
|
||||
add_index :pgp_keypairs, [:fingerprint], unique: true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue