7个版本

0.3.0 2023年3月17日
0.2.4 2023年2月12日
0.2.3 2022年8月18日
0.1.0 2022年8月12日

#1770 in 异步

Download history 9/week @ 2024-03-11 48/week @ 2024-04-01 2/week @ 2024-05-20

每月55次下载

MIT许可证

53KB
1K SLoC

Nostr机器人

workflow

你想运行自己的Nostr机器人?你来到正确的地方了。这个crate让你轻松实现自己的机器人,该机器人可以响应nostr事件,使用tokio

这个crate还比较年轻,仍在开发中,可能会有一些问题。如果你发现任何问题,请毫不犹豫地在GitHub上创建PR/issue。

完整文档请见此处

用法

此crate位于crates.io,您可以通过将nostr-bot添加到项目Cargo.toml中的依赖项来使用它。

[dependencies]
nostr-bot = "0.2"

您还可以使用GitHub 仓库

[dependencies]
nostr-bot = { git = "https://github.com/slaninas/nostr-bot", rev = "v0.2.3" }

或者您也可以克隆仓库并在本地使用

[dependency]
nostr-bot = { path = "your/path/to/nostr-bot" }

示例

// Bot that reacts to '!yes', '!no' and '!results' commands.
use nostr_bot::*;

// Your struct that will be passed to the commands responses
struct Votes {
    question: String,
    yes: u64,
    no: u64,
}

type State = nostr_bot::State<Votes>;

fn format_results(question: &str, votes: &Votes) -> String {
    format!(
        "{}\n------------------\nyes: {}\nno:  {}",
        question, votes.yes, votes.no
    )
}

// Following functions are command responses, you are getting nostr event
// and shared state as arguments and you are supposed to return non-signed
// event which is then signed using the bot's key and send to relays
async fn yes(event: Event, state: State) -> EventNonSigned {
    let mut votes = state.lock().await;
    votes.yes += 1;

    // Use formatted voting results to create new event
    // that is a reply to the incoming command
    get_reply(event, format_results(&votes.question, &votes))
}

async fn no(event: Event, state: State) -> EventNonSigned {
    let mut votes = state.lock().await;
    votes.no += 1;
    get_reply(event, format_results(&votes.question, &votes))
}

async fn results(event: Event, state: State) -> EventNonSigned {
    let votes = state.lock().await;
    get_reply(event, format_results(&votes.question, &votes))
}

#[tokio::main]
async fn main() {
    init_logger();

    let relays = vec![
        "wss://nostr-pub.wellorder.net",
        "wss://relay.damus.io",
        "wss://relay.nostr.info",
    ];

    let keypair = keypair_from_secret(
        // Your secret goes here, can be hex or bech32 (nsec1...)
        "0000000000000000000000000000000000000000000000000000000000000001",
    );

    let question = String::from("Do you think Pluto should be a planet?");

    // Wrap your object into Arc<Mutex> so it can be shared among command handlers
    let shared_state = wrap_state(Votes {
        question: question.clone(),
        yes: 0,
        no: 0,
    });

    // And now the Bot
    Bot::new(keypair, relays, shared_state)
        // You don't have to set these but then the bot will have incomplete profile info :(
        .name("poll_bot")
        .about("Just a bot.")
        .picture("https://i.imgur.com/ij4XprK.jpeg")
        .intro_message(&question)
        // You don't have to specify any command but then what will the bot do? Nothing.
        .command(Command::new("!yes", wrap!(yes)))
        .command(Command::new("!no", wrap!(no)))
        .command(Command::new("!results", wrap!(results)))
        // And finally run it
        .run()
        .await;
}

依赖项

~15–28MB
~405K SLoC