func (users Users) String(userID int) string {
	result := fmt.Sprintf("%s %s", users.list[userID].FirstName, users.list[userID].LastName)
	if users.list[userID].UserName != "" {
		result += fmt.Sprintf(" (@%s)", users.list[userID].UserName)
	}
	return result
}
String - format user name
package main
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"strconv"
	"strings"
	"time"
	tgbotapi "gopkg.in/telegram-bot-api.v2"
)
type User struct {
	UserID         int       `json:"user_id"`           
	UserName       string    `json:"user_name"`         
	FirstName      string    `json:"first_name"`        
	LastName       string    `json:"last_name"`         
	AuthCode       string    `json:"auth_code"`         
	AuthCodeRoot   string    `json:"auth_code_root"`    
	IsAuthorized   bool      `json:"is_authorized"`     
	IsRoot         bool      `json:"is_root"`           
	PrivateChatID  int       `json:"private_chat_id"`   
	Counter        int       `json:"counter"`           
	LastAccessTime time.Time `json:"last_access_time"`  
}
type Users struct {
	list                   map[int]*User
	predefinedAllowedUsers map[string]bool
	predefinedRootUsers    map[string]bool
	needSaveDB             bool  
}
type UsersDB struct {
	Users    []User    `json:"users"`
	DateTime time.Time `json:"date_time"`
}
const SecondsForOldUsersBeforeVacuum = 1200
func NewUsers(appConfig Config) Users {
	users := Users{
		predefinedAllowedUsers: map[string]bool{},
		predefinedRootUsers:    map[string]bool{},
		list:                   map[int]*User{},
		needSaveDB:             true,
	}
	if appConfig.persistentUsers {
		users.LoadFromDB(appConfig.usersDB)
	}
	for _, name := range appConfig.predefinedAllowedUsers {
		users.predefinedAllowedUsers[name] = true
	}
	for _, name := range appConfig.predefinedRootUsers {
		users.predefinedAllowedUsers[name] = true
		users.predefinedRootUsers[name] = true
	}
	return users
}
func (users *Users) AddNew(tgbotMessage tgbotapi.Message) {
	privateChatID := 0
	if !tgbotMessage.Chat.IsGroup() {
		privateChatID = tgbotMessage.Chat.ID
	}
	UserID := tgbotMessage.From.ID
	if _, ok := users.list[UserID]; ok && privateChatID > 0 && privateChatID != users.list[UserID].PrivateChatID {
		users.list[UserID].PrivateChatID = privateChatID
		users.needSaveDB = true
	} else if !ok {
		users.list[UserID] = &User{
			UserID:        UserID,
			UserName:      tgbotMessage.From.UserName,
			FirstName:     tgbotMessage.From.FirstName,
			LastName:      tgbotMessage.From.LastName,
			IsAuthorized:  users.predefinedAllowedUsers[tgbotMessage.From.UserName],
			IsRoot:        users.predefinedRootUsers[tgbotMessage.From.UserName],
			PrivateChatID: privateChatID,
		}
		users.needSaveDB = true
	}
	users.list[UserID].LastAccessTime = time.Now()
	if users.list[UserID].IsAuthorized {
		users.list[UserID].Counter++
	}
}
func (users *Users) DoLogin(userID int, forRoot bool) string {
	code := getRandomCode()
	if forRoot {
		users.list[userID].IsRoot = false
		users.list[userID].AuthCodeRoot = code
	} else {
		users.list[userID].IsAuthorized = false
		users.list[userID].AuthCode = code
	}
	users.needSaveDB = true
	return code
}
func (users *Users) SetAuthorized(userID int, forRoot bool) {
	users.list[userID].IsAuthorized = true
	users.list[userID].AuthCode = ""
	if forRoot {
		users.list[userID].IsRoot = true
		users.list[userID].AuthCodeRoot = ""
	}
	users.needSaveDB = true
}
func (users Users) IsValidCode(userID int, code string, forRoot bool) bool {
	var result bool
	if forRoot {
		result = code != "" && code == users.list[userID].AuthCodeRoot
	} else {
		result = code != "" && code == users.list[userID].AuthCode
	}
	return result
}
func (users Users) IsAuthorized(userID int) bool {
	isAuthorized := false
	if _, ok := users.list[userID]; ok && users.list[userID].IsAuthorized {
		isAuthorized = true
	}
	return isAuthorized
}
func (users Users) IsRoot(userID int) bool {
	isRoot := false
	if _, ok := users.list[userID]; ok && users.list[userID].IsRoot {
		isRoot = true
	}
	return isRoot
}
func (users Users) BroadcastForRoots(messageSignal chan<- BotMessage, message string, excludeID int) {
	for userID, user := range users.list {
		if user.IsRoot && user.PrivateChatID > 0 && (excludeID == 0 || excludeID != userID) {
			sendMessage(messageSignal, user.PrivateChatID, []byte(message), false)
		}
	}
}