Broadcast By SMS

For developer

Introduction

The Ozeki Phone System Broadcast By SMS is an excellent software product that enables you to send automated test messages. It is the most advanced technology available today. It reaches people by phone with personalised and automated SMSs. It operates 24/7 so it is the best solution for a stable automated system. Ozeki Broadcast By SMS is the ideal platform for sending alerts and notifications, direct marketing options, etc.

Software requirements

  • Microsoft Windows
  • Microsoft Visual Studio
  • Ozeki Phone System

Installation and Configuration of Ozeki Phone System

In order to connect to the server, Ozeki Phone System has to be installed. A Setup Guide can be found here: How to install and configurate your Ozeki Phone System, the installation package can be downloaded from the following page: Download. After the installation, the main page of the PBX can be accessed on the http://localhost:7777/Home address (Figure 1).

ozeki phone system login screen
Figure 1 - Ozeki Phone System login screen

For the first login attempt, use the username and password, which was provided during the installation process.

New user can be added to the system with the Add user button. It can be found under the Office users menu item in the Connections menu (Figure 2).

add new user
Figure 2 - Add new user

The username and password specified here can be used to connect to the system, in the OPSClient LoginAsync method (Figure 3).

new user configuration panel
Figure 3 - New user configuration panel

Project development

  1. Let us create a new WPF Application project with the help of File/New/Project menu item.
  2. Let us add the OPSSDK.dll file to the project references in the Solution Explorer by clicking on Add Reference… menu item. This will ensure the connection interface to Ozeki Phone System.

1 OPS SMS Sender

The Ozeki Phone System SMS Sender makes it possible to send messages based on a specified list when connected to Ozeki Phone System. The SMS Sender forwards the message to Ozeki Phone System and in case there is an appropriately configured SMPP Outside line and a Dial plan rule, then the message is sent to the Outside line. The SMPP Outside line sends the message to the addressee and sends back a notification about its success. Simultaneous SMS sending is allowed depending on the number of the simultaneous message sedning that was set. This makes message sending automated and clean. The different groups can be saved into different lists and later, pre-written messages can be sent to the groups based on these lists.

1.1 Settings

After this, an Extension has to be added that will receive the incoming requests from the clients. On the right hand side of the Home screen, click on the Install New button in the Extension section (Figure 4).

install new button in extension section
Figure 4 - Install New button in the Extension section

From the appearing bullet, the API Extension will be needed (Figure 5).

install api extension
Figure 5 - Install API Extension

Select the ’Install’ button. The ’Extension number’ that you can see here will be needed for configuring the lient. You can leave every settings intact in this configuration form, it will work perfectly. Click on ’OK’ to save it.

After this, install an SMPP Connection Outside line as well. To do so, click on the ’Install new’ button in the Outside line section of the Home screen (Figure 6).

outside lines section
Figure 6 - Outside lines section

Now select the SMPP Connection with the help of the Install button (Figure 7).

smpp connection in outside lines section
Figure 7 - SMPP connection in Outside lines section

Then configure the SMPP Server with the help of the information received from the SMS provider.

Besides this, it is necessary to add a Dial plan rule. To do that, go back to the Home screen and select the ’Add rule’ button (Figure 8).

dial plans
Figure 8 - Dial plans

You can write anything you want in the Description field that reminds us for the purpose of the rule; it can be modified later. You can configure on the Source tab from which device you can receive information. Select the previously set API extension from the combobox, which belongs to the ’Specific extension’.On the Condition tab, the SMS is specified at the Type field. Then by clicking on the Destination tab, the device on which the information should be forwarded needs to be provided. In this case, let it be ’Send to outside line SMPPService1 – SMPP Connection and call dialed number’ (Figure 9).

dial plan rule and destination section
Figure 9 - Dial plan rule and destination section

The rule can be saved by clicking on ’OK’.

Now, only the final step remains. On the Home interface of Ozeki Phone System select the Connections from the upper menu bar and then select the Office users menu item (Figure 10).

connections bar from upper menu
Figure 10 - Connections bar from the upper menu

On the appearing interface click on the Add user button, which is located on the right. Fill in the form that appears on the General tab. Next, click on the ’OK’ button. This way a new user is created. Later, the login to the Ozeki Phone System SMS Sender will take place with the data that was provided here.

Now everything is set on the Server side. Continue with the Client side. After installing and starting the Ozeki Phone System SMS Sender, a login window appears. Provide the Server address in this window. In case the server address is unknown, the easiest way to find it out is to open the Home screen of Ozeki Phone System. The part located before the colon of the browser track will be the Server Address. Next, provide the data of the previously created user and click on the Login button. It is practical to have the data remembered by enabling the ’Remember me’ checkbox. Please note that the login is successful only when every data is correct and Ozeki Phone System is running in the background as well.

