]> git.sesse.net Git - skvidarsync/blob - www/event.pl
cf7a21283949c74872d0341ef8f6514f6a950221
[skvidarsync] / www / event.pl
1 #! /usr/bin/perl
2 use strict;
3 use warnings;
4 no warnings qw(once);
5 use CGI;
6 use JSON::XS;
7 use Digest::SHA qw(hmac_sha256_hex);
8 use LWP::UserAgent;
9 use DBI;
10
11 require '../include/config.pm';
12
13 sub mark {
14         print STDERR "Marking that a sync is needed.\n";
15         open my $fh, ">", "/srv/skvidar-slack.sesse.net/marker";
16         close $fh;
17 }
18
19 my $dbh = DBI->connect("dbi:Pg:dbname=$config::dbname;host=127.0.0.1", $config::dbuser, $config::dbpass, {RaiseError => 1})
20         or die "Could not connect to Postgres: " . DBI->errstr;
21
22 my $cgi = CGI->new;
23 my $post = $cgi->param('POSTDATA');
24 my $ts = $cgi->http('X-Slack-Request-Timestamp');
25 my $sig = $cgi->http('X-Slack-Signature');
26
27 my $digest = Digest::SHA::hmac_sha256_hex("v0:$ts:$post", $config::signing_secret);
28 die "Failed signature" unless ($sig eq "v0=$digest");
29
30 print STDERR "JSON: $post\n";
31
32 my $json = JSON::XS::decode_json($post);
33 if (exists($json->{'challenge'})) {
34         print CGI->header(-type=>'text/plain');
35         print $json->{'challenge'}, "\n";
36         exit;
37 }
38
39 if (exists($json->{'event'}) && exists($json->{'event'}{'type'})) {
40         my $type = $json->{'event'}{'type'};
41         my $reaction = $json->{'event'}{'reaction'};
42         my $channel = $json->{'event'}{'item'}{'channel'};
43         my $ts = $json->{'event'}{'item'}{'ts'};
44         my $event_ts = $json->{'event'}{'event_ts'};
45         my $user = $json->{'event'}{'user'};
46
47         if (!defined($channel) || !defined($ts)) {
48                 print STDERR "Not reacting to a message; ignoring.\n";
49                 print CGI->header(-type=>'text/plain');
50                 print "OK\n";
51                 exit;
52         }
53
54         if ($type eq 'reaction_added') {
55                 $dbh->do('INSERT INTO reactions (userid, channel, ts, reaction) VALUES (?,?,?,?)', undef,
56                         $user, $channel, $ts, $reaction);
57                 $dbh->do('INSERT INTO reaction_log (userid, channel, ts, reaction, event_type, event_ts) VALUES (?,?,?,?,?,?)', undef,
58                         $user, $channel, $ts, $reaction, $type, $event_ts);
59                 mark();
60         } elsif ($type eq 'reaction_removed') {
61                 $dbh->do('DELETE FROM reactions WHERE userid=? AND channel=? AND ts=? AND reaction=?', undef,
62                         $user, $channel, $ts, $reaction);
63                 $dbh->do('INSERT INTO reaction_log (userid, channel, ts, reaction, event_type, event_ts) VALUES (?,?,?,?,?,?)', undef,
64                         $user, $channel, $ts, $reaction, $type, $event_ts);
65                 mark();
66         } else {
67                 print STDERR "Type is $type (not a reaction added or removed); ignoring.\n";
68         }
69
70         # Fall through.
71 } else {
72         print STDERR "Has no type; igoring.\n";
73 }
74
75 print CGI->header(-type=>'text/plain');
76 print "OK\n";