Showing 2 changed files with 189 additions and 388 deletions
+175 -345
sms/bot
... ...
@@ -3,21 +3,23 @@
3 3
 use strict;
4 4
 use warnings;
5 5
 
6
-use Net::XMPP;
7 6
 use DBI;
8 7
 use POSIX qw/ceil strftime/;
8
+use HiPi::Huawei::E3531;
9
+use HiPi::Huawei::Errors;
9 10
 
10 11
 use open ':utf8';
11 12
 use open ':std';
12 13
 use utf8;
13
-#use Data::Dumper;
14
+
15
+use Data::Dumper;
14 16
 
15 17
 use threads;
16 18
 use threads::shared;
17 19
 use Thread::Queue;
20
+use Thread::Semaphore;
18 21
 
19
-$ENV{PWD} = "" if not defined $ENV{PWD};
20
-my $scriptconf = $ENV{PWD} . "/$0";
22
+my $scriptconf = $0;
21 23
 $scriptconf =~ s/\.pl$//;
22 24
 $scriptconf =~ s/$/.conf/;
23 25
 if (-r $scriptconf) {
... ...
@@ -34,146 +36,46 @@ else {
34 36
 }
35 37
 
36 38
 $SIG{INT}=\&terminate;
37
-#my $next_sms :shared; # utilisé pour le top du procahin envoi
38
-my $debugLevel = 0;
39
-
40
-my $phone_status : shared = "";
41 39
 
42
-my $from_gtalksms_queue = Thread::Queue->new;
43
-my $to_gtalksms_queue = Thread::Queue->new;
40
+my $inbox_sms_queue = Thread::Queue->new;
41
+my $outbox_sms_queue = Thread::Queue->new;
44 42
 my $mail_queue = Thread::Queue->new;
45 43
 
46
-my $bot = &xmpp_login($cfg::config{xmpp}->{hostName}, 
47
-                      $cfg::config{xmpp}->{portNumber}, 
48
-                      $cfg::config{xmpp}->{userName}, 
49
-                      $cfg::config{xmpp}->{passWord}, 
50
-                      $cfg::config{xmpp}->{componentName}, 
51
-                      $cfg::config{xmpp}->{resource}, 
52
-                      $cfg::config{xmpp}->{tls}, 
53
-                      1, "", 0, 
54
-                      $cfg::config{DEBUG});
44
+my $mutex = Thread::Semaphore->new();
45
+STDERR->autoflush();
55 46
 
56
-$SIG{INT} = sub { $bot->Disconnect; };
47
+my $mail = threads->new(\&send_mail);
57 48
 
58
-my $mail = threads->new(\&ssmtp_send_mail);
49
+my $inbox_sms = threads->new(\&inbox_sms_parse);
59 50
 
60
-my $from_gtalksms = threads->new(\&from_gtalksms_parse);
51
+my $outbox_sms = threads->new(\&hilink_send_sms);
61 52
 
62
-my $to_gtalksms = threads->new(\&xmpp_send_sms);
63
-
64
-sub debug_print {
65
-    print STDERR "sendxmpp: " . (join ' ', @_) . "\n"
66
-	if (@_ && ($cfg::config{DEBUG} ||$cfg::config{VERBOSE}));
67
-}
53
+my $hlink = HiPi::Huawei::E3531->new();
68 54
 
69 55
 sub log_bot {
70
-#    open(LOGFILE,'>>', 'bot.log');
71
-#    print LOGFILE sprintf("[%s] %s\n",strftime("%Y-%m-%d %H:%M:%S", localtime), shift);
72
-    print  sprintf("[%s] %s\n",strftime("%Y-%m-%d %H:%M:%S", localtime), shift);
73
-#    close LOGFILE;
74
-}
75
-
76
-sub xmpp_logout($) {
77
-    # HACK
78
-    # messages may not be received if we log out too quickly...
79
-    sleep 1;
80
-
81
-    my $cnx = shift;
82
-    $cnx->Disconnect();
83
-    xmpp_check_result ('Disconnect',0); # well, nothing to check, really
56
+    $mutex->down();
57
+    print STDERR sprintf("%s\n", shift);
58
+    $mutex->up();
84 59
 }
85 60
 
86 61
 sub terminate () {
87
-    my $cnx = shift;
88
-    debug_print "caught TERM";
89
-    xmpp_logout($cnx);
62
+    log_bot($mail_queue->pending() . " mails en attente d'envoi !") if ($mail_queue->pending() > 0);
63
+    $mail->exit();
64
+    log_bot($inbox_sms_queue->pending() . " SMS en attente de traitement !") if ($inbox_sms_queue->pending() > 0);
65
+    $inbox_sms->exit();
66
+    log_bot($outbox_sms_queue->pending() . " SMS en attente d'envoi !") if ($outbox_sms_queue->pending() > 0);
67
+    $outbox_sms->exit();
68
+    log_bot("arrêt");
90 69
     exit 0;
91 70
 }
92 71
 
93
-sub error_exit {
94
-    my ($err,$cnx) = @_;
95
-    print STDERR "$err\n";
96
-    xmpp_logout ($cnx)
97
-	if ($cnx);
98
-    exit 1;
99
-}
100
-
101
-sub xmpp_check_result {
102
-    my ($txt, $res, $cnx)=@_;
103
-
104
-    error_exit ("Error '$txt': result undefined")
105
-	unless (defined $res);
106
-
107
-    # res may be 0
108
-	if ($res == 0) {
109
-		debug_print "$txt";
110
-		# result can be true or 'ok'
111
-	}
112
-	elsif ((@$res == 1 && $$res[0]) || $$res[0] eq 'ok') {
113
-		debug_print "$txt: " .  $$res[0];
114
-		# otherwise, there is some error
115
-	}
116
-	else {
117
-		my $errmsg = $cnx->GetErrorCode() || '?';
118
-		error_exit ("Error '$txt': " . join (': ',@$res) . "[$errmsg]", $cnx);
119
-	}
120
-}
121
-
122
-sub xmpp_login ($$$$$$$$$$$) {
123
-    my ($host, $port, $user, $pw, $comp, $res, $tls, $no_tls_verify, $tls_ca_path, $ssl, $debug) = @_;
124
-    my $cnx = new Net::XMPP::Client(debuglevel=>0);
125
-    error_exit "could not create XMPP client object: $!" unless ($cnx);
126
-
127
-	my $ssl_verify = 0x01;
128
-	if ($no_tls_verify) { $ssl_verify = 0x00; }
129
-	debug_print "ssl_verify: $ssl_verify";
130
-
131
-	debug_print "tls_ca_path: $tls_ca_path";
132
-
133
-    my @res;
134
-	my $arghash = {
135
-		hostname		=> $host,
136
-		port            => $port,
137
-		tls				=> $tls,
138
-		ssl_verify		=> $ssl_verify,
139
-		ssl_ca_path		=> $tls_ca_path,
140
-		ssl             => $ssl,
141
-		connectiontype	=> 'tcpip',
142
-		componentname	=> $comp
143
-	};
144
-
145
-	delete $arghash->{port} unless $port; 
146
-	if ($arghash->{port}) {
147
-		@res = $cnx->Connect(%$arghash);
148
-		error_exit ("Could not connect to '$host' on port $port: $@") unless @res;
149
-	} else {
150
-		@res = $cnx->Connect(%$arghash);
151
-		error_exit ("Could not connect to server '$host': $@") unless @res;
152
-	}
153
-
154
-    xmpp_check_result("Connect",\@res,$cnx);
155
-
156
-	if ($comp) {
157
-		my $sid = $cnx->{SESSION}->{id};
158
-		$cnx->{STREAM}->{SIDS}->{$sid}->{hostname} = $comp
159
-	}
160
-
161
-    @res = $cnx->AuthSend(#'hostname' => $host,
162
-			  'username' => $user,
163
-			  'password' => $pw,
164
-			  'resource' => $res);
165
-    xmpp_check_result('AuthSend',\@res,$cnx);
166
-
167
-    return $cnx;
168
-}
169
-
170 72
 sub sql_request ($) {
171
-    my $request = shift;
73
+    my $msg = shift;
172 74
     my @result;
173 75
     my $dbh = DBI->connect($cfg::config{db}->{driver}, $cfg::config{db}->{user}, $cfg::config{db}->{password}, {'RaiseError' => 1});
174 76
     $dbh->{'mysql_enable_utf8'} = 1;
175 77
     $dbh->do(qq{SET NAMES "utf8"});
176
-    my $sth = $dbh->prepare($request);
78
+    my $sth = $dbh->prepare($msg);
177 79
     $sth->execute();
178 80
     if (defined($sth->{NUM_OF_FIELDS})) {
179 81
         while (my $ref = $sth->fetchrow_hashref()) {
... ...
@@ -186,19 +88,19 @@ sub sql_request ($) {
186 88
 }
187 89
 
188 90
 sub massive_send_sms {
189
-    my $request = shift;
190
-    if ($to_gtalksms_queue->pending() > 0) {
191
-        $to_gtalksms_queue->insert(0, [$request->{phone}, "un envoi massif est déjà en cours, lancé par " . $cfg::config{last_sender} . ", reste " . $to_gtalksms_queue->pending() . ", annulation"]);
91
+    my $msg = shift;
92
+    if ($outbox_sms_queue->pending() > 0) {
93
+        $outbox_sms_queue->insert(0, [$msg->{Phone}, "un envoi massif est déjà en cours, lancé par " . $cfg::config{last_sender} . ", reste " . $outbox_sms_queue->pending() . ", annulation"]);
192 94
         return;
193 95
     }
194
-    $cfg::config{last_sender} = $request->{phone_owner};
195
-    my @results = sql_request("SELECT phone, firstname, gender FROM " . $cfg::config{table} . " WHERE " . $cfg::config{group_prefix} . $request->{table} . " > '0'");
96
+    $cfg::config{last_sender} = $msg->{PhoneOwner};
97
+    my @results = sql_request("SELECT phone, firstname, gender FROM " . $cfg::config{table} . " WHERE " . $cfg::config{group_prefix} . $msg->{groupe} . " > '0'");
196 98
     my $qty = scalar(@results);
197 99
     my $start_msg = "envoi de " . $qty . " SMS (fin prévue entre ". strftime("%H:%M", localtime(time() + $qty * 60)) . " et " . strftime("%H:%M", localtime(time() + $qty * 90)) . ")";
198
-    $to_gtalksms_queue->enqueue([$request->{phone}, $start_msg]);
100
+    $outbox_sms_queue->enqueue([$msg->{Phone}, $start_msg]);
199 101
     foreach my $contact (@results) {
200 102
         $contact->{phone} =~ s/[\s\.]//g;
201
-        $_ = $request->{body};
103
+        $_ = $msg->{Content};
202 104
         s/\@prénom/$contact->{firstname}/g;
203 105
         if ($contact->{gender} eq 'F') {
204 106
             s/\@\(\s*(\w+)\s*,\s*\w+\s*\)/$1/g;
... ...
@@ -206,64 +108,21 @@ sub massive_send_sms {
206 108
         else {
207 109
             s/\@\(\s*\w+\s*,\s*(\w+)\s*\)/$1/g;
208 110
         }
209
-        $to_gtalksms_queue->enqueue([$contact->{phone}, $_])
111
+        $outbox_sms_queue->enqueue([$contact->{phone}, $_])
210 112
     }
211
-    $to_gtalksms_queue->enqueue([$request->{phone}, "envoi des SMS terminé !"]);
113
+    $outbox_sms_queue->enqueue([$msg->{Phone}, "envoi des SMS terminé !"]);
212 114
 }
213 115
 
214
-sub control_sms_flow {
215
-    my ($body, $max, $interval) = @_;
216
-    my $flow_control="/home/sms/flow.control";
217
-#    use bytes; # les caractères UTF-8 peuvent être codés sur plus d'un octet
218
-#    my $nbr = ceil(length($$body)/140); # taille d'un SMS 140 octets
219
-     my $nbr = 1;
220
-#    no bytes;
221
-    while (1) {
222
-        my $left = $max;
223
-        my $t = time;
224
-        open (FILE, "<", $flow_control);
225
-        my @lines = <FILE>;
226
-        close FILE;
227
-        open(FILE, ">", $flow_control);
228
-        foreach my $line (@lines) {
229
-            $line =~ /(\d+)/;
230
-            my $ts = $1;
231
-            if ($ts + $interval > $t) {
232
-                $left--;
233
-                print FILE $line;
234
-            }
235
-        }
236
-        close FILE;
237
-        log_bot("  ---> to send: $nbr; left: $left");
238
-        last if $nbr < $left;
239
-        sleep 60;
240
-    }
241
-    open (FILE,">>", $flow_control);
242
-    for (my $i = 0; $i < $nbr; $i++) { print FILE time, "\n"; }
243
-    close FILE;
244
-}
116
+sub send_mail {
117
+    while (my $msg = $mail_queue->dequeue) {
118
+        defined($msg->{to}) or $msg->{to} = $cfg::config{mail};
119
+        open(MAIL, "|msmtp $msg->{to}");
120
+        print MAIL "Subject: $msg->{Subject}\n";
121
+        print MAIL "Reply-To: $msg->{Email}\n" if ($msg->{Email} ne '');
245 122
 
246
-sub xmpp_send {
247
-    my $msg = shift;
248
-    $bot->MessageSend(
249
-            to => $cfg::config{xmpp}->{phoneBuddy}, 
250
-            from => $cfg::config{xmpp}->{userName} . "@" . $cfg::config{xmpp}->{hostName}, 
251
-            resource => $cfg::config{xmpp}->{resource}, 
252
-            type => 'chat', 
253
-            body => $$msg
254
-    );
255
-}
256
-
257
-sub ssmtp_send_mail {
258
-    while (my $request = $mail_queue->dequeue) {
259
-        defined($request->{to}) or $request->{to} = $cfg::config{mail};
260
-        open(MAIL, "|/usr/lib/sendmail -t");
261
-        print MAIL "Subject: $request->{subject}\n"; 
262
-        print MAIL "To: $request->{to}\n";
263
-        print MAIL "Reply-To: $request->{email}\n" if ($request->{email} ne '');
264
-        print MAIL "$request->{body}\n";
123
+        print MAIL "$msg->{Content}\n";
265 124
         close(MAIL);
266
-        log_bot("mail envoyé à $request->{to}");
125
+        log_bot("mail envoyé à $msg->{to}");
267 126
     }
268 127
 }
269 128
 
... ...
@@ -275,27 +134,38 @@ sub wait_open_time ($$) {
275 134
     }
276 135
 }
277 136
 
278
-sub xmpp_send_sms {
279
-    while (my $ref = $to_gtalksms_queue->dequeue) {
137
+sub hilink_send_sms {
138
+    my $sendbox = HiPi::Huawei::E3531->new();
139
+    while (1) {
140
+        my $sms = $outbox_sms_queue->dequeue_timed(10, 1);
141
+        next if ! defined $sms;
280 142
         wait_open_time($cfg::config{close_hour}, $cfg::config{begin_hour}); # pas d'envoi entre 21h et 8h
281
-#        TODO lock($next_sms);
282
-#        TODO $next_sms = $$ref[0];
283
-        xmpp_send(\"sms:$$ref[0]:$$ref[1]");
284
-        log_bot("envoi à $$ref[0] : $$ref[1]");
285
-        sleep 60 + int(rand(30)); # en attendant la maîtrise de cond_wait et cond_signal: cond_signal() called on unlocked variable at ./bot line 348
286
-#        TODO cond_wait($next_sms); # attend le top 
143
+
144
+        if ($sendbox->{code}) {
145
+            log_bot('sendbox new: ' . HiPi::Huawei::Errors->get_error_message($sendbox->{code}));
146
+        }
147
+        else {
148
+            my $reponse = $sendbox->send_sms($$sms[0], , $$sms[1]);
149
+            if ($reponse->{code}) {
150
+                log_bot('send_sms: ' . HiPi::Huawei::Errors->get_error_message($reponse->{code}));
151
+            }
152
+
153
+            log_bot("envoi à $$sms[0] : $$sms[1]");
154
+        }
155
+        sleep 60 + int(rand(30));
287 156
     }
157
+    log_bot('fin du thread outbox_sms');
288 158
 }
289 159
 
290 160
 sub is_authorized {
291
-    my ($request) = @_;
292
-    my @results = sql_request("SELECT * FROM $cfg::config{table} WHERE phone = '$request->{phone}'");
161
+    my ($msg) = @_;
162
+    my @results = sql_request("SELECT * FROM $cfg::config{table} WHERE phone = '$msg->{Phone}'");
293 163
     if (scalar(@results) == 1) {
294 164
         my $_results = $results[0];
295 165
         foreach my $column (keys(%$_results)) {
296 166
             if ($column =~ /^$cfg::config{group_prefix}/) {
297 167
                 if ($results[0]->{$column} == 2) {
298
-                    $request->{address} = $results[0]->{address};
168
+                    $msg->{address} = $results[0]->{address};
299 169
                     return 1; # true
300 170
                 }
301 171
             }
... ...
@@ -308,21 +178,21 @@ sub is_authorized {
308 178
 }
309 179
 
310 180
 sub authorized_on_table {
311
-    my %request = @_;
312
-    my $table_name = $cfg::config{group_prefix} . $request{groupe};
313
-    my @results = sql_request("SELECT * FROM $cfg::config{table} WHERE phone = '$request{id}'");
181
+    my %msg = @_;
182
+    my $table_name = $cfg::config{group_prefix} . $msg{groupe};
183
+    my @results = sql_request("SELECT * FROM $cfg::config{table} WHERE phone = '$msg{id}'");
314 184
     if (scalar(@results) == 1) {
315 185
         if (! defined($results[0]->{$table_name})) {
316
-            $request{error} = "le groupe $request{groupe} n'existe pas";
317
-            $to_gtalksms_queue->insert(0, [$request{id}, $request{error}]);
186
+            $msg{error} = "le groupe $msg{groupe} n'existe pas";
187
+            $outbox_sms_queue->insert(0, [$msg{id}, $msg{error}]);
318 188
             return 0; # false
319 189
         }
320 190
     }
321
-    @results = sql_request("SELECT $table_name FROM $cfg::config{table} WHERE phone = '$request{id}'");
191
+    @results = sql_request("SELECT $table_name FROM $cfg::config{table} WHERE phone = '$msg{id}'");
322 192
     if (scalar(@results) == 1) {
323 193
         if ($results[0]->{$table_name} != 2) {
324
-            $request{error} = "désolé, écrire au groupe $request{groupe} n'est pas autorisé pour toi";
325
-            $to_gtalksms_queue->insert(0, [$request{id}, $request{error}]);
194
+            $msg{error} = "désolé, écrire au groupe $msg{groupe} n'est pas autorisé pour toi";
195
+            $outbox_sms_queue->insert(0, [$msg{id}, $msg{error}]);
326 196
             return 0; # false
327 197
         }
328 198
         else {
... ...
@@ -332,10 +202,10 @@ sub authorized_on_table {
332 202
 }
333 203
 
334 204
 sub react_on_message {
335
-    my ($hashref , $request) = @_;
205
+    my ($hashref , $msg) = @_;
336 206
     for my $regex (keys(%$hashref)) {
337
-        if ($request->{body} =~ m/$regex/i) {
338
-            $request->{body} =~ s/$regex//i;
207
+        if ($msg->{Content} =~ m/$regex/i) {
208
+            $msg->{Content} =~ s/$regex//i;
339 209
             $hashref->{$regex}();
340 210
             return 1; # true
341 211
         }
... ...
@@ -343,166 +213,126 @@ sub react_on_message {
343 213
     return 0; # false
344 214
 }
345 215
 
346
-sub messageCB {
347
-    my ($sid, $msg) = @_;
348
-    $from_gtalksms_queue->enqueue($msg) if $msg->DefinedBody();
349
-}
350
-
351
-sub from_gtalksms_parse {
352
-    while (my $msg = $from_gtalksms_queue->dequeue) {
353
-        my %request = (body => $msg->GetBody);
354
-        my %part_from_gtalksms = (
355
-            $cfg::gtalksms{from} => sub { # Message de +33612345678 :
356
-                $request{phone} = "0" . $1;
357
-                $request{phone_owner} = '';
358
-                $request{email} = '';
359
-                my @results = sql_request("SELECT * FROM " . $cfg::config{table} . " WHERE phone = '$request{phone}'");
360
-                my $number_of_candidates = @results;
361
-                $number_of_candidates == 0 and return;
362
-                $request{phone_owner} .= '(';
363
-                foreach (@results) {
364
-                    $request{phone_owner} .= "$_->{firstname} $_->{lastname}";
365
-                    --$number_of_candidates > 0 and $request{phone_owner} .= ' ou ';
366
-                    $request{email} = $_->{email};
367
-                } 
368
-                $request{phone_owner} .= ')';
369
-                log_bot("message de $request{phone} $request{phone_owner}");
370
-            },
371
-            $cfg::gtalksms{"delivered"} => sub { # SMS "un contenu de SMS" pour 0612345678 délivré.
372
-                log_bot("message $1 délivré pour $2");
373
-# TODO cond_signal($next_sms);
374
-            },
375
-            $cfg::gtalksms{forget} => sub { # Le destinataire par défaut est 0612345678: inutile
376
-                return;
377
-            },
378
-        );
379
-
380
-        my %sms_action = (
381
-            "create flag" => sub {
382
-                my ($flag) = @_;
383
-                my $gid = getgrnam("sms-action");
384
-                mkdir $cfg::sms_action{flagdir};
385
-                chmod 0770, $cfg::sms_action{flagdir};
386
-                chown $>, $gid, $cfg::sms_action{flagdir};
387
-
388
-                open(FLAG, ">" . $cfg::sms_action{flagdir} . "/" . $cfg::sms_action{flag});
389
-                chmod 0660, $cfg::sms_action{flagdir} . "/" . $cfg::sms_action{flag};
390
-                chown $>, $gid, $cfg::sms_action{flagdir} . "/" . $cfg::sms_action{flag};
391
-
392
-                print FLAG $$flag if defined $flag;
393
-                close FLAG;
394
-            },
395
-            "start action" => sub {
396
-                # 0 = false
397
-                return ! system("sudo /bin/systemctl start action.service");
398
-            },
399
-            "get locker" => sub {
400
-                open FLAG, $cfg::sms_action{flagdir} . "/" . $cfg::sms_action{flag};
401
-                my $locker = '';
402
-                my $intro_ = '';
403
-                while (<FLAG>) {
404
-                    if (/^firstname:(.+)$/) {
405
-                        $locker = " par " . $1;
406
-                    }
407
-                    if (/^intro:(.+)$/) {
408
-                        $intro_ = " de test ($1)";
409
-                    }
410
-                }
411
-                close FLAG;
412
-                return "l'envoi " . $intro_ . " est déjà prévu" . $locker . ", abandon";
413
-            },
414
-        );
216
+sub inbox_sms_parse {
217
+    while (my $msg = $inbox_sms_queue->dequeue) {
415 218
 
416 219
         my %part_from_user = (
417
-            $cfg::user{"stop"} => sub {
418
-                log_bot("arrêt demandé par $request{phone} $request{phone_owner}");
419
-                $bot->Disconnect();
420
-            },
421 220
             $cfg::user{"message de groupe"} => sub {
422
-                $request{table} = lc $1;
423
-                if (authorized_on_table(groupe => $request{table}, id => $request{phone})) {
424
-                    &massive_send_sms(\%request);
221
+                $msg->{groupe} = lc $1;
222
+                if (authorized_on_table(groupe => $msg->{groupe}, id => $msg->{Phone})) {
223
+                    &massive_send_sms(\%$msg);
425 224
                 }
426 225
             },
427 226
             $cfg::user{"message pour un destinataire"} => sub {
428
-                $to_gtalksms_queue->enqueue([$1, $2]);
227
+                $outbox_sms_queue->enqueue([$1, $msg->{Content}]);
429 228
             },
430 229
             $cfg::user{"ping"} => sub {
431
-                my $envoi_en_cours = "";
432
-                if ($to_gtalksms_queue->pending() > 0) {
433
-                    $envoi_en_cours = "\nenvoi en cours de traitement " . $cfg::config{last_sender};
434
-                }
435
-                log_bot("envoi d'un pong à $request{phone} $request{phone_owner}");
436
-                $to_gtalksms_queue->insert(0, [$request{phone}, "pong ($phone_status)" . $envoi_en_cours]);
437
-            },
438
-            $cfg::user{"test intro pour action"} => sub {
439
-                my $intro = $1;
440
-                if (! -r $cfg::sms_action{flag_prefix} . $intro . $cfg::sms_action{flag_suffix}) {
441
-                    $to_gtalksms_queue->enqueue([$request{phone}, "l'intro $intro n'existe pas, abandon"]);
442
-                    return;
443
-                }
444
-                if (-r $cfg::sms_action{flagdir} . "/" . $cfg::sms_action{flag}) {
445
-                    $to_gtalksms_queue->enqueue([$request{phone}, $sms_action{"get locker"}()]);
446
-                }
447
-                else {
448
-                    log_bot("demande envoi du mail des actions avec intro $intro depuis $request{phone} $request{phone_owner} à $request{address}");
449
-                    my $flag_content = "to:" . $request{address} . "\nintro:" . $intro . "\nfirstname:" . $request{phone} . " " . $request{phone_owner};
450
-                    $sms_action{"create flag"}(\$flag_content);
451
-                    if ($sms_action{"start action"}()) {
452
-                        $to_gtalksms_queue->enqueue([$request{phone}, "le mail de test des actions avec intro $intro envoyé à $request{address}"]);
453
-                    }
454
-                    else {
455
-                        $to_gtalksms_queue->enqueue([$request{phone}, "problème: le mail de test des actions avec intro $intro pour $request{address}, n'est probablement pas parti"]);
456
-                    }
457
-                }
458
-            },
459
-            $cfg::user{"envoi normal pour action"} => sub {
460
-                if (-r $cfg::sms_action{flagdir} . "/" . $cfg::sms_action{flag}) {
461
-                    $to_gtalksms_queue->enqueue([$request{phone}, $sms_action{"get locker"}()]);
462
-                }
463
-                else {
464
-                    log_bot("demande envoi du mail des actions depuis $request{phone} $request{phone_owner}");
465
-                    $sms_action{"create flag"}();
466
-                    if ($sms_action{"start action"}()) {
467
-                        $to_gtalksms_queue->enqueue([$request{phone}, "le mail des actions est parti"]);
468
-                    }
469
-                    else {
470
-                        $to_gtalksms_queue->enqueue([$request{phone}, "problème: le mail des actions n'est probablement pas parti"]);
230
+                my $envoi_en_cours = '';
231
+                if ($outbox_sms_queue->pending() > 0) {
232
+                    for (my $queue_id = $outbox_sms_queue->pending(); $queue_id >= 0; $queue_id--) {
233
+                        log_bot(Dumper($outbox_sms_queue->peek($queue_id)));
471 234
                     }
235
+                    $envoi_en_cours = "\nenvoi en cours de traitement (reste " . $outbox_sms_queue->pending() . ") ";
236
+                    $envoi_en_cours .= "par $cfg::config{last_sender}" if defined($cfg::config{last_sender});
472 237
                 }
238
+                log_bot("envoi d'un pong à $msg->{Phone} $msg->{PhoneOwner} $envoi_en_cours");
239
+                $outbox_sms_queue->insert(0, [$msg->{Phone}, "pong" . $envoi_en_cours]);
473 240
             },
474 241
         );
475 242
 
476
-        if (react_on_message(\%part_from_gtalksms, \%request)) {
477
-            if (defined $request{phone} and !(is_authorized(\%request) and react_on_message(\%part_from_user, \%request))) {
478
-                $request{subject} = "SMS recu de $request{phone} $request{phone_owner}";
479
-                $mail_queue->enqueue(\%request);
480
-            }
243
+        $msg->{Phone} =~ s/^\+33/0/;
244
+        $msg->{Email} = '';
245
+
246
+        my @results = sql_request("SELECT * FROM " . $cfg::config{table} . " WHERE phone = '$msg->{Phone}'");
247
+        my $number_of_candidates = @results;
248
+        $number_of_candidates == 0 and return;
249
+        $msg->{PhoneOwner} = '(';
250
+        foreach (@results) {
251
+            $msg->{PhoneOwner} .= "$_->{firstname} $_->{lastname}";
252
+            --$number_of_candidates > 0 and $msg->{PhoneOwner} .= ' ou ';
253
+            $msg->{Email} = $_->{email};
481 254
         }
482
-        else {
483
-            log_bot("message de type inconnu: $request{body}") unless $request{body} eq "";
255
+        $msg->{PhoneOwner} .= ')';
256
+        $msg->{Subject} = "SMS recu de $msg->{Phone} $msg->{PhoneOwner}";
257
+
258
+        if (defined $msg->{Phone} and !(is_authorized(\%$msg) and react_on_message(\%part_from_user, \%$msg))) {
259
+            log_bot("message de $msg->{Phone} $msg->{PhoneOwner}");
260
+            $mail_queue->enqueue(\%$msg);
484 261
         }
485 262
 
486
-        undef %request;
263
+        undef $msg;
487 264
     }
488 265
 }
489 266
 
490
-$from_gtalksms->detach; # gère la file des événements produits par GTalkSMS
491
-$to_gtalksms->detach;   # gère la file des envois de SMS par GTalkSMS
492
-$mail->detach;          # gère la file des mails
493
-$bot->SetMessageCallBacks(message => \&messageCB);
267
+$inbox_sms->detach;    # gère la file des événements produits par GTalkSMS
268
+log_bot("inbox thread ok");
269
+$outbox_sms->detach;   # gère la file des envois de SMS par GTalkSMS
270
+log_bot("outbox thread ok");
271
+$mail->detach;         # gère la file des mails
272
+log_bot("mail thread ok");
494 273
 
495
-$bot->PresenceSend();
496
-my $roster = $bot->Roster;
497
-$roster->add($cfg::config{xmpp}->{phoneBuddy});
274
+my $loop = 0;
275
+log_bot("robot prêt");
276
+while ( 1 ) {
498 277
 
499
-while(defined($bot->Process())) { 
500
-    $bot->RosterGet();
501
-    my $status = $roster->query($cfg::config{xmpp}->{phoneBuddy},'resources');
502
-    if ($status) {
503
-        $phone_status = $status->{GTalkSMS}->{status} =~ s/^GTalkSMS - //r;
278
+    $loop++;
279
+
280
+    my $notifications = $hlink->check_notifications();
281
+    if ($notifications->{code}) {
282
+        log_bot('check_notifications: ' . HiPi::Huawei::Errors->get_error_message($notifications->{code}));
504 283
     }
505
-    else {
506
-        $phone_status = "";
284
+#TODO    elsif ($notifications->{OnlineUpdateStatus} != 10) {
285
+#TODO        trouver les significations
286
+#TODO    }
287
+    elsif ($notifications->{UnreadMessage}) {
288
+        my $inbox = $hlink->get_inbox();
289
+        if ($inbox->{code}) {
290
+            log_bot('get_inbox: ' . HiPi::Huawei::Errors->get_error_message($inbox->{code}));
291
+        }
292
+        elsif (defined $inbox->{Count} and $inbox->{Count} > 0) {
293
+#            log_bot($inbox->{Count} . " messages dans inbox");
294
+            for (my $i = 0; $i < $inbox->{Count}; $i++) {
295
+#                log_bot("id " . $inbox->{Messages}[$i]->{Index} . ", status: " . $inbox->{Messages}[$i]->{Smstat});
296
+                if ($inbox->{Messages}[$i]->{Smstat}) { # message lu
297
+                    my $delete = $hlink->delete_sms($inbox->{Messages}[$i]->{Index});
298
+                    if ($delete->{code}) {
299
+                        log_bot('delete_sms: ' . HiPi::Huawei::Errors->get_error_message($delete->{code}));
300
+                    }
301
+#                    log_bot("id " . $inbox->{Messages}[$i]->{Index} . " deleted");
302
+                }
303
+                else {
304
+                    $inbox_sms_queue->enqueue($inbox->{Messages}[$i]);
305
+#                    log_bot("id " . $inbox->{Messages}[$i]->{Index} . " enqueued");
306
+                    my $read = $hlink->set_sms_read($inbox->{Messages}[$i]->{Index});
307
+                    if ($read->{code}) {
308
+                        log_bot('set_sms_read: ' . HiPi::Huawei::Errors->get_error_message($read->{code}));
309
+                    }
310
+#                    log_bot("id " . $inbox->{Messages}[$i]->{Index} . " marked as read") if defined $inbox->{Messages}[$i]->{Index};
311
+                }
312
+            }
313
+        }
314
+    }
315
+
316
+#on vérifie toutes les 30 secondes
317
+    sleep 30;
318
+    log_bot('outbox_sms not running') unless ($outbox_sms->is_running());
319
+    next if ($loop % 20);
320
+    $loop = 0;
321
+
322
+# nettoyage des envoyés toutes les 10 minutes
323
+    my $outbox = $hlink->get_outbox();
324
+    if ($outbox->{code}) {
325
+        log_bot('get_outbox: ' . HiPi::Huawei::Errors->get_error_message($outbox->{code}));
326
+    }
327
+    elsif (defined $outbox->{Count} and $outbox->{Count} > 1) {
328
+#        log_bot($outbox->{Count} . " messages dans outbox");
329
+# on conserve le dernier envoyé
330
+        for (my $i = 1; $i < $outbox->{Count}; $i++) {
331
+            my $delete = $hlink->delete_sms($outbox->{Messages}[$i]->{Index});
332
+            if ($delete->{code}) {
333
+                log_bot('delete_sms: ' . HiPi::Huawei::Errors->get_error_message($delete->{code}));
334
+            }
335
+#            log_bot("id " . $outbox->{Messages}[$i]->{Index} . " deleted");
336
+        }
507 337
     }
508 338
 }
+14 -43
sms/bot.conf.example
... ...
@@ -5,49 +5,20 @@ use open ':std';
5 5
 use utf8;
6 6
 
7 7
 %config = (
8
-    xmpp => {
9
-        hostName => '192.168.xxx.xxx', # @IP serveur XMPP
10
-        portNumber => 5222, # port XMPP (en général 5222)
11
-        componentName => '192.168.xxx.xxx', # @IP serveur sms
12
-        userName => 'xxxxxxx', # user XMPP
13
-        passWord => 'xxxxxxx', # password de l'utilisateur
14
-        resource => 'xxxxxxx', # une ressource (cf RFC XMPP)
15
-        tls => 1,
16
-        connectionType => 'tcpip',
17
-        phoneBuddy => 'xxxxx@192.168.xxx.xxx', # le contact GTalkSMS sur XMPP (utilisateur@IP_serveur_XMPP)
18
-    },
19
-    db => {
20
-        driver => "DBI:mysql:database=xxxxx;host=xxxxxx", # database: le nom de la bdd, host: l'hôte de la bdd, type: le type de bdd (sqlite, mysql, ...) 
21
-        user => "xxxxxxx", # utilisateur de la base de donnée
22
-        password => "xxxxxxx", # son mot de passe
23
-    },
24
-    DEBUG => 0,
25
-    VERBOSE => 0,
26
-    mail => 'xxxxxxx@xxxxxxx.xxx', # pour l'envoi des mails
8
+        db => { # config du connecteur
9
+            driver => "DBI:XXXXX:database=XXXXX;host=XXXXXXXXX",
10
+            user => "XXXXXX",
11
+            password => "XXXXXXXXXX",
12
+        },
13
+        table => 'XXXXXXXX', # le nom de la table qui contient les infos
14
+        group_prefix => 'XXXXXXXXX', # le préfixe des colonnes de groupes
15
+        close_hour => 'XX', # mise en pause des envois de SMS à XX heures
16
+        begin_hour => 'XX', # reprise des envois de SMS à XX heures
17
+        mail => 'XXXXXXXX@XXXXXXXXXXXX', # envoi de mails (avec msmtp) à cette adresse
27 18
 );
28 19
 
29
-# spécifique pour la liaison avec l'appli action
30
-%sms_action = (
31
-    flag_prefix => '/var/www/owncloud/data/xxxxxxxxxx/files/xxxxxx',
32
-    flag_suffix => '.html',
33
-    flagdir => '/xxxx/xxxxxx',
34
-    flag => 'xxxxxx',
35
-);
36
-
37
-%gtalksms = (
38
-     "from"         => '^Message\s+de\s+\+33([67]\d{8})\s+:\W*',
39
-     "delivered"    => '^SMS "(.+)" pour (0\d{9}) délivré\.$',
40
-     "forget"       => '^Le destinataire par défaut est (\+33|0)\d{9}$',
41
- 
42
-);
43
-
44
-%user = (
45
-    "stop"                            => '^\s*stoppe le bousin\s*$',
46
-    "message de groupe"               => '^\s*envoi\s+[aà]\s+(\w+)\s*:\W*',
47
-    "message pour un destinataire"    => '^\s*sms\s+pour\s+(0\d{9})\s*:(.+)$',
48
-    "copie d'une base"                => '^\s*copie\s+(\w+)\s+en\s+(\w+)(.*)$',
49
-    "ajout d'une entrée dans un base" => '^\s*ajoute\s+dans\+(\w+)\s*:\n',
50
-    "ping"                            => '^\s*ping\s*$',
51
-    "test intro pour action"          => '^\s*test\s+intro\s+(\w+)\s*$',
52
-    "envoi normal pour action"        => '^\s*action\s*$',
20
+%user = ( # chaque clé correspond à une expression régulière qui sera testée sur le SMS reçu
21
+        "message de groupe"               => '^\s*envoi\s+[aà]\s+(\w+)\s*:\W*',
22
+        "message pour un destinataire"    => '^\s*sms\s+pour\s+(0\d{9})\s*:\W*',
23
+        "ping"                            => '^\s*ping\s*$',
53 24
 );