After the successful login, click on the Settings menu item. Specify the value of the previously created API Extension’s ’Extension number’ in the ’Extension ID’ field and then click on the ’Save’ button. After that, click on the ’Open’ icon, browse the folder of the application and select the TestEntries.csv document. Thus a line appears in which the e-mail address can be provided where the message has to be sent with the Subject and the Content included in the line. After this is done, click on the ’Start’ icon. Next, the result can be seen in the State column. For more information, select the log menu of the SMPP provider, which was set in Ozeki Phone System.

Select the ’Save’ command and save it to an appropriate place. Then this document can be edited with a spreadsheet or a text editor. New lines can be added to it but be aware of preserving the data structure, the optional commas and line breaks. The best way to edit is by using a spreadsheet.

1.2 Model

1.2.1 About configuration classes

It serves to store, save in a standard way and load certain settings given by a user. It is inherited from the class BaseModel and it implements the ICloneable and the IDataErrorInfo interfaces. As a result, the Raise method (inherited from the BaseModel) can be called on every property of this class, making the communication simpler with the GUI. The writing of the Clone() method is important because the settings have to be saved if they are valid and the user saves it. Displaying data on the user interface can be implemented with data binding. If the interface is modified, it would appear in the Model layer as well, although it is not practical. The data can only be saved to the Model layer after validation. When the data is displayed, we do not specify the data classes directly but a cloned copy. If any modification is made, it will be executed on the cloned copy, not on the original class. When it is about saving, check the validity of this copy. If it is valid, overwrite the configuration files handled by SettingsRepository.

The data can be validated by the properties of the IDataErrorInfo interface.

1.2.2 SMSConfig

By setting the ConcurrentWorks property, the number of the executable simultaneous tasks can be defined. This is where the ExtensionId property is located. The purpose of this property is that to determine the extension of Ozeki Phone System, which will be used for communicating with the application.

In this class, we can also see the Item and Error properties, provided by the IDataErrorInfo interface. These are responsible for letting users to save only valid status. Such a status examination is e.g. the condition, which refers to the "ExtensionId". According to this condition, the value of the property can only be a series containing empty characters, otherwise the "Extension ID cannot be empty" text will be passed to the LoginWindow. The ConcurrentWorks property works in a similar way, by looking at its code it can be seen that 1 is the minumum value for this property.

The IsValid property of the class is made up from the above things.

1.2.3 SmsEntry

This class is for store and handle tasks that are form the BaseModel. This way, the class inherits the methods and events of BaseModel. Later this class will be referred to as task class. This class will be passed as a T generic parameter. We can observe how simply the Raise method can be used defined in the BaseModel:

[ReadOnlyProperty]
[ExportIgnoreProperty]
public WorkState State
{
	get { return state; }
	set { state = value; Raise(() => State); }
}

[InvisibleProperty]
[ExportIgnoreProperty]
public bool IsCompleted
{
	get { return isCompleted; }
	set { isCompleted = value; Raise(() => IsCompleted); }
}
	

As we mention it in the parent class, the Raise method is responsible for make the modifications of the properties appear on the GUI.

It is worth observing the usage of Attributes placed on properties and also how the class implements the ICompletedWork interface.

1.2.4 SMSWorker

The executeable task is getting implemented in this class. It will be generated by the SmsWorkerFactory. As a parameter, it receives a task class and the IAPIExtension, which was set by the user. The setting of the IAPIExtension is about creating an Api Extension. Specify its ID here in the Client, in the SettingsWindow.

The concrete task, which has to be executed, should be provided in the StartWork() method. In case this task was successfully executed previously, just skip it. On the other hand, if the State status of the task is not Success, then continue as follows:

By using the information, which is stored in the task class,(SmsEntry) an SmsMessage is created that can be sent with the help of the received apiExtension:

var message = new SMSMessage(smsEntry.Recipient, smsEntry.Content);
messageId = message.MessageId;

apiExtension.SendMessageAsync(message, result =>
{
  switch (result.RoutingState)
    {
      case RoutingState.DestinationAccepted:
      smsEntry.State = WorkState.Routed;
      break;
      case RoutingState.DestinationNotFound:
      OnWorkCompleted(WorkState.DeliveringFailed);
      apiExtension.MessageSubmitted -=apiExtension_MessageSubmitted;
      break;
    }
});
	

As it can be seen the SendMessageAsync method is waiting for an Action<RoutingResult> parameter. This parameter will be the switch block as you can see it above. After the message forwarding had run on the server side, the Action will run. If it was successful, change the status of the tasks to Routed and in case it was unsuccessful, change it to DestinationNotFound. Furthermore, in the second case, the OnWorkCompleted eventhandler is invited as well.

