Overview

An SMS campaign is a form of marketing that allows you to interact with your customers via text. It is faster and easier to create since it requires no creative other than an initial campaign to get your customers’ numbers, and your 160 character message

There are two different kinds of SMS Campaigns

  • Promotional
  • Transactional

Promotional SMS campaigns can be used to reach out more than one client. For example If organization wants promote some product or organization wants to give heads up for their loan repayment dates. Transactional SMS campaigns can be used to reach out a targeted client. For example message about loan repayment successful or message about CR/DR transactions on client's savings account.

In fineract, promotional SMS campaigns are further divided into two groups.

  • Direct - If organization wants to send an SMS one time, it has to create Direct SMS Campaigns
  • Scheduled - If organization wants to send an SMS recurrently, then it has to create Scheduled SMS Campaigns

High Level Component Diagram

Requirements/User Stories

#TitleUser StoryNotes
1Create SMS CampaignAs a user I should be able to create DIRECT SMS Campaign 
2Update SMS CampaignAs a user I should be able to update message in SMS Campaign 
3Activate SMS CampaignAs a user I should be able to activate SMS Campaigns 
4Close SMS CampaignAs a user I should be able to close/deactivate SMS Campaign 
5Reactivate SMS CampaignAs a user I should be able to reactivate already closed SMS Campagin 
6Schedule job configurationAs a user I should be able to configure schedule job to send direct and scheduled SMS campaigns 
7Schedule job configurationAs a user I should be able to configure schedule job to receive SMS delivery report 
8Transactional SMS

As a user I should have a support for transactional SMS when loan is approved, loan rejected, loan repayment is done,

client is activated, client is rejected, savings account is activated, savings account is rejected, amount is deposited from savings account,

amount is withdrawn from savings account

 

Business Rule

While creating an SMS campaign, user has to attach a business rule which is nothing but a stretchy report from the platform. This business rule will be used to filter the clients. The template parameters associated to each business rule can be used to format a message for the SMS campaign. The business rules are divided into two categories.

  • Triggered - For transactional messages
  • Non-Triggered - For Promotional messages

Users are free to add new SMS (Non-Triggered) type stretchy reports to support their requirements. These newly added stretchy reports can be attached while creating Direct, Scheduled SMS Campaigns and should not be attached to Triggered SMS Campaigns. We are going to support following trigger type business rules.

  • Client Activated - Should be used to send SMS on client activation
  • Client Rejected - Should be used to send SMS on client rejection
  • Loan Approved - Should be used to send SMS on loan approval
  • Loan Rejected - Should be used to send SMS on loan rejection
  • Loan Repayment - Should be used to send SMS on loan repayment
  • Savings Activated - Should be used to send SMS on savings account activation
  • Savings Rejected - Should be used to send SMS on savings account rejection
  • Savings Withdrawal - Should be used to send SMS on amount withdrawal from savings account
  • Savings Deposit - Should be used to send SMS on amount deposit in savings account

Functionality Enhancements

DB Schema

We need to add two tables to store SMS Campaign details and Outbound message details. The tables are described below.

sms_campaign

NameDatatypeLengthRemarksDescription
idBIGINT20PRIMARY KEY & AUTO INCREMENT 
campaign_nameVARCHAR100NOT NULL 
campaign_typeINT3NOT NULLby default SMS. In future it can be used for MAIL
campaign_trigger_typeINT3NOT NULLDIRECT / SCHEDULED / TRIGGERED
report_idINT5NOT NULLBusiness rule ID
provider_idINT20NOT NULLSMS gateway bridge Identifier
param_valueVARCHARTEXTNULLBusiness rule parameters
status_enumINT3NOT NULLPENDING(100), ACTIVE(300), CLOSED(600)
messageTEXT NOT NULLParameterized message
submittedon_dateDATE NOT NULL 
submittedon_useridBIGINT20NOT NULLCreated user id
approvedon_dateDATE NULL DEFAULT NULL 
approvedon_useridBIGINT20NULL DEFAULT NULLApproved user id
closedon_dateDATE NULL DEFAULT NULL 
closedon_useridBIGINT20NULL DEFAULT NULL 
recurrenceVARCHAR100NULL DEFAULT NULLFor scheduled campaigns, this value defines the recurrence details
next_trigger_dateDATETIME NULL DEFAULT NULLDate on which SMS is sent again
last_trigger_dateDATETIME NULL DEFAULT NULLDate on which SMS was sent last time
recurrence_start_dateDATETIME NULL DEFAULT NULL 
is_visibleTINYINT1NULL DEFAULT '1'Soft delete

 

sms_messages_outbound

NameDatatypeLengthRemarksDescription
idBIGINT20PRIMARY KEY & AUTO INCREMENT 
group_idBIGINT20NULL DEFAULT NULL 
client_idBIGINT20NULL DEFAULT NULL 
staff_idBIGINT20NULL DEFAULT NULL 
status_enumINT5NOT NULL DEFAULT '100' 
mobile_noVARCHAR20NOT NULL 
messageVARCHAR1024NOT NULL 
campaign_idBIGINT20NOT NULL & FOREIGN KEY 
external_idVARCHAR100NULL DEFAULT NULL 
submittedon_dateDATETIME NOT NULL 
delivered_on_dateDATETIME NULL DEFAULT NULL 

 

Changes/Enhancements to Batch Jobs

We have to define 3 new jobs.

  • Send messages to SMS gateway -> Send all pending DIRECT and SCHEDULED SMS messages to message gateway
  • Update Sms Outbound with campaign message -> Create and save SMS outbound messages for all schedule campaigns
  • Get delivery reports from SMS gateway -> Get delivery reports for all SENT messages

User interaction and design

  • Create SMS Campaign - Wizard implementation

 

 

 

Rest API(s)

Create SMS Campaign : https://Domain Name/api/v1/smscampaigns
  • Method: POST
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json

  • Request Body:

     {"campaignName": "Savings Deposit Campaign",
      "campaignType": "SMS",
      "triggerType": 3,
      "providerId": 2,
      "runReportId": 180,
      "paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
      "message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}"
    }
  • Response: {"resourceId": 1 }
Update message in existing SMS Campaign : https://Domain Name/api/v1/smscampaigns/{campaignId}
  • Method: PUT
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: {"message": "Hello your savings account {savingsAccountNo} debited with {withdrawAmount}"}
  • Response: {"resourceId": 1, "changes": { "message": "Hello your savings account {savingsAccountNo} debited with {withdrawAmount}" } }
Delete existing SMS Campaign:https://DomainName/api/v1/smscampaigns/{campaignId}
  • Method: DELETE
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: N/A
  • Response: { "resourceId": 1, "changes": {}}
Get list of SMS Campaigns: https://Domain Name/api/v1/smscampaigns
  • Method: GET
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: N/A
  • Response: 
       [{ "id": 1, 
"campaignName": "Savings Deposit Campaign",
 "campaignType": "SMS",
"triggerType": 3,
"providerId": 2,
"runReportId": 180,
"reportName" : "Savings Deposit",
"paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
"message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}",
"status" : { "id":"","code":"","value":""}
}]
Retrieve One SMS Campaign: https://Domain Name/api/v1/smscampaigns/{campaignId}
  • Method: GET
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: N/A
  • Response: 
       { "id": 1, 
"campaignName": "Savings Deposit Campaign",
 "campaignType": "SMS",
"triggerType": 3,
"providerId": 2,
"runReportId": 180,
"reportName" : "Savings Deposit",
"paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
"message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}",
"status" : { "id":"","code":"","value":""}
}

       In case of Scheduled Campaign

       {
		"id": 1,
		"campaignName": "Savings Deposit Campaign"
		"campaignType": "SMS",
		"triggerType": 3,
		"providerId": 2,
		"runReportId": 180,
		"reportName" : "Savings Deposit",
		"paramValue": "{"officeId":1,"loanOfficerId":-1,"transactionId":1,"reportName":"Savings Deposit"}",
		"message": "Hello {fullName} your account is credited with {depositAmount} on {transactionDate}",
		"status" : { "id":"","code":"","value":""},
		"nextTriggerDate": "22 Jan 2017",
		"lastTriggerDate": "22 Jan 2016",
		"recurrenceStartDate":"22 Jan 2016",
		"recurrence": "YEARLY"			
       }
