Crate russenger

Crate russenger 

Source
Expand description

§Russenger Library

The Russenger library provides a set of modules and macros to help you build bots using the Russenger bot framework.

§Modules

  • cli: This module provides command-line interface utilities.
  • core: This module contains the core functionalities of the Russenger bot framework.
  • prelude: This module re-exports important traits and structs for convenience.
  • query: This module provides utilities for handling queries.
  • response_models: This module contains models for different types of responses.

§Macros

  • action: This proc macro is used to define an action.
  • russenger::actions!: This macro is used to register the actions for the main application.

§New Features

  • Custom Models: Developers can now use their own models with the Russenger library. This is made possible by the integration with rusql_alchemy, an ORM for sqlx. This means that models are defined in Rust code, eliminating the need to write SQL queries.

§Examples

Creating a new action that sends a greeting message when the user input is “Hello”:

use russenger::prelude::*;

#[derive(FromRow, Clone, Model)]
pub struct Register {
    #[field(primary_key = true, auto_increment = true)]
    pub id: Integer,
    #[field(foreign_key = "RussengerUser.facebook_user_id", unique = true)]
    pub user_id: String,
    #[field(size = 30, unique = true)]
    pub username: String,
}

async fn index(res: Res, req: Req) -> Result<()> {
    // Send a greeting message to the user
    res.send(TextModel::new(&req.user, "Hello!")).await?;

    // Check if the user is registered
    if let Some(user_register) = Register::get(kwargs!(user_id = req.user), &req.query.conn).await {
        // If the user is registered, send a personalized greeting message
        res.send(TextModel::new(&req.user, &format!("Hello {}", user_register.username)))
            .await?;
    } else {
        // If the user is not registered, ask for their name
        res.send(TextModel::new(&req.user, "What is your name: "))
            .await?;
        // Set the next action to SignUp
        res.redirect("/signup").await?;
        return Ok(());
    }

    // If the user is registered, set the next action to GetUserInput
    res.redirect("/get_user_input").await?;

    Ok(())
}

async fn signup(res: Res, req: Req) -> Result<()> {
    // Get the username from the user input
    let username: String = req.data.get_value()?;

    // Try to create a new Register record for the user
    let message = if Register::create(kwargs!(user_id = req.user, username = username), &req.query.conn).await {
        "Register success"
    } else {
        "Register failed"
    };

    // Send a message to the user indicating whether the registration was successful
    res.send(TextModel::new(&req.user, message)).await?;

    // Go back to the index action
    index(res, req).await?;

    Ok(())
}

async fn get_user_input(res: Res, req: Req) -> Result<()> {
    // Define a closure that creates a new Payload for a given value
    let payload = |value: &str| Payload::new("/next_action", Some(Data::new(value)));

    // Create a QuickReplyModel with two options: "blue" and "red"
    let quick_replies: Vec<QuickReply> = vec![
        QuickReply::new("blue", None, payload("blue")),
        QuickReply::new("red", None, payload("red")),
    ];
    let quick_reply_model = QuickReplyModel::new(&req.user, "choose one color", quick_replies);

    // Send the QuickReplyModel to the user
    res.send(quick_reply_model).await?;

    Ok(())
}

async fn next_action(res: Res, req: Req) -> Result<()> {
    // Get the color chosen by the user
    let color: String = req.data.get_value()?;

    // Send a message to the user confirming their choice
    res.send(TextModel::new(&req.user, &color)).await?;

    // Go back to the index action
    index(res, req).await?;

    Ok(())
}

#[tokio::main]
async fn main() -> Result<()> {
    App::init().await?
       .attach(
            Router::new()
                .add("/", index)
                .add("/signup", signup)
                .add("/get_user_input", get_user_input)
                .add("/next_action", next_action)
        )
        .launch()
        .await?;
    Ok(())
}

These examples demonstrate how to define an action, use custom models, and register actions for the main application.

Re-exports§

pub use core::router::Router;
pub use core::services::webhook_core;
pub use core::services::webhook_verify;
pub use anyhow;
pub use rusql_alchemy;

Modules§

core
The core module contains the core functionality of the application.
error
models
The models module contains the data models used by the Russenger library.
prelude
This allows users to include everything they need with a single use statement.
query
The query module provides utilities for handling queries. The Query struct represents a database query. It includes a DB enum that represents the database connection.
response_models
The response_models module contains various response models that can be sent to a user.

Macros§

router

Structs§

App
App State