Because the demand for work, the need butt SMS gateway, when the business is a registered user, the phone needs to send a verification code; other companies are likely to use third-party interfaces, but the big point of the company, for safety, they have their own SMS message Center (SMSC)
1. business needs
- 1. docking SMS Gateway, send a message, a downlink transmission (MT) using openSMPP open source development kit
- 2. verification code using redis storage (mainly, distributed storage, support expiration time)
2. The following is a simple example of the code (including transmission message authentication code storage and redis)
pom add a dependent
<dependency> <groupId>org.opensmpp</groupId> <artifactId>opensmpp-core</artifactId> <version>3.0.2</version> </dependency>
public class SmsController { @Autowired private RedisTemplate redisTemplate; public boolean sendVerifyCode() { String destination = "8613594312686"; String host = "192.168.XX"; String port = "12345"; String userName = "test"; String password = "test"; //存储redis中的key Key = String getDestinationNumKey (Where do you want); // redis this code already exists, then redis using stored codes (transmission codes in the same expiration time of 15 minutes), or generates the 6-digit codes Object valueByKey = getValueByKey (Key); String verificationCode ? = Objects.nonNull (valueByKey) valueByKey.toString (): String.valueOf (( int ) (Math.random () * 900000 + 100000 )); // tenant (does not pass, the default default ) Boolean = sendSuccess the sendMessage (Host, Port, the userName, password, Where do you want, verificationCode); // following a successful transmission, redis codes stored and set the expiration time (default 15 minutes) IF (sendSuccess) { putValueToRedisWithTimeout (Key, verificationCode,15, TimeUnit.MINUTES); } return sendSuccess; } private String getDestinationNumKey(String destination) { return String.format("%s:%s", "DESTINATION", destination); } public boolean sendMessage(String host, String port, String userName, String password, String phonenumber, String verifyCode) { log.info("start to send sms notification, reciever,host {},port {}, userName {} password {} destinations is {} verifyCode {}", host, port, userName, password, phonenumber, verifyCode); try { TCPIPConnection connection = new TCPIPConnection(host, Integer.parseInt(port)); Session session = new Session(connection); BindRequest request = new BindTransmitter(); request.setSystemId(userName); request.setPassword(password); //SMPP protocol version request.setInterfaceVersion((byte) 0x34); request.setSystemType("SMPP"); BindResponse bind = session.bind(request); log.info("bind response debugString {},response command status {}", bind.debugString(), bind.getCommandStatus()); String content = "[Registration]" + verifyCode + " is your verification code. Valid in 15 minutes. Please do not share this code with anyone else."; SubmitSM SubmitSM = constructRequest (phonenumber, Content); // Bund faild leading cause TCPIPConnection Close Close causing outputStream NO SubmitSMResp Response = session.submit (submitSM); log.info ( " Send Message Result {}, {IS Command Status } " , response.debugString (), response.getCommandStatus ()); } the catch (Exception E) { log.error ( " Invoke the session Exception SMS " , E); } } Private SubmitSM constructRequest(String phoneNumber, String content) throws WrongLengthOfStringException, UnsupportedEncodingException { String recipientPhoneNumber = phoneNumber; SubmitSM request = new SubmitSM(); request.setDestAddr(createAddress(recipientPhoneNumber)); request.setShortMessage(content, Data.ENC_UTF8); request.setReplaceIfPresentFlag((byte) 0); request.setEsmClass((byte) 0); request.setProtocolId((byte) 0); request.setPriorityFlag((byte) 0); request.setRegisteredDelivery((byte) 1);// we want delivery reports request.setDataCoding((byte) 0); request.setSmDefaultMsgId((byte) 0); return request; } private Address createAddress(String address) throws WrongLengthOfStringException { Address addressInst = new Address(); // national ton addressInst.setTon((byte) 1); // numeric plan indicator addressInst.setNpi((byte) 1); addressInst.setAddress(address, Data.SM_ADDR_LEN); return addressInst; } /** * Redis中存储Value(value可为string,map,list,set等),并设置过期时间 * * @param key * @param value * @param timeout * @param unit */ public void putValueToRedisWithTimeout(Object key, Object value, final long timeout, final TimeUnit unit) { try { ValueOperations valueOperations = redisTemplate.opsForValue(); valueOperations.set(key, value, timeout, unit); } catch (Exception e) { } } / * * * Key The Get Value Value * * @param Key * / public Object getValueByKey (Object Key) { Object value = null ; the try { ValueOperations valueOperations = redisTemplate.opsForValue (); value . ValueOperations = GET (Key) ; } the catch (Exception E) { } return value; } / * * * Key The Get value value * * @param Key * / public Object deleteKey(Object key) { Object value = null; try { if (redisTemplate.hasKey(key)) { redisTemplate.delete(key); } } catch (Exception e) { } return value; } }
3. Verify PIN
Here the code is not posted, directly from the phone number to redis query, if value is compared whether right or wrong, without value, direct throw to the verification code is invalid
4. docking gateway api
Please refer to : https://www.world-text.com/docs/interfaces/SMPP/ and https://www.smssolutions.net/tutorials/smpp/smpperrorcodes/
The SMS gateway simulator
Docking test how the test environment is a problem, find a simulation SMPP from the Internet, I feel very good use, share address here: SMPP simulator
Other references:
https://support.nowsms.com/discus/messages/1/SMPP_v3_4_Issue1_2-24857.pdf
https://www.activexperts.com/sms-component/smpp-specifications/smpp-pdu-definition/
https://zhuanlan.zhihu.com/p/58237629