Skip to content

Commit

Permalink
Merge pull request #39 from grahamegrieve/max_message_per_phone
Browse files Browse the repository at this point in the history
import limit to number of messages per phone for a day
  • Loading branch information
grahamegrieve committed Mar 31, 2020
2 parents 6133b68 + 79b85ff commit 48dab8f
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 167 deletions.
110 changes: 55 additions & 55 deletions ClinicArrivals.Models/FhirAppointmentUpdater.cs
Original file line number Diff line number Diff line change
@@ -1,64 +1,64 @@
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using System;
using System.Linq;

namespace ClinicArrivals.Models
{
public class FhirAppointmentUpdater : IFhirAppointmentUpdater
{
public FhirAppointmentUpdater(Func<FhirClient> GetFhirClient)
{
this.GetFhirClient = GetFhirClient;
}
private Func<FhirClient> GetFhirClient;

/// <summary>
/// This will retrieve the FHIR resource, set the AppointmentType for teleconsultation,
/// include a link for the video link in the comment and update the resource
/// </summary>
/// <param name="appointment"></param>
/// <param name="videoLinkComment"></param>
public void SaveAppointmentAsVideoMeeting(PmsAppointment appt, string videoLinkComment, string VideoUrl)
{
// Get the Appointment based on the appointment having an ID
var fhirServer = GetFhirClient();
Hl7.Fhir.Model.Appointment fhirAppt = fhirServer.Read<Appointment>($"{fhirServer.Endpoint}Appointment/{appt.AppointmentFhirID}");
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using System;
using System.Linq;

namespace ClinicArrivals.Models
{
public class FhirAppointmentUpdater : IFhirAppointmentUpdater
{
public FhirAppointmentUpdater(Func<FhirClient> GetFhirClient)
{
this.GetFhirClient = GetFhirClient;
}
private Func<FhirClient> GetFhirClient;

/// <summary>
/// This will retrieve the FHIR resource, set the AppointmentType for teleconsultation,
/// include a link for the video link in the comment and update the resource
/// </summary>
/// <param name="appointment"></param>
/// <param name="videoLinkComment"></param>
public void SaveAppointmentAsVideoMeeting(PmsAppointment appt, string videoLinkComment, string VideoUrl)
{
// Get the Appointment based on the appointment having an ID
var fhirServer = GetFhirClient();
Hl7.Fhir.Model.Appointment fhirAppt = fhirServer.Read<Appointment>($"{fhirServer.Endpoint}Appointment/{appt.AppointmentFhirID}");
if (fhirAppt == null)
{
throw new Exception("Unable to read appointment " + appt.AppointmentFhirID);
}
CodeableConcept teleHealth = new CodeableConcept("http://hl7.org/au/fhir/CodeSystem/AppointmentType", "teleconsultation");
if (fhirAppt.AppointmentType == null || (fhirAppt.AppointmentType.Coding.FirstOrDefault()?.System != teleHealth.Coding[0].System
|| fhirAppt.AppointmentType.Coding.FirstOrDefault()?.Code != teleHealth.Coding[0].Code))
{
fhirAppt.AppointmentType = teleHealth;
}
CodeableConcept teleHealth = new CodeableConcept("http://hl7.org/au/fhir/CodeSystem/AppointmentType", "teleconsultation");
if (fhirAppt.AppointmentType == null || (fhirAppt.AppointmentType.Coding.FirstOrDefault()?.System != teleHealth.Coding[0].System
|| fhirAppt.AppointmentType.Coding.FirstOrDefault()?.Code != teleHealth.Coding[0].Code))
{
fhirAppt.AppointmentType = teleHealth;
}
fhirAppt.RemoveExtension("http://hl7.org.au/fhir/StructureDefinition/telehealth-videolink");
if (VideoUrl != null)
{
fhirAppt.Extension.Add(new Extension() { Url = "http://hl7.org.au/fhir/StructureDefinition/telehealth-videolink", Value = new FhirUrl(VideoUrl) });
}
fhirServer.Update(fhirAppt);
}

/// <summary>
/// This will retrieve the FHIR appointment from the server,
/// set the status value and then update back to the server
/// </summary>
/// <param name="appointment"></param>
public void SaveAppointmentStatusValue(PmsAppointment appt)
{
// Get the Appointment based on the appointment having an ID
// and update the status value
var fhirServer = GetFhirClient();
Hl7.Fhir.Model.Appointment fhirAppt = fhirServer.Read<Appointment>($"{fhirServer.Endpoint}Appointment/{appt.AppointmentFhirID}");
if (fhirAppt.Status != appt.ArrivalStatus)
{
// Don't save it if hasn't changed
fhirAppt.Status = appt.ArrivalStatus;
fhirServer.Update(fhirAppt);
}
}
}
}
fhirServer.Update(fhirAppt);
}

/// <summary>
/// This will retrieve the FHIR appointment from the server,
/// set the status value and then update back to the server
/// </summary>
/// <param name="appointment"></param>
public void SaveAppointmentStatusValue(PmsAppointment appt)
{
// Get the Appointment based on the appointment having an ID
// and update the status value
var fhirServer = GetFhirClient();
Hl7.Fhir.Model.Appointment fhirAppt = fhirServer.Read<Appointment>($"{fhirServer.Endpoint}Appointment/{appt.AppointmentFhirID}");
if (fhirAppt.Status != appt.ArrivalStatus)
{
// Don't save it if hasn't changed
fhirAppt.Status = appt.ArrivalStatus;
fhirServer.Update(fhirAppt);
}
}
}
}
3 changes: 3 additions & 0 deletions ClinicArrivals.Models/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public class Settings

