Skip to content

How to manage state and scenes#

Installation#

Before you begin, you need to install the library and initiate the bot; this process is described in detail here: How to import the library and initiate your bot.

How to manage user state#

By default, in this library the state is stored in a map of type map[string]interface{}{}. The key can be any string, any object can be the value. The state ID is the chat ID, meaning each chat will have a separate state. To manage the state, you need to use the methods of the Notification structure:

Method Descriptionm
ActivateNextScene() Activates the selected scene.
GetCurrentScene() Returns the current scene.
GetStateData() Returns the status data of the selected chat.
SetStateData() Replaces the state data of the selected chat.
UpdateStateData() Updates the status data of the selected chat.

Webhooks like incomingBlock, deviceInfo, stateInstanceChanged are not tied to the chat, so they do not have their own state.

If you want to interact with the states of other chats other than the chat of the webhook being processed, you can use the methods of the StateManager structure directly. The StateManager methods do the same as the Notification structure methods, but they expect an additional stateId parameter.

As an example, a simple bot was created to simulate user registration.

Link to example: state.go.

package state

import (
    "github.com/green-api/whatsapp_chatbot_golang"
)

type StartScene struct {
}

func (s StartScene) Start(bot *whatsapp_chatbot_golang.Bot) {
    bot.IncomingMessageHandler(func(notification *whatsapp_chatbot_golang.Notification) {
        if notification.Filter(map[string][]string{"text": {"/start"}}) {
            notification.AnswerWithText("Hi! This bot is an example of using state.\nPlease enter your login:")
            notification.ActivateNextScene(LoginScene{})
        } else {
            notification.AnswerWithText("Please enter the /start command.")
        }
    })
}

type LoginScene struct {
}

func (s LoginScene) Start(bot *whatsapp_chatbot_golang.Bot) {
    bot.IncomingMessageHandler(func(notification *whatsapp_chatbot_golang.Notification) {
        login, err := notification.Text()
        if err != nil || len(login) > 12 || len(login) < 6 {
            notification.AnswerWithText("Select a login from 6 to 12 characters!")
        } else {
            notification.UpdateStateData(map[string]interface{}{"login": login})
            notification.ActivateNextScene(PasswordScene{})
            notification.AnswerWithText("Your login " + notification.GetStateData()["login"].(string) + " - successfully saved.\nCreate a password:")
        }
    })
}

type PasswordScene struct {
}

func (s PasswordScene) Start(bot *whatsapp_chatbot_golang.Bot) {
    bot.IncomingMessageHandler(func(notification *whatsapp_chatbot_golang.Notification) {
        password, err := notification.Text()
        if err != nil || len(password) > 16 || len(password) < 8 {
            notification.AnswerWithText("Choose a password between 8 and 16 characters!")
        } else {
            notification.UpdateStateData(map[string]interface{}{"password": password})
            notification.ActivateNextScene(StartScene{})
            notification.AnswerWithText("Success! Your login: " + notification.GetStateData()["login"].(string) + "\nYour password: " + notification.GetStateData()["password"].(string))
        }
    })
}

If you need that when creating a new state, it already has some default values, you need to change the InitData field of the StateManager structure. In the standard implementation of MapStateManager this is done like this:

package main

import (
    "github.com/green-api/whatsapp_chatbot_golang"
    "github.com/green-api/whatsapp_chatbot_golang/examples/full"
)

func main() {
    bot := whatsapp_chatbot_golang.NewBot("INSTANCE_ID", "TOKEN")

    bot.StateManager = whatsapp_chatbot_golang.NewMapStateManager(
        map[string]interface{}{
            "defaultField1": "defaultValue1",
            "defaultField2": "defaultValue2",
            "defaultField3": "defaultValue3",
        })

    bot.SetStartScene(full.StartScene{})

    bot.StartReceivingNotifications()
}

List of examples#

Description Link to example
How to initialize a handler base.go
How to initialize a scene baseScene.go
Scene "Echo" echo.go
How to receive other types of notifications event.go
How to filter incoming messages filter.go
How to work with bot state state.go
Example of a ready-made chat bot full.go