···11+tiny program that listens on a port for *any* tcp connection (but assuming its http so curl / webhooks etc. work fine) and plays a click sound using [`quad-snd`](https://github.com/not-fl3/quad-snd).
22+33+the click sound is taken from https://github.com/enjarai/clickrtraining.
+24
UNLICENSE
···11+This is free and unencumbered software released into the public domain.
22+33+Anyone is free to copy, modify, publish, use, compile, sell, or
44+distribute this software, either in source code form or as a compiled
55+binary, for any purpose, commercial or non-commercial, and by any
66+means.
77+88+In jurisdictions that recognize copyright laws, the author or authors
99+of this software dedicate any and all copyright interest in the
1010+software to the public domain. We make this dedication for the benefit
1111+of the public at large and to the detriment of our heirs and
1212+successors. We intend this dedication to be an overt act of
1313+relinquishment in perpetuity of all present and future rights to this
1414+software under copyright law.
1515+1616+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1717+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1818+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1919+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2020+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2121+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2222+OTHER DEALINGS IN THE SOFTWARE.
2323+2424+For more information, please refer to <https://unlicense.org/>
+35
src/main.rs
···11+use std::{
22+ io::{BufRead, BufReader, Write},
33+ net::TcpListener,
44+};
55+66+use quad_snd::*;
77+88+const CLICK: &[u8] = include_bytes!("./sound.ogg");
99+1010+fn main() {
1111+ let ctx = AudioContext::new();
1212+ let click = Sound::load(&ctx, CLICK);
1313+1414+ let port = std::env::var("PORT")
1515+ .ok()
1616+ .and_then(|p| p.parse::<u16>().ok())
1717+ .unwrap_or(8668);
1818+ let listener = TcpListener::bind(("0.0.0.0", port)).expect("cant bind");
1919+2020+ for stream in listener.incoming() {
2121+ let Ok(mut stream) = stream else {
2222+ continue;
2323+ };
2424+ click.play(&ctx, PlaySoundParams::default());
2525+ // exhaust connection to not get "connection reset by peer"
2626+ BufReader::new(&stream)
2727+ .lines()
2828+ .flatten()
2929+ .take_while(|line| !line.is_empty())
3030+ .for_each(drop);
3131+ // this never "fails"
3232+ let response = "HTTP/1.1 200 OK\r\n\r\n";
3333+ let _ = stream.write_all(response.as_bytes());
3434+ }
3535+}