public string DeveloperPhoneNumber { get; set; }

public int MessageLimitForNumber { get; set; }

public string PhoneWhiteList { get; set; }

public bool IsDoingVideo { get; set; }
Expand Down Expand Up @@ -74,6 +76,7 @@ public void CopyFrom(Settings other)
MinutesBeforeScreeningMessage = other.MinutesBeforeScreeningMessage;
MinutesBeforeVideoInvitation = other.MinutesBeforeVideoInvitation;
AutoStartServices = other.AutoStartServices;
MessageLimitForNumber = other.MessageLimitForNumber;
}
}
}
217 changes: 124 additions & 93 deletions ClinicArrivals.Models/TwilioSmsProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,93 +1,124 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;

namespace ClinicArrivals.Models
{
public class TwilioSmsProcessor : ISmsProcessor
{
Settings _settings;
public void Initialize(Settings settings)
{
_settings = settings;
System.Diagnostics.Debug.WriteLine("account: " + _settings.ACCOUNT_SID);
System.Diagnostics.Debug.WriteLine("token: " + _settings.AUTH_TOKEN);
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
}

/// <summary>
/// Send a message to the Twilio gateway
/// </summary>
/// <param name="message"></param>
public void SendMessage(SmsMessage sendMessage)
{
String url = "https://api.twilio.com/2010-04-01/Accounts/" + _settings.ACCOUNT_SID + "/Messages";
String body = "To="+sendMessage.phone+"&From="+ _settings.FromTwilioMobileNumber + "&Body="+ Uri.EscapeDataString(sendMessage.message);
var webRequest = WebRequest.Create(url);
webRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(_settings.ACCOUNT_SID + ":" + _settings.AUTH_TOKEN));
webRequest.Method = "POST";
var bytes = Encoding.UTF8.GetBytes(body);
webRequest.ContentLength = bytes.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";
using (var requestStream = webRequest.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse) webRequest.GetResponse())
{
if (response.StatusCode != HttpStatusCode.Created)
{
throw new Exception("Twilio post failed");
}
}
}

private CredentialCache GetCredential(String url)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(_settings.ACCOUNT_SID, _settings.AUTH_TOKEN));
return credentialCache;
}

