main.rs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #![feature(proc_macro_hygiene, decl_macro)]
  2. #[macro_use]
  3. extern crate rocket;
  4. use reqwest::Client;
  5. use rocket::request;
  6. use rocket::State;
  7. use rocket::{http::Status, Outcome, Request};
  8. use std::env;
  9. mod handlers;
  10. mod registry;
  11. mod github;
  12. mod payload;
  13. mod team;
  14. static BOT_USER_NAME: &str = "rust-highfive";
  15. use github::{Comment, GithubClient, Issue};
  16. use payload::SignedPayload;
  17. use registry::HandleRegistry;
  18. #[derive(PartialEq, Eq, Debug, serde::Deserialize)]
  19. #[serde(rename_all = "lowercase")]
  20. pub enum IssueCommentAction {
  21. Created,
  22. Edited,
  23. Deleted,
  24. }
  25. #[derive(Debug, serde::Deserialize)]
  26. pub struct IssueCommentEvent {
  27. action: IssueCommentAction,
  28. issue: Issue,
  29. comment: Comment,
  30. }
  31. enum Event {
  32. IssueComment,
  33. Other,
  34. }
  35. impl<'a, 'r> request::FromRequest<'a, 'r> for Event {
  36. type Error = String;
  37. fn from_request(req: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
  38. let ev = if let Some(ev) = req.headers().get_one("X-GitHub-Event") {
  39. ev
  40. } else {
  41. return Outcome::Failure((Status::BadRequest, format!("Needs a X-GitHub-Event")));
  42. };
  43. let ev = match ev {
  44. "issue_comment" => Event::IssueComment,
  45. _ => Event::Other,
  46. };
  47. Outcome::Success(ev)
  48. }
  49. }
  50. #[post("/github-hook", data = "<payload>")]
  51. fn webhook(event: Event, payload: SignedPayload, reg: State<HandleRegistry>) -> Result<(), String> {
  52. match event {
  53. Event::IssueComment => {
  54. let payload = payload
  55. .deserialize::<IssueCommentEvent>()
  56. .map_err(|e| format!("IssueCommentEvent failed to deserialize: {:?}", e))?;
  57. let event = registry::Event::IssueComment(payload);
  58. reg.handle(&event).map_err(|e| format!("{:?}", e))?;
  59. }
  60. // Other events need not be handled
  61. Event::Other => {}
  62. }
  63. Ok(())
  64. }
  65. #[catch(404)]
  66. fn not_found(_: &Request) -> &'static str {
  67. "Not Found"
  68. }
  69. fn main() {
  70. env_logger::init();
  71. dotenv::dotenv().ok();
  72. let client = Client::new();
  73. let gh = GithubClient::new(client.clone(), env::var("GITHUB_API_TOKEN").unwrap());
  74. let mut registry = HandleRegistry::new();
  75. handlers::register_all(&mut registry, gh.clone());
  76. rocket::ignite()
  77. .manage(gh)
  78. .manage(registry)
  79. .mount("/", routes![webhook])
  80. .register(catchers![not_found])
  81. .launch();
  82. }