Created
January 24, 2018 18:30
-
-
Save otikev/f6ad2bdbf91e486bdb383526b8565fff to your computer and use it in GitHub Desktop.
A sample Parser for M-PESA SMSs. This works as of Jan 24th 2018. The format of the SMSs might/will change in future and this will not be relevant any more.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.HashMap; | |
| import java.util.Map; | |
| import java.util.regex.Matcher; | |
| import java.util.regex.Pattern; | |
| /** | |
| * 24 Jan, 2018 | |
| * Parses MPESA SMS String through simple String manipulation. And a tiny bit of regex :-D | |
| */ | |
| public class SillyMpesaMessageParser { | |
| public Map<String,String> parse(final String message){ | |
| String[] exploded = message.toLowerCase().split(" "); | |
| //Get Transaction code | |
| String code = exploded[0]; | |
| //Get transaction type | |
| String transactionType = getTransactionType(message.toLowerCase()); | |
| //Get sender/recipient | |
| String participant = getParticipant(transactionType,message.toLowerCase()); | |
| //Get mpesa amount | |
| String amount = ""; | |
| String balance = ""; | |
| String transactionCost = ""; | |
| int moneyCount = 0; | |
| for(String str : exploded){ | |
| if(str.startsWith("ksh")){ | |
| String money = str.replace("ksh",""); | |
| if(moneyCount == 0){ | |
| amount = money; | |
| }else if(moneyCount == 1){ | |
| balance = money.substring(0,money.length()-1); | |
| }else if(moneyCount == 2){ | |
| transactionCost = money.substring(0,money.length()-1); | |
| } | |
| moneyCount++; | |
| } | |
| } | |
| Map<String,String> parsed = new HashMap<>(); | |
| parsed.put("type",transactionType.trim()); | |
| parsed.put("code",code.trim()); | |
| parsed.put("amount",amount.trim()); | |
| parsed.put("balance",balance.trim()); | |
| parsed.put("cost",transactionCost.trim()); | |
| parsed.put("participant",participant.trim()); | |
| return parsed; | |
| } | |
| private String getTransactionType(String message){ | |
| String transactionType = "unknown"; | |
| if(message.toLowerCase().contains("you have received")){ | |
| transactionType = "received"; | |
| }else if(message.toLowerCase().contains("sent to")){ | |
| transactionType = "sent"; | |
| }else if(message.toLowerCase().contains("withdraw")){ | |
| transactionType = "withdraw"; | |
| }else if(message.toLowerCase().contains("paid to")){ | |
| transactionType = "paybill"; | |
| }else if(message.toLowerCase().contains("you bought")){ | |
| transactionType = "airtime"; | |
| } | |
| return transactionType; | |
| } | |
| private String getParticipant(String transactionType, String msg){ | |
| if(transactionType.equals("received")){ | |
| Pattern findSubject = Pattern.compile("from(.*)on [1-9]"); | |
| Matcher matcher = findSubject.matcher(msg); | |
| while (matcher.find()) { | |
| return matcher.group(1); | |
| } | |
| }else if(transactionType.equals("withdraw")){ | |
| Pattern findSubject = Pattern.compile("from(.*)new m-pesa"); | |
| Matcher matcher = findSubject.matcher(msg); | |
| while (matcher.find()) { | |
| return matcher.group(1); | |
| } | |
| }else if(transactionType.equals("sent") || transactionType.equals("paybill")){ | |
| Pattern findSubject = Pattern.compile("to(.*)on [1-9]"); | |
| Matcher matcher = findSubject.matcher(msg); | |
| while (matcher.find()) { | |
| return matcher.group(1); | |
| } | |
| } | |
| return ""; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import org.junit.Before; | |
| import org.junit.Test; | |
| import java.util.Map; | |
| import static org.junit.Assert.*; | |
| public class SillyMpesaMessageParserTest { | |
| SillyMpesaMessageParser parser; | |
| @Before | |
| public void setUp() throws Exception { | |
| parser = new SillyMpesaMessageParser(); | |
| } | |
| @Test | |
| public void testReceivedMpesa(){ | |
| String msg = "MDDA561QDA Confirmed. You have received Ksh5,000.00 from JOHN DOE 0799654321 "+ | |
| "on 15/1/18 at 7:00 PM. New M-PESA balance is Ksh6,000.00. Pay bills via M-PESA."; | |
| Map<String,String> response = parser.parse(msg); | |
| assertEquals("received",response.get("type")); | |
| assertEquals("MDDA561QDA".toLowerCase(),response.get("code"));// Gets the correct transaction code | |
| assertEquals("JOHN DOE 0799654321".toLowerCase(),response.get("participant"));// Gets the correct sender | |
| assertEquals("5,000.00",response.get("amount")); | |
| assertEquals("6,000.00",response.get("balance")); | |
| assertEquals("",response.get("cost")); | |
| } | |
| @Test | |
| public void testSentMpesa(){ | |
| String msg = "MDDA561QDA Confirmed. Ksh5,000.00 sent to JOHN DOE 0799654321 "+ | |
| "on 15/1/18 at 7:00 PM. New M-PESA balance is Ksh500.00. Transaction cost, Ksh27.00."; | |
| Map<String,String> response = parser.parse(msg); | |
| assertEquals("sent",response.get("type")); | |
| assertEquals("MDDA561QDA".toLowerCase(),response.get("code"));// Gets the correct transaction code | |
| assertEquals("JOHN DOE 0799654321".toLowerCase(),response.get("participant"));// Gets the correct sender | |
| assertEquals("5,000.00",response.get("amount")); | |
| assertEquals("500.00",response.get("balance")); | |
| assertEquals("27.00",response.get("cost")); | |
| } | |
| @Test | |
| public void testWithdrawMpesa(){ | |
| String msg = "MDDA561QDA Confirmed.on 15/1/18 at 7:00 PMWithdraw Ksh2,000.00 from 99999 - Super Agent "+ | |
| "New M-PESA balance is Ksh900.00. Transaction cost, Ksh27.00."; | |
| Map<String,String> response = parser.parse(msg); | |
| assertEquals("withdraw",response.get("type")); | |
| assertEquals("MDDA561QDA".toLowerCase(),response.get("code"));// Gets the correct transaction code | |
| assertEquals("99999 - Super Agent".toLowerCase(),response.get("participant"));// Gets the correct sender | |
| assertEquals("2,000.00",response.get("amount")); | |
| assertEquals("900.00",response.get("balance")); | |
| assertEquals("27.00",response.get("cost")); | |
| } | |
| @Test | |
| public void testPaybillMpesa(){ | |
| String msg = "MDDA561QDA Confirmed. Ksh5,000.00 paid to AWESOME MARKET. on 15/1/18 at 7:00 PM. "+ | |
| "New M-PESA balance is Ksh900.00. Transaction cost, Ksh0.00."; | |
| Map<String,String> response = parser.parse(msg); | |
| assertEquals("paybill",response.get("type")); | |
| assertEquals("MDDA561QDA".toLowerCase(),response.get("code"));// Gets the correct transaction code | |
| assertEquals("AWESOME MARKET.".toLowerCase(),response.get("participant"));// Gets the correct sender | |
| assertEquals("5,000.00",response.get("amount")); | |
| assertEquals("900.00",response.get("balance")); | |
| assertEquals("0.00",response.get("cost")); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment