Class: Botiasloop::Chat

Inherits:
Object
  • Object
show all
Defined in:
lib/botiasloop/chat.rb

Overview

Chat model - represents a communication channel between user(s) and agent A chat belongs to a specific channel (telegram, cli) and external source (chat_id) Each chat tracks its current conversation (which can be any conversation in the system)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.find_or_create(channel, external_id, user_identifier: nil) ⇒ Chat

Class method to find or create a chat by channel and external_id

Parameters:

  • channel (String)

    Channel type (e.g., “telegram”, “cli”)

  • external_id (String)

    External identifier (e.g., chat_id, “cli”)

  • user_identifier (String, nil) (defaults to: nil)

    Optional user identifier (e.g., telegram username)

Returns:

  • (Chat)

    Found or created chat



28
29
30
31
32
33
34
35
36
37
# File 'lib/botiasloop/chat.rb', line 28

def self.find_or_create(channel, external_id, user_identifier: nil)
  chat = find(channel: channel, external_id: external_id)
  return chat if chat

  create(
    channel: channel,
    external_id: external_id,
    user_identifier: user_identifier
  )
end

Instance Method Details

#active_conversationsArray<Conversation>

List all non-archived conversations in the system Sorted by updated_at in descending order (most recently updated first)

Returns:



94
95
96
# File 'lib/botiasloop/chat.rb', line 94

def active_conversations
  Conversation.where(archived: false).order(Sequel.desc(:updated_at)).all
end

#archive_currentHash

Archive the current conversation and create a new one

Returns:

  • (Hash)

    Hash with :archived and :new_conversation keys

Raises:



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/botiasloop/chat.rb', line 108

def archive_current
  current = current_conversation if current_conversation_id

  raise Error, "No current conversation to archive" unless current

  current.update(archived: true)
  new_conversation = create_new_conversation

  {
    archived: current,
    new_conversation: new_conversation
  }
end

#archived_conversationsArray<Conversation>

List all archived conversations in the system

Returns:



101
102
103
# File 'lib/botiasloop/chat.rb', line 101

def archived_conversations
  Conversation.where(archived: true).order(Sequel.desc(:updated_at)).all
end

#create_new_conversationConversation

Create a new conversation and make it current for this chat

Returns:



84
85
86
87
88
# File 'lib/botiasloop/chat.rb', line 84

def create_new_conversation
  conversation = Conversation.create
  update(current_conversation_id: conversation.id)
  conversation
end

#current_conversationConversation

Get the current conversation for this chat Creates a new conversation if none exists or current is archived

Returns:



43
44
45
46
47
48
49
50
51
52
# File 'lib/botiasloop/chat.rb', line 43

def current_conversation
  conv = super

  if conv.nil? || conv.archived
    conv = create_new_conversation
    update(current_conversation_id: conv.id)
  end

  conv
end

#switch_conversation(identifier) ⇒ Conversation

Switch to a different conversation by label or conversation ID

Parameters:

  • identifier (String)

    Conversation label or human-readable ID

Returns:

Raises:

  • (Error)

    If conversation not found



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/botiasloop/chat.rb', line 59

def switch_conversation(identifier)
  identifier = identifier.to_s.strip
  raise Error, "Usage: /switch <label-or-id>" if identifier.empty?

  # First try to find by label
  conversation = Conversation.find(label: identifier)

  # If not found by label, treat as ID (case-insensitive)
  unless conversation
    normalized_id = HumanId.normalize(identifier)
    conversation = Conversation.all.find { |c| HumanId.normalize(c.id) == normalized_id }
  end

  raise Error, "Conversation '#{identifier}' not found" unless conversation

  # Auto-unarchive if switching to archived conversation
  conversation.update(archived: false) if conversation.archived

  update(current_conversation_id: conversation.id)
  conversation
end

#validateObject

Validations



16
17
18
19
20
# File 'lib/botiasloop/chat.rb', line 16

def validate
  super
  validates_presence i[channel external_id]
  validates_unique i[channel external_id]
end