using Hermes.Model; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Net; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Documents; using System.Windows.Input; namespace Hermes { public partial class SmsWindow : Window { private ObservableCollection status = new ObservableCollection(); private bool sending = false; private static Regex telFrRgx = new Regex(@"^0\d{9}"); private static Regex telFrPrefixRgx = new Regex(@"^0"); public static string HashSHA1(string input) { SHA1 sha = SHA1.Create(); byte[] bHash = sha.ComputeHash(Encoding.UTF8.GetBytes(input)); StringBuilder sBuilder = new StringBuilder(); for(int i = 0; i < bHash.Length; i++) { sBuilder.Append(bHash[i].ToString("x2")); } return sBuilder.ToString(); } public SmsWindow(Window parent, List rcps) { InitializeComponent(); Owner = parent; foreach(Citoyen rcp in rcps) { SmsSendingStatus s = new SmsSendingStatus(); s.Nom = rcp.Nom; s.Prenom = rcp.Prenom; s.Mobile = rcp.TelPort.Replace(" ", "").Replace(".", ""); Match m = telFrRgx.Match(s.Mobile); if(m.Success) { // numéro FR (+33) s.Mobile = telFrPrefixRgx.Replace(s.Mobile, "+33"); } s.Status = "En attente"; status.Add(s); } lvLog.ItemsSource = status; } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if(sending) { e.Cancel = true; return; } } public void Envoyer_Click(object sender, RoutedEventArgs e) { ModelContext dbContext = ModelContext.Getinstance(); bool error = false; string message = new TextRange(messageTextBox.Document.ContentStart, messageTextBox.Document.ContentEnd).Text; Preferences pref = dbContext.Preferences.Local[0]; if(String.IsNullOrWhiteSpace(pref.ovhSmsServiceName) || String.IsNullOrWhiteSpace(pref.ovhSmsApplicationKey) || String.IsNullOrWhiteSpace(pref.ovhSmsApplicationSecret) || String.IsNullOrWhiteSpace(pref.ovhSmsConsumerKey)) { MessageBox.Show("Erreur lors de la tentative d'envoi : Clés d'accès invalides.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Error); return; } if(String.IsNullOrWhiteSpace(message)) { MessageBox.Show("Votre message est vide.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Warning); return; } envoyerButton.IsEnabled = false; annulerButton.IsEnabled = false; messageTextBox.IsEnabled = false; sending = true; Cursor previousCursor = Mouse.OverrideCursor; Mouse.OverrideCursor = Cursors.Wait; string query = $"https://eu.api.ovh.com/1.0/sms/{pref.ovhSmsServiceName}/jobs"; foreach(SmsSendingStatus stat in status) { if(!stat.Status.Equals("Envoyé")) { OVHQueryBody body = new OVHQueryBody(); body.charset = "UTF-8"; body.receivers = new string[] { stat.Mobile }; body.message = message; body.priority = "high"; body.senderForResponse = true; string bodyStr = JsonConvert.SerializeObject(body); string ts = ((Int32) DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds).ToString(); string signature = "$1$" + HashSHA1(pref.ovhSmsApplicationSecret + "+" + pref.ovhSmsConsumerKey + "+" + "POST" + "+" + query + "+" + bodyStr + "+" + ts); try { HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create(query); req.Method = "POST"; req.ContentType = "application/json"; req.Headers.Add("X-Ovh-Application:" + pref.ovhSmsApplicationKey); req.Headers.Add("X-Ovh-Consumer:" + pref.ovhSmsConsumerKey); req.Headers.Add("X-Ovh-Signature:" + signature); req.Headers.Add("X-Ovh-Timestamp:" + ts); using(System.IO.Stream s = req.GetRequestStream()) { using(System.IO.StreamWriter sw = new System.IO.StreamWriter(s)) { sw.Write(bodyStr); } } HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); using(var stream = resp.GetResponseStream()) { var reader = new StreamReader(stream); OVHResponseBody rb = JsonConvert.DeserializeObject(reader.ReadToEnd().Trim()); if(rb.validReceivers.Length > 0 && rb.validReceivers[0] != null && rb.validReceivers[0].Equals(stat.Mobile)) { stat.Status = "Envoyé"; } else { error = true; stat.Status = "Numéro de mobile invalide"; } } resp.Close(); } catch(WebException ex) { error = true; WebResponse resp = ex.Response; if(resp == null) { string errorMsg = ex.Message == null ? "" : ex.Message; stat.Status = $"Erreur de transmission : {errorMsg}"; continue; } try { using(var stream = resp.GetResponseStream()) { StreamReader reader = new StreamReader(stream); String result = reader.ReadToEnd().Trim(); stat.Status = result; } } catch(Exception) { stat.Status = $"Erreur de transmission"; } } catch(Exception ex) { error = true; string errorMsg = ex.Message == null ? "" : ex.Message; stat.Status = $"Erreur de transmission : {errorMsg}"; } } } envoyerButton.IsEnabled = true; annulerButton.IsEnabled = true; messageTextBox.IsEnabled = true; sending = false; Mouse.OverrideCursor = previousCursor; if(error) { MessageBox.Show("Plusieurs envois se sont mal déroulés. Certains numéros de téléphone ne sont peut-être pas valides.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Error); } } public void Annuler_Click(object sender, RoutedEventArgs e) { Close(); } } }