# User model

In the conversation flow <mark style="color:blue;">`@user`</mark> can be called, which is an instance of this model for the user who is chatting.

## Location

{% code title="bot/models/user.rb" %}

```ruby
class User < ActiveRecord::Base

end
```

{% endcode %}

## `users` table schema

| `id`                     | Secuencial record ID.                                                                  |
| ------------------------ | -------------------------------------------------------------------------------------- |
| `psid`                   | The user identification on each platform.                                              |
| `platform`               | The platform through which the user is chatting.                                       |
| `psid_from_post_comment` | The user's ID who has commented on a post on the Fan Page associated with the project. |
| `page_id`                | Facebook Page's ID                                                                     |
| `name`                   | User's name.                                                                           |
| `first_name`             | User's first name.                                                                     |
| `last_name`              | User's last name.                                                                      |
| `timezone`               | User's timezone.                                                                       |
| `locale`                 | User's locale.                                                                         |
| `last_usage_at`          | Stores the last time when a message or event was received from the user.               |
| `context`                | The current context of the conversation with the user.                                 |
| `context_params`         | Stores the parameters from the current context of the conversation with the user.      |
| `session_vars`           | Stores the user's session vars.                                                        |
| `last_message_read`      | Boolean that indicates if the last message sent was read by the user.                  |
| `created_at`             | Date and time of record creation.                                                      |
| `updated_at`             | Date and time of the record's last update.                                             |

{% hint style="success" %}

### New User Creation

When an incoming message or event arrives, in the most of the cases it will be associated to a person(user).&#x20;

Through this model, Kogno will automatically create a record with the user's information in the table `users` in the database.&#x20;
{% endhint %}

## Common Methods and Attributes.

### <mark style="color:orange;">`first_time?()`</mark>

This method returns true if the user has been created current session.

#### Usage

```ruby
if @user.first_time?
    @reply.text t(:welcome)
else
    @reply.text t(:hello)
end
```

### <mark style="color:orange;">`platform`</mark>

This attribute returns the user's platform. For example: `"messenger"`, `"telegram"` or `"whatsapp"`.

#### Usage

```ruby
case @user.platform
  when "messenger"
    @reply.text "You're in Messenger"
  when "whatsapp"
    @reply.text "You're in WhatsApp"
  when "telegram"
    @reply.text "You're in Telegram"
end
```

### <mark style="color:orange;">`context`</mark>

Returns the current context of the conversation with the user.

#### Usage

```ruby
@user.context
```

### <mark style="color:orange;">`exit_context()`</mark>

Exit the user from the current context of the conversation.

#### Usage

```ruby
@user.exit_context
```

### <mark style="color:orange;">`reschedule_message(tag=Symbol, send_at=Time)`</mark>

Re-Schedule the messages associated with the provided tag.

#### Usage

```ruby
@user.reschedule_scheduled_message(:window_24h, Time.now + 23.hours + 55.minutes)
```

### <mark style="color:orange;">`scheduled_message?(tag=Symbol)`</mark>

Returns true if there is a scheduled message associated with the provided tag.

#### Usage

```ruby
@user.scheduled_message?(:window_24h)
```

### <mark style="color:orange;">`destroy_scheduled_messages(tag=Symbol)`</mark>

Deletes the scheduled message associated with the provided tag.

#### Usage

```ruby
@user.destroy_scheduled_messages(:window_24h)
```

### <mark style="color:orange;">`messenger_recurring_notification_data()`</mark>

Returns the user's subscription status for Messenger Recurring Notifications

#### Usage

```ruby
user = User.where(platform: :messenger).first
user.messenger_recurring_notification_data
=> {:token=>"XXXXXXX", :frecuency=>"daily", :expires_at=>2022-11-21 18:06:31 UTC, :token_status=>"NOT_REFRESHED", :timezone=>"UTC", :status=>:active} 
```

### <mark style="color:orange;">`messenger_recurring_notification?()`</mark>

Returns true if the subscription to Messenger Recurring Notifications is active.

#### Usage

```ruby
user = User.where(platform: :messenger).first
if user.subscribed_to_messenger_recurring_notification?
    puts "active"
else
    puts "unactive"
end
```

### <mark style="color:orange;">`vars`</mark>

This attribute allows saving and retrieving any data within the conversation flow.

#### Saving data

```ruby
@user.vars[:contact_information] = {
    email: "martin@kogno.io",
    phone: "‭+34 654 022 112‬"
}
```

#### Retrieving data

```ruby
if @user.vars[:contact_information].nil?
    @reply.text "Your email: #{@user.vars[:contact_information][:email]}"
end    
```

#### Deleting data

```ruby
@user.vars[:contact_information] = nil
```

{% hint style="info" %}
Para usar este attributo fuera del flujo de la conversación se necesita llamar a los metodos get\_session\_vars() y save\_session\_vars()

```ruby
user = User.first
user.get_session_vars()
user.vars[:contact_information] = {
    email: "martin@kogno.io",
    phone: "‭+34 654 022 112‬"
}
user.save_session_vars()
```

{% endhint %}

### <mark style="color:orange;">`set_locale(locale=Symbol)`</mark>

Set user locale

#### Usage

```ruby
@user.set_locale(:es)
```

## Customization Example

Suppose we need to ask the user to leave us their email and we would like to save that information.&#x20;

To do this we could do the following:

### Adding email field in users table.

```sql
alter table users add email varchar(60)
```

### Editing User model

In the User model we will create the methods that we consider necessary to carry out this operation: in this case we will create one to save the mail and another to verify that it exists.

```ruby
class User < ActiveRecord::Base

  def save_email(email)
    self.email = email
    self.save
  end

  def has_email?
    self.email.nil?
  end
  
end
```

### Testing

We can test this on the console by running `kogno c` in the terminal

```bash
2.6.3 :001 > user = User.first
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`psid` = '111112222333333' LIMIT 1
 => #<User id: 1, psid: "111112222333333", page_id: "1111111111111111".... 
 2.6.3 :002 > user.has_email?
 => false
 2.6.3 :003 > user.save_email("martin@kogno.io")
  (0.2ms)  BEGIN
  User Update (6.8ms)  UPDATE `users` SET `users`.`email` = 'martin@kogno.io"' WHERE `users`.`id` = 1
  (4.5ms)  COMMIT
 => true
 2.6.3 :004 > user.has_email?
 => true
   
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kogno.io/models/user-model.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
