~raboof/chatbot-dialogue

ref: a55ab0fc2e7fa77162105852e2bfa5fcf7163483 chatbot-dialogue/src/main.rs -rw-r--r-- 3.7 KiB
a55ab0fc — Arnout Engelen Remember the 'previous' pandora response 1 year, 1 month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use dotenv;
use serde::Deserialize;
use std::env;
use regex::Regex;

type Result<T> = std::result::Result<T, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>;

#[derive(Deserialize)]
#[derive(Debug)]
struct PandoraResponse {
    responses: Vec<String>,
    sessionid: u32
}

struct Pandora {
    // Not changed after construction:
    name: String,
    referer: String,
    url: String,
    botkey: String,
    clientname: String,
    sessionid: u32,

    // Mutable:
    response: String
}
impl Pandora {
    async fn new(client: &reqwest::Client, message: &str) -> Result<Pandora> {
        let referer = env::var("referer").unwrap();
        let botkey = env::var("pandora_botkey").unwrap();
        let clientname = env::var("pandora_clientname").unwrap();
        let url = env::var("pandora_url").unwrap();
        let name = env::var("pandora_name").unwrap();
        let params: [(&str, &str); 4] = [
            ("input", "xintro"),
            ("botkey", &botkey),
            ("clientname", &clientname),
            ("sessionid", "null")
        ];
        let http_response = client.post(&url)
            .form(&params)
            .header("Referer", &referer)
            .send()
            .await?
            .json::<PandoraResponse>()
            .await?;
        Ok(Pandora {
            name: name,
            referer: referer.to_owned(),
            url: url,
            sessionid: http_response.sessionid,
            botkey: botkey,
            clientname: clientname,
            response: message.to_owned()
        })
    }

    // Say 'message' to pandora, expect a response
    async fn say(mut self, client: &reqwest::Client, message: &str) -> Result<Pandora> {
        let pandorasayparams = [
            ("input", message),
            ("botkey", &self.botkey),
            ("clientname", &self.clientname),
            ("sessionid", &self.sessionid.to_string())
        ];
        let re = Regex::new("<[^\\s]*").unwrap();
        let pandorares = client.post(&self.url)
            .form(&pandorasayparams)
            .header("Referer", &self.referer)
            .send()
            .await?
            .json::<PandoraResponse>()
            .await?;
        match pandorares.responses.get(0) {
            Some(response) => {
                let s = re.replace_all(response, "");
                self.response = s.into_owned();
                Ok(self)
            },
            None =>
                panic!("pandora response: {:?}", pandorares),
        }
    }
}

pub async fn chatscript_say(client: &reqwest::Client, url: &str, message: &str) -> Result<String> {
    let params = [("user", "peter"), ("send", ""), ("message", message)];
    let chatscript = client.post(url)
        .form(&params)
        .send()
        .await?
        .text()
        .await?;
    if chatscript.chars().next().unwrap() == '[' {
        Ok(chatscript.trim_start_matches(|c : char| c != ']').get(2..).unwrap().to_owned())
    } else {
        Ok(chatscript)
    }
}

#[tokio::main]
pub async fn main() -> Result<()> {
    dotenv::dotenv().ok();

    let client = reqwest::Client::new();

    let mut pandora: Pandora = Pandora::new(&client, "Hello, there!").await?;

    let chatscript_name = env::var("chatscript_name").unwrap();
    let chatscript_url = env::var("chatscript_url").unwrap();

    let mut cs_message: String;
    let mut count = 0;
    loop {
        count += 1;
        cs_message = chatscript_say(&client, &chatscript_url, &pandora.response).await?;
        println!("{}: {}", chatscript_name, cs_message);

        pandora = pandora.say(&client, &cs_message).await?;
        println!("{}: {}", pandora.name, pandora.response);

        if count == 5000 {
            break;
        }
    }
   
    Ok(())
}