1#!/opt/local/bin/perl 2 3use warnings; 4use strict; 5 6use Net::Twitter; 7use DNSCheck; 8use SDBM_File; 9use Fcntl; 10 11my $dc = DNSCheck->new; 12my $conf = $dc->config->get("twitterbot"); 13my %db; 14 15tie %db, 'SDBM_File', $conf->{datafile}, O_RDWR | O_CREAT, 0666 16 or die "Failed to tie database: $!\n"; 17 18my $twitter = Net::Twitter->new( 19 username => $conf->{username}, 20 password => $conf->{password}, 21 clientname => 'DNSCheck TwitterBot', 22 clientver => '1.0', 23 clienturl => 'http://dnscheck.iis.se/', 24) or die; 25 26unless (defined($db{since_id})) { 27 $db{since_id} = 1; 28} 29 30sub update { 31 my ($name, $text) = @_; 32 33 my $tmp = substr('@' . $name . ' ' . $text, 0, 140); 34 $twitter->update($tmp); 35 36 # print "$tmp\n"; 37} 38 39sub process { 40 my ($name, $text) = @_; 41 42 my ($domain) = $text =~ m/ 43 ( 44 (?:\w+\.)+\w+ 45 ) 46 /x; 47 48 if (!defined($domain)) { 49 update($name, 50'Tweet me with a domain name, and I will reply with an assessment of its DNS correctness.' 51 ); 52 } elsif ($dc->dns->preflight_check($domain)) { 53 $dc->zone->test($domain); 54 my $l = $dc->logger; 55 my $msg; 56 if ($l->count_critical > 0) { 57 $msg = 58 $l->count_critical 59 . ' critical error' 60 . ($l->count_critical == 1 ? '' : 's'); 61 } elsif ($l->count_error > 0) { 62 $msg = 63 $l->count_error . ' error' . ($l->count_error == 1 ? '' : 's'); 64 } elsif ($l->count_warning > 0) { 65 $msg = 66 $l->count_warning 67 . ' warning' 68 . ($l->count_warning == 1 ? '' : 's'); 69 } else { 70 $msg = 'No problems'; 71 } 72 update($name, sprintf('%s for %s', $msg, $domain)); 73 } else { 74 update($name, sprintf('%s not found', $domain)); 75 } 76} 77 78my $mentions = $twitter->mentions( 79 { 80 since_id => $db{since_id}, 81 count => 200, 82 } 83); 84 85foreach my $t (@$mentions) { 86 process($t->{user}{screen_name}, $t->{text}); 87 $db{since_id} = $t->{id} if $t->{id} >= $db{since_id}; 88} 89 90untie(%db); 91 92=head1 NAME 93 94twitterbot 95 96=head1 SYNOPSIS 97 98Check Twitter for mentions of a given username, look for a domain name in the 99returned tweets, test those domains and post reply tweets with (very) 100abbreviated test results. 101 102=head1 DESCRIPTION 103 104This script gets all its configuration data via the DNSCheck configuration 105system. It will look for three keys under the 106top-level key C<twitterbot>: 107 108=over 109 110=item datafile 111 112Where to store persistent data. As of this writing this is only the ID number 113of the last tweet responded to, but this may change in the future. Will 114actually write two files: the given name with suffixes .dir and .pag. 115 116=item username 117 118The Twitter username to use. 119 120=item password 121 122The password to go with the given Twitter username. 123 124=back 125 126Given a correct setup of those keys, it should work fine running the script 127regularly from L<cron>. 128 129=cut 130