In case the message was successfully forwareded, the Email Service will recive it for processing. As it can be seen, subscription took place to the apiExtension_MessageSubmitted event. In case of successful or unsuccessful sending, a feedback is received about the execution of the task. After that the WorkCompleted event will be triggered and subscribed objects will be notified about it.

1.2.5 SMSWorkerFactory

This class is responsible for producing the SmsWorker. The actual IAPIExtensionwill be set in the BroadcastViewModel and then the SmsWorkerFactory is invited by the Scheduler. This is when the SmsWorkers are generated for completing their tasks.

1.3 View

1.3.1 SettingsUC

The SettingsViewModel is set as the Datacontext of this UserControl so the properties and commands of SettingsViewModel ViewModel can be accessed from here too. The SaveCommand and CancelCommand commands are bound to Save and Cancel buttons. Their description is available at SettingsViewModel class. The GeneralSettingsUC was placed on the UserControl for referencing on a tab. This UserControl will be added later to ContentControl of SettingsWindow window.

1.3.2 GeneralSettingsUC

This UserControl is responsible for displaying and handling the data of the SmsConfig class.

This UserControl is responsible for displaying and handling the own data, which is possessed by the SmsConfig class. The items have been bounded to the SmsConfig property, which can be found in the SettingsViewModel. Read more about their task at the class descriptions.

1.4 ViewModel

1.4.1 SmsViewModel

The main window gets this ViewModel indirectly as a DataContext. In the signature you can see that the concrete SMSEntry task class is given here:

public class SMSViewModel : BroadcastMainViewModel < SMSEntry >

The BroadcastMainWindow and BroadcastMainViewModel will work with this SMSEntry task class further on as a generic T type. In its constructor we get its own settingsRepository. In this way we can pass the maximum number of tasks to the BroadcastMainViewModel that can be performed simultaneously. In this class we define the body of the GetSettingsViewModel() and GetMaxConcurrentWorkers() abstract method as well that derive from BroadcastMainViewModel.

1.4.2 SettingsViewModel

This ViewModel will be passed in the GetSettingsViewModel() of BroadcastMainViewModel method.

In this way we solve that the BroadcastMainViewModel can access and use this class and the user’s settings. We requests the settingsRepository and call the GetSettings() method. In this method we instantiate our SmsConfigproperty. If settingsRepository.GetSettings() method will not be null value, then we set the clone copy of the received settings of the SmsConfigproperty.

var config = settingsRepository.GetSettings();
if (config != null)
    SMSConfig = config.Clone() as SMSConfig; 
	

In the description of the configuration classes you can read why cloning is needed. Two RelayCommand can also be found in our class which is used for saving or rejecting saving. The SaveCommand can be executed only if the configured settings that we made now are still valid.

1.5 App.xaml

This class is a bit outside of the three layers defined by the MVVM but it is important to tell a few words about it. Since this is the entry point of the application, the general settings concerning the whole application should be given here. Firstly a SingletonApp with "OPSSmsSender" parameter is created. We can read its importance in the description of the class. Thereafter the necessary classes and interfaces will be registered in the InitDependencies() method. These classes and interfaces can be reached from any point of the program and it is guaranteed that they work as singleton. It is important that we covered our all classes that need resources with the help of an interface. We pass these interfaces and classes in InitDependencies() method but they can be changed Mock classes anytime if needed. For example we can simulate a connection with a database or with a server during the tests.

We can notice that concrete SmsEntry task class is passed as generic parameter in many cases.

SimpleIoc.Default.Register>(()
=> new CsvImporter());

SimpleIoc.Default.Register>(() 
=> new GenericSettingsRepository());
	

After the registration is completed in the Inversion of Control (IoC) container, let’s look over the OnStartup(StartupEventArgs e) method. Here we call singletonApp.OnStartup(e) method, with which we can achieve that the application can run in one instance only. If we try to do further application starts, the started application will be closed. We can read more about it in the SingletonApp section.

The application can start after the LoginViewModel class has completed the login in Ozeki Phone System and it has given the following command to the message handling system:

Messenger.Default.Send(new NotificationMessage (Messages.NavigateToMainWindow));
	

We instantiate a BroadcastMainWindow in MessageReceived method and we start it. We should not forget that SmsEntry will be the generic parameter of BroadcastMainWindow class that is passed in the signature of SmsViewModel.

We can read the following code in app.xaml class:



	
		
	
	
	...


	

Here we give DataTemplate which will be used by SettingsWindow to display the SettingsUC UserControl. Wherever we use SettingsViewModel class, its DataTemplate will always be the configured SettingsUC since the Application.Resources defined in app.xaml class can be reached from any xaml class. That is why the icons used by the application and some resources are given here.



Download Installer    Download Source Code



More information