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
fn main() {
use std::net::TcpStream;
use twitchchat::commands::PrivMsg;
use twitchchat::{Client, UserConfig, Writer};
// create a userconfig
let userconfig = UserConfig::builder()
.nick(std::env::var("MY_TWITCH_NAME").unwrap())
.token(std::env::var("MY_TWITCH_PASS").unwrap())
// enable these capbilities
.tags()
.membership()
.commands()
// build the config
.build() // enable these tags
.expect("semi-valid config");
// connect to twitch
let read = TcpStream::connect(twitchchat::TWITCH_IRC_ADDRESS).expect("connect");
// clone the tcpstream
let write = read.try_clone().expect("must be able to clone");
// create the read adapter from the TcpStream
let read = twitchchat::SyncReadAdapter::new(read);
// create a new client from the read, write pairs
let mut client = Client::new(read, write);
// when we receive a PrivMsg run this function
// tok allows us to remove this later, if we want
let _tok = client.on(move |msg: PrivMsg, w: Writer<_>| {
const KAPPA: usize = 25;
// print out `user: message`
println!("{}: {}", msg.display_name().unwrap(), msg.message());
let kappas = msg
.emotes()
.iter()
// filter Kappas
.filter(|e| e.id == KAPPA)
// count how many times it appears
.map(|d| d.ranges.len())
.sum::<usize>();
// if someone sent more than 3 Kappas, send a Kappa back
if kappas >= 3 {
// using the provided Writer
w.send(msg.channel, "Kappa").unwrap();
}
});
// log if the broadcaster, a sub or a mod talks
client.on(move |msg: PrivMsg, _: Writer<_>| {
use twitchchat::BadgeKind::{Broadcaster, Subscriber};
let name = msg.display_name().unwrap_or_else(|| msg.user());
let badges = msg
.badges()
.iter()
// filter to just the "BadgeKind"
.map(|badge| badge.kind.clone())
.collect::<Vec<_>>();
match (
badges.contains(&Broadcaster),
badges.contains(&Subscriber),
msg.moderator(), // or badges.contains(&Moderator)
) {
(true, _, _) => println!("{} is the broadcaster", name),
(_, true, _) => println!("{} is a subscriber", name),
(_, _, true) => println!("{} is a mod", name),
(_, _, _) => {
// just a normal viewer
}
};
});
// 'register' (sends out creds.) with the server
client.register(userconfig).expect("register with twitch");
// blocks the thread until the server tells us who we were
match client.wait_for_ready() {
// and print it out
Ok(user) => {
// id: 23196011, name: Some("museun"), color: Some(OrangeRed)
println!(
"id: {}, name: {:?}, color: {:?}",
user.user_id, user.display_name, user.color
)
}
Err(twitchchat::ReadError::Inner(twitchchat::Error::InvalidRegistration)) => {
eprintln!("invalid nick/pass");
std::process::exit(1);
}
Err(err) => panic!(err),
};
// get a clone of the writer, this allows you to write to the connection
let w = client.writer();
// join a channel
w.join("museun").unwrap();
{
// not needed here, but the writer is clonable
// you can also get another one from the `client`
let w = w.clone();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(3));
w.send("museun", "VoHiYo").unwrap();
});
}
// block this thread until the connection ends
// this will call the filters when it receives the appropirate message
if let Err(err) = client.run() {
eprintln!("error while running: {}", err);
std::process::exit(1);
}
}