# frozen_string_literal: true require 'cdr_signal_api' class CdrSignal attr_accessor :client # # check token and return bot attributes of token # # bot = CdrSignal.check_token('token') # def self.check_token(api_url, token) api = CdrSignalApi.new(api_url, token) begin bot = api.fetch_self rescue StandardError => e raise "invalid api token: #{e.message}" end bot end # # create or update channel, store bot attributes and verify token # # channel = CdrSignal.create_or_update_channel('token', params) # # returns # # channel # instance of Channel # def self.create_or_update_channel(api_url, token, params, channel = nil) # verify token bot = CdrSignal.check_token(api_url, token) raise 'Bot already exists!' unless channel && CdrSignal.bot_duplicate?(bot['id']) raise 'Group needed!' if params[:group_id].blank? group = Group.find_by(id: params[:group_id]) raise 'Group invalid!' unless group unless channel channel = CdrSignal.bot_by_bot_id(bot['id']) channel ||= Channel.new end channel.area = 'Signal::Account' channel.options = { adapter: 'cdr_signal', bot: { id: bot['id'], number: bot['number'] }, api_token: token, api_url: api_url, welcome: params[:welcome] } channel.group_id = group.id channel.active = true channel.save! channel end # # check if bot already exists as channel # # success = CdrSignal.bot_duplicate?(bot_id) # # returns # # channel # instance of Channel # def self.bot_duplicate?(bot_id, channel_id = nil) Channel.where(area: 'Signal::Account').each do |channel| next unless channel.options next unless channel.options[:bot] next unless channel.options[:bot][:id] next if channel.options[:bot][:id] != bot_id next if channel.id.to_s == channel_id.to_s return true end false end # # get channel by bot_id # # channel = CdrSignal.bot_by_bot_id(bot_id) # # returns # # true|false # def self.bot_by_bot_token(bot_token) Channel.where(area: 'Signal::Account').each do |channel| next unless channel.options next unless channel.options[:bot_token] return channel if channel.options[:bot_token].to_s == bot_token.to_s end nil end # # date = CdrSignal.timestamp_to_date('1543414973285') # # returns # # 2018-11-28T14:22:53.285Z # def self.timestamp_to_date(timestamp_str) Time.at(timestamp_str.to_i).utc.to_datetime end def self.message_id(message_raw) format('%s@%s', source: message_raw['source'], timestamp: message_raw['timestamp']) end # # client = CdrSignal.new('token') # def initialize(api_url, token) @token = token @api_url = api_url @api = CdrSignalApi.new(api_url, token) end # # client.send_message(chat_id, 'some message') # def send_message(recipient, message) return if Rails.env.test? @api.send_message(recipient, message) end def user(number) { # id: params[:message][:from][:id], id: number, username: number # first_name: params[:message][:from][:first_name], # last_name: params[:message][:from][:last_name] } end def to_user(message) Rails.logger.debug { 'Create user from message...' } Rails.logger.debug { message.inspect } # do message_user lookup message_user = user(message[:source]) # create or update user login = message_user[:username] || message_user[:id] auth = Authorization.find_by(uid: message[:source], provider: 'cdr_signal') user_data = { login: login, mobile: message[:source] } user = if auth User.find(auth.user_id) else User.where(mobile: message[:source]).order(:updated_at).first end if user user.update!(user_data) else user = User.create!( firstname: message[:source], mobile: message[:source], note: "Signal #{message_user[:username]}", active: true, role_ids: Role.signup_role_ids ) end # create or update authorization auth_data = { uid: message_user[:id], username: login, user_id: user.id, provider: 'cdr_signal' } if auth auth.update!(auth_data) else Authorization.create(auth_data) end user end def to_ticket(message, user, group_id, channel) UserInfo.current_user_id = user.id Rails.logger.debug { 'Create ticket from message...' } Rails.logger.debug { message.inspect } Rails.logger.debug { user.inspect } Rails.logger.debug { group_id.inspect } # prepare title title = '-' title = message[:message][:body] unless message[:message][:body].nil? title = "#{title[0, 60]}..." if title.length > 60 # find ticket or create one state_ids = Ticket::State.where(name: %w[closed merged removed]).pluck(:id) ticket = Ticket.where(customer_id: user.id).where.not(state_id: state_ids).order(:updated_at).first if ticket # check if title need to be updated ticket.title = title if ticket.title == '-' new_state = Ticket::State.find_by(default_create: true) ticket.state = Ticket::State.find_by(default_follow_up: true) if ticket.state_id != new_state.id ticket.save! return ticket end ticket = Ticket.new( group_id: group_id, title: title, state_id: Ticket::State.find_by(default_create: true).id, priority_id: Ticket::Priority.find_by(default_create: true).id, customer_id: user.id, preferences: { channel_id: channel.id, cdr_signal: { bot_token: channel.options[:bot_token], chat_id: message[:source] } } ) ticket.save! ticket end def to_article(message, user, ticket, channel) Rails.logger.debug { 'Create article from message...' } Rails.logger.debug { message.inspect } Rails.logger.debug { user.inspect } Rails.logger.debug { ticket.inspect } UserInfo.current_user_id = user.id article = Ticket::Article.new( from: message[:source], to: channel[:options][:bot][:number], body: message[:message][:body], content_type: 'text/plain', message_id: "cdr_signal.#{message[:id]}", ticket_id: ticket.id, type_id: Ticket::Article::Type.find_by(name: 'cdr_signal').id, sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id, internal: false, preferences: { cdr_signal: { timestamp: message[:timestamp], message_id: message[:id], from: message[:source] } } ) # TODO: attachments # TODO voice # TODO emojis # if message[:message][:body] Rails.logger.debug { article.inspect } article.save! Store.remove( object: 'Ticket::Article', o_id: article.id ) return article end raise 'invalid action' end def to_group(message, group_id, channel) # begin import Rails.logger.debug { 'signal import message' } # TODO: handle messages in group chats return if Ticket::Article.find_by(message_id: message[:id]) ticket = nil # use transaction Transaction.execute(reset_user_id: true) do user = to_user(message) ticket = to_ticket(message, user, group_id, channel) to_article(message, user, ticket, channel) end ticket end def from_article(article) # sends a message from a zammad article Rails.logger.debug { "Create signal message from article to '#{article[:to]}'..." } @api.send_message(article[:to], article[:body]) end end