/// <summary>
/// Receive the current messages from the Twilio sms gateway
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<SmsMessage>> ReceiveMessages()
{
List<SmsMessage> messages = new List<SmsMessage>();
string url = "https://clinics.healthintersections.com.au/twilio?AccountSid="+ _settings.ACCOUNT_SID;
try
{
using (var webClient = new HttpClient())
{
var result = await webClient.GetAsync(url);
var json = await result.Content.ReadAsStringAsync();
var msgs = JsonConvert.DeserializeObject<SmsMessageResponse>(json);
return msgs.messages;
}
}
catch (Exception ex)
{
// not sure what to do
System.Diagnostics.Trace.WriteLine(ex.Message);
return null;
}
}
}

public class SmsMessageResponse
{
public List<SmsMessage> messages { get; set; }

}
}
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;

namespace ClinicArrivals.Models
{
public class TwilioSmsProcessor : ISmsProcessor
{
Settings _settings;
Dictionary<String, int> numCount;
int maxMessagePerPhone = 20;
DateTime day;

public void Initialize(Settings settings)
{
_settings = settings;
System.Diagnostics.Debug.WriteLine("account: " + _settings.ACCOUNT_SID);
System.Diagnostics.Debug.WriteLine("token: " + _settings.AUTH_TOKEN);
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
if (_settings.MessageLimitForNumber > 0)
{
maxMessagePerPhone = _settings.MessageLimitForNumber;
}
}

/// <summary>
/// Send a message to the Twilio gateway
/// </summary>
/// <param name="message"></param>
public void SendMessage(SmsMessage sendMessage)
{
if (day != DateTime.Today)
{
day = DateTime.Today;
numCount.Clear();
}
if (!numCount.ContainsKey(sendMessage.phone))
{
numCount.Add(sendMessage.phone, 1);
}
else
{
int i = numCount[sendMessage.phone];
i++;
if (i == maxMessagePerPhone)
{
sendMessage.message = sendMessage.message + ". This message is that last that will be sent to this phone number today (max limit reached)";
}
else if (i > maxMessagePerPhone)
{
return; // just don't send anything
}
numCount[sendMessage.phone] = i;
}
String url = "https://api.twilio.com/2010-04-01/Accounts/" + _settings.ACCOUNT_SID + "/Messages";
String body = "To="+sendMessage.phone+"&From="+ _settings.FromTwilioMobileNumber + "&Body="+ Uri.EscapeDataString(sendMessage.message);
var webRequest = WebRequest.Create(url);
webRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(_settings.ACCOUNT_SID + ":" + _settings.AUTH_TOKEN));
webRequest.Method = "POST";
var bytes = Encoding.UTF8.GetBytes(body);
webRequest.ContentLength = bytes.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";
using (var requestStream = webRequest.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse) webRequest.GetResponse())
{
if (response.StatusCode != HttpStatusCode.Created)
{
throw new Exception("Twilio post failed");
}
}
}

private CredentialCache GetCredential(String url)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(_settings.ACCOUNT_SID, _settings.AUTH_TOKEN));
return credentialCache;
}

/// <summary>
/// Receive the current messages from the Twilio sms gateway
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<SmsMessage>> ReceiveMessages()
{
List<SmsMessage> messages = new List<SmsMessage>();
string url = "https://clinics.healthintersections.com.au/twilio?AccountSid="+ _settings.ACCOUNT_SID;
try
{
using (var webClient = new HttpClient())
{
var result = await webClient.GetAsync(url);
var json = await result.Content.ReadAsStringAsync();
var msgs = JsonConvert.DeserializeObject<SmsMessageResponse>(json);
return msgs.messages;
}
}
catch (Exception ex)
{
// not sure what to do
System.Diagnostics.Trace.WriteLine(ex.Message);
return null;
}
}
}

public class SmsMessageResponse
{
public List<SmsMessage> messages { get; set; }

}
}
Loading

0 comments on commit 48dab8f

Please sign in to comment.