aboutsummaryrefslogtreecommitdiff
path: root/examples/08_search/src/main.rs
blob: 53d194f40435418688b739d6fb7551bc11b712ed (plain) (blame)
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
//! Requires the "cache", "methods", and "voice" features be enabled in your
//! Cargo.toml, like so:
//!
//! ```toml
//! [dependencies.serenity]
//! version = "*"
//! features = ["cache", "framework", "methods"]
//! ```
//!
//! Note that - due to bot users not being able to search - this example may
//! only be run under a user account.
//!
//! This particular example will automatically ensure that only the current user
//! may search; this acts as a "selfbot".

extern crate serenity;

use serenity::client::{CACHE, Client, Context};
use serenity::model::Message;
use serenity::utils::builder::{SortingMode, SortingOrder};
use std::env;

fn main() {
    let mut client = Client::login_user(&env::var("DISCORD_TOKEN").unwrap());

    client.with_framework(|f| f
        .configure(|c| c.prefix("~").on_mention(true))
        .on("search", search)
        .set_check("search", self_check));

    client.on_ready(|_context, ready| {
        println!("{} is connected!", ready.user.name);
    });

    if let Err(why) = client.start() {
        println!("Client error: {:?}", why);
    }
}

fn self_check(_context: &Context, message: &Message) -> bool {
    message.author.id == CACHE.read().unwrap().user.id
}

fn search(context: &Context, message: &Message, args: Vec<String>) {
    let query = args.join(" ");

    if query.is_empty() {
        let _ = context.say("You must provide a query");

        return;
    }

    let guild_id = match message.guild_id() {
        Some(guild_id) => guild_id,
        None => {
            let _ = context.say("Only supports guilds");

            return;
        },
    };

    let channel_ids = {
        let cache = CACHE.read().unwrap();

        let guild = match cache.get_guild(guild_id) {
            Some(guild) => guild,
            None => {
                let _ = context.say("Guild data not found");

                return;
            },
        };

        guild.channels
            .values()
            .filter(|c| c.name.starts_with("search-"))
            .map(|c| c.id)
            .collect()
    };

    let search = context.search_guild(guild_id, channel_ids, |s| s
        .content(&query)
        .context_size(0)
        .has_attachment(true)
        .has_embed(true)
        .max_id(message.id.0 - 1)
        .sort_by(SortingMode::Timestamp)
        .sort_order(SortingOrder::Descending));

    let messages = match search {
        Ok(messages) => messages,
        Err(why) => {
            println!("Error performing search '{}': {:?}", query, why);

            let _ = context.say("Error occurred while searching");

            return;
        },
    };

    let _ = context.send_message(message.channel_id, move |m| m
        .content(&format!("Found {} total results", messages.total))
        .embed(move |mut e| {
            for (i, mut messages) in messages.results.into_iter().enumerate() {
                let ref mut message = messages[0];
                message.content.truncate(1000);

                e = e.field(|f| f
                    .name(&format!("Result {}", i))
                    .value(&message.content));
            }

            e
        }));
}