Activate SMS Campaign: https://Domain Name/api/v1/smscampaigns/{campaignId}?command=activate
  • Method: POST
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: { "activationDate":"01 May 2016", "locale":"en", "dateFormat":"dd MMMM yyyy" }
  • Response: 
       {"resourceId": 1,
        "changes": {
       "status": {
          "id": 300,
          "code": "smsCampaignStatus.active",
          "value": "active",
       },
       "locale": "en",
       "dateFormat": "dd MMMM yyyy",
       "activationDate": "01 May 2016"
       }

Deactivate SMS Campaign: https://Domain Name/api/v1/smscampaigns/{campaignId}?command=close

  • Method: POST
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: { "closureDate":"01 May 2016", "locale":"en", "dateFormat":"dd MMMM yyyy" }
  • Response: 
       {"resourceId": 1,
        "changes": {
       "status": {
          "id": 600,
          "code": "smsCampaignStatus.closed",
          "value": "closed",
       },
       "locale": "en",
       "dateFormat": "dd MMMM yyyy",
       "closureDate": "01 May 2016"
       }
Reactivates SMS Campaign:  https://Domain Name/api/v1/smscampaigns/{campaignId}?command=reactivate
  • Method: POST
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: { "activationDate":"01 May 2016", "locale":"en", "dateFormat":"dd MMMM yyyy" }
  • Response: 
       {"resourceId": 1,
        "changes": {
       "status": {
          "id": 300,
          "code": "smsCampaignStatus.active",
          "value": "active",
       },
       "locale": "en",
       "dateFormat": "dd MMMM yyyy",
       "activationDate": "01 May 2016"
       }


Message Gateway

Message gateway is independent deployable component which is having support for Twilio and Infobip SMS providers.

Note: Message-Gateway is not bundled with Apache Fineract. You need to download the source code, build and run it separately.

Rest API(s)

Create a tenant: http://hostName:9191/tenants/
  • Method: POST
  • Content-Type: application/json
  • Request Body: {"tenantId":"default" , "description": "Some description"}
  • Response: 
       {"123456543234abdkdkdkd"}

On tenant creation, it will return a unique app key (passphrase). This key should be used as header parameter on subsequent requests

Create an SMS bridge: http://localhost:9191/smsbridges
  • Method: POST
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: {
       "phoneNo": "+xxxxxxxxxx",
       "providerName": "Twilio SMS Provider", 
       "providerDescription": "Twilio SMS Provider",
       "providerKey":"Twilio",
       "countryCode":"+91",
       "bridgeConfigurations": [
                   {"configName":"Provider_Account_Id",
                  "configValue":"username/account id"},
                  {"configName":"Provider_Auth_Token",
                   "configValue":"accountkey/passphrase"}]

       }

  • Response: 
       {1}

Note: While creating a SMS bridge providerKey should be either 'Twilio' or 'InfoBip'

Send SMS: http://localhost:9191/sms/
  • Method: POST
  • Headers:
    • Fineract-Platform-TenantId:abcd
    • Fineract-Tenant-App-Key:tenantAppKey
  • Content-Type: application/json
  • Request Body: 

    [{

    "internalId":"55",

    "mobileNumber":"+xxxxxxxxxxxx",

    "message":"Hello from Staging",

    "providerId":"2"

    }]

  • Response: Response Status ACCEPTED
       

DB Schema

m_tenants - This table is used to save tenant id, tenant app key

NameDatatypeLengthRemarks
idBIGINT20PRIMARY KEY & AUTO INCREMENT
tenant_idVARCHAR32NOT NULL
tenant_app_keyVARCHAR100NOT NULL
descriptionVARCHAR500NULL DEFAULT NULL

 

m_sms_bridge - This table is used to save Provider details for a tenant

 NameDatatypeLengthRemarks
idBIGINT20PRIMARY KEY & AUTO INCREMENT
tenant_idBIGINT20NOT NULL & FOREIGN KEY
tenant_phone_noVARCHAR20NOT NULL
 country_codeVARCHAR5NOT NULL
provider_nameVARCHAR100NOT NULL
provider_keyVARCHAR100NOT NULL
descriptionVARCHAR200NULL DEFAULT NULL
created_onTIMESTAMP NULL DEFAULT NULL
last_modified_onTIMESTAMP NULL DEFAULT NULL

 

m_sms_bridge_configuration - This table is used to save provider account confiuration

NameDatatypeLengthRemarks
idBIGINT20PRIMARY KEY & AUTO INCREMENT
sms_bridge_idBIGINT20NOT NULL
config_nameVARCHAR100NOT NULL
config_valueVARCHAR100NOT NULL

 

m_outbound_messages - This table is used to save all outbound short messages

NameDatatypeLengthRemarks
idBIGINT20PRIMARY KEY & AUTO INCREMENT
tenant_idVARCHAR32NOT NULL & FOREIGN KEY
external_idVARCHAR100NULL DEFAULT NULL
internal_idVARCHAR100NOT NULL
delivery_error_messageVARCHAR500NULL DEFAULT NULL
source_addressVARCHAR100NULL DEFAULT NULL
sms_bridge_idBIGINT20NOT NULL
mobile_numberVARCHAR20NOT NULL
messageVARCHAR4096NOT NULL
delivery_statusINT3NOT NULL
submitted_on_dateTIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
delivered_on_dateTIMESTAMP NULL DEFAULT NULL
  • No labels