callback interface

Last updated:2021-12-15
Expand all
callback interface
  • Set and verify the callback address;
  • Callback message format description;
  • Methods for testing callback functions;

Set callback address

Function description

  • Set and verify callback address

Operation path

Step1: Log in to the console
Step2: Enter the application template
Step3: Select [SMS Settings] from the menu on the right
Step4: Click to select the callback interface you want to use

Set callback address

Fill in the callback address in the console. The callback address must end with http:// or https:// At the beginning, custom ports are not supported. After filling in the callback address, it must be verified before it can be used. Verification rules:Jiguangwill give callback URL initiate a GET Requests a parameter with a random 8-digit string echostr, developers need to Response Body output as it is echostr value.

Callback message format

Callback method description

When there is a callback message, it will be used HTTP POST method to fill in the callback to the developer URL Submit notification message. It should be noted that if the callback fails, thenJiguangWill try again after a certain interval, up to three times. The time intervals for retrying callbacks are 3 minutes, 1 hour, and 12 hours respectively.

The basic parameters of the callback are as follows

KEY REQUIRE DESCRIPTION
nonce Long Random long integer
signature String signature, combination appKey、appMasterSecret、nonce、timestamp generate
timestamp Long Current timestamp, millisecond value
type String notification type (SMS_REPORT/SMS_REPLY)
data String notification content,json String, developers can use type Deserialization data

signatureGenerate verification rules

  • Will appKey、appMasterSecret、nonce、timestamp Substitute the value into the generated string appKey={appKey}&appMasterSecret={appMasterSecret}&nonce={nonce}&timestamp={timestamp};
  • Run on the generated string sha1 encryption;
  • The developer takes the received signature Compare it with the signature generated by your own local code according to the same rules. If they are consistent, you can determine that this callback comes fromJiguang。

Downstream message delivery status callback parameters

CODE TYPE DESCRIPTION
msgId String API Returned when calling msg_id
status Integer Send status return code
receiveTime Timestamp SMS delivery time
phone String SMS delivered to mobile phone number

Send status return code

CODE DESCRIPTION
4001 Sent successfully
4002 The called mobile phone number iscarriersBlacklist, need to contactcarriersdeal with
4003 Mobile phone terminal problems, mobile phone shutdown, shutdown, etc. Please confirm whether the mobile phone status is normal
4004 The called mobile phone number is empty. Please verify whether the mobile phone number is legal.
4005 Insufficient remaining space for sending text messages
4006 Send overclocking, send frequency exceedingcarrierslimit
4007 Unanswered, voice message status, voice message call successful, user did not answer or refused to answer
4008 The user is busy, voice message status, the called user is busy
4009 Unable to connect, voice message status, not in the service area, no signal on the mobile phone, or the phone is forwarded to the incoming call reminder, etc.
4010 Sensitive word interception, caused by the presence of sensitive words in the text message contentcarriersintercept
4100 Other errors

Upstream message content callback parameters

CODE TYPE DESCRIPTION
phone String Calling number (user’s mobile phone number)
replyTime Date The message was delivered toJiguangplatform time
content String The message content of the user's reply

Template review result callback parameters

CODE TYPE DESCRIPTION
tempId Integer Template ID
status Integer Template status, 1 means passed the review, 2 means failed.
refuseReason String Reasons for failure to pass the review

Signature review result callback parameters

CODE TYPE DESCRIPTION
signId Integer Signature ID
status Integer Signature status, 1 means approved, 2 means failed.
refuseReason String Reasons for failure to pass the review

callback test

Function description

  • Two methods are provided for testing callback functionality:
  1. Console callback setting page test;
  2. curl simulation POST callback request;

Console callback settings page test

The developer clicks the test button in the callback settings page,JiguangA callback will be initiated to call back the fixed test data to the callback address provided by the developer. Developers can determine whether the callback request is successful by checking whether the callback request is received and whether the received data is consistent with the table below.

KEY VALUE
content TD
phone 13000000000
replyTime 1492150740292
KEY VALUE
msgId 1857496
phone 13000000000
receiveTime 1492150740292
status 4001

Template review results callback test data

KEY VALUE
tempId 57496
status 1
refuseReason null

Signature review result callback test data

KEY VALUE
signId 123
status 1
refuseReason null

curl simulation POST callback request

exist linux It is very convenient to use curl Command initiated HTTP POST Request, at windows Need to install curl Tool software. The following is curl Example of mocking callbacks

Upstream message content callback

curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_REPLY&data={\"content\":\"TD\",\"phone\":\"13720481024\",\"replyTime\":1492150740292}" "http://localhost:8088/callback"
          curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_REPLY&data={\"content\":\"TD\",\"phone\":\"13720481024\",\"replyTime\":1492150740292}" "http://localhost:8088/callback"

        
This code block is shown in the floating window

Downstream message sending status callback

curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_REPORT&data={\"msgId\":\"1652496\",\"phone\":\"15822889320\",\"receiveTime\":1492150741392,\"status\":4001}" "http://localhost:8088/callback"
          curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_REPORT&data={\"msgId\":\"1652496\",\"phone\":\"15822889320\",\"receiveTime\":1492150741392,\"status\":4001}" "http://localhost:8088/callback"

        
This code block is shown in the floating window

Template review result callback

curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_TEMPLATE&data={\"tempId\":57496,\"status\":1,\"refuseReason\":null}" "http://localhost:8088/callback"
          curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_TEMPLATE&data={\"tempId\":57496,\"status\":1,\"refuseReason\":null}" "http://localhost:8088/callback"

        
This code block is shown in the floating window

Signature review result callback

curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_SIGN&data={\"signId\":57496,\"status\":1,\"refuseReason\":null}" "http://localhost:8088/callback"
          curl -d "nonce=7659972084945889195&timestamp=1492150740274&signature=007eff6a105503211b472802eecc42465582ba70&type=SMS_SIGN&data={\"signId\":57496,\"status\":1,\"refuseReason\":null}" "http://localhost:8088/callback"

        
This code block is shown in the floating window

HttpClient simulation POST callback request

The following is Java language use apache HttpClient An example of component simulation callback, the following needs to be introduced before use jar Bag:

pom.xml

<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.31</version> </dependency>
               <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.31</version>
        </dependency>   

        
This code block is shown in the floating window

CallbackTest.java

package cn.jiguang.sms.dev.sample; import com.alibaba.fastjson.JSON; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; /** * Created by jiguang on 2017/4/14. */ public class CallbackTest { private final static String URL = "http://localhost:8088/callback"; // 开发者将自己的回调URL写入 private final static String APPKEY = "dev_sample_appKey"; // 开发者将自己的appKey写入 private final static String APPMASTERSECRET = "dev_sample_appMasterSecret"; // 开发者将自己的appMasterSecret写入 public static void main(String[] args) throws IOException { long nonce = new Random().nextLong(); long timestamp = System.currentTimeMillis(); String str = String.format("appKey=%s&appMasterSecret=%s&nonce=%s&timestamp=%s", APPKEY, APPMASTERSECRET, nonce, timestamp); String signature = encrypt(str); Map<String, Object> params = new HashMap<>(); params.put("nonce", nonce); params.put("timestamp", timestamp); params.put("signature", signature); // 测试用户回复消息回调 ReplyMessage replyMessage = new ReplyMessage(); replyMessage.setPhone("13720481024"); replyMessage.setReplyTime(new Date()); replyMessage.setContent("TD"); params.put("data", JSON.toJSONString(replyMessage)); params.put("type", "SMS_REPLY"); System.out.println("post params: " + JSON.toJSONString(params)); sendPost(URL, params); // 测试短信送达状态回调 ReportMessage reportMessage = new ReportMessage(); reportMessage.setMsgId("1652496"); reportMessage.setStatus(4001); reportMessage.setPhone("15822889320"); reportMessage.setReceiveTime(new Date()); params.put("data", JSON.toJSONString(reportMessage)); params.put("type", "SMS_REPORT"); System.out.println("post params: " + JSON.toJSONString(params)); sendPost(URL, params); // 测试短信模板审核结果回调 TemplateMessage templateMessage = new TemplateMessage(); templateMessage.setTempId(57496); templateMessage.setStatus(1); templateMessage.setRefuseReason(null); params.put("data", JSON.toJSONString(templateMessage)); params.put("type", "SMS_TEMPLATE"); System.out.println("post params: " + JSON.toJSONString(params)); sendPost(URL, params); } private static void sendPost(String url, Map<String, Object> params) throws IOException { HttpClient httpClient = HttpClients.custom().build(); HttpPost httpPost = new HttpPost(url); List<NameValuePair> formParams = new ArrayList<>(); for (Map.Entry<String, Object> entry : params.entrySet()) { formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString())); } UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formParams, "UTF-8"); httpPost.setEntity(uefEntity); HttpResponse response = httpClient.execute(httpPost); System.out.println("response: " + JSON.toJSONString(response)); } private static class ReplyMessage { private String phone; private Date replyTime; private String content; public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Date getReplyTime() { return replyTime; } public void setReplyTime(Date replayTime) { this.replyTime = replayTime; } } private static class ReportMessage { private String msgId; private Integer status; private String phone; private Date receiveTime; public String getMsgId() { return msgId; } public void setMsgId(String msgId) { this.msgId = msgId; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public Date getReceiveTime() { return receiveTime; } public void setReceiveTime(Date receiveTime) { this.receiveTime = receiveTime; } } private static class TemplateMessage { private Integer tempId; private Integer status; private String refuseReason; public Integer getTempId() { return tempId; } public void setTempId(Integer tempId) { this.tempId = tempId; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getRefuseReason() { return refuseReason; } public void setRefuseReason(String refuseReason) { this.refuseReason = refuseReason; } } /** * SHA1加密 * * @param strSrc 明文 * @return 加密之后的密文 */ public static String encrypt(String strSrc) { MessageDigest md = null; String strDes = null; byte[] bt = strSrc.getBytes(); try { md = MessageDigest.getInstance("SHA-1");// 将此换成SHA-1、SHA-512、SHA-384等参数 md.update(bt); strDes = bytes2Hex(md.digest()); // to HexString } catch (NoSuchAlgorithmException e) { return null; } return strDes; } /** * byte数组转换为16进制字符串 * * @param bts 数据源 * @return 16进制字符串 */ private static String bytes2Hex(byte[] bts) { String des = ""; String tmp = null; for (int i = 0; i < bts.length; i++) { tmp = (Integer.toHexString(bts[i] & 0xFF)); if (tmp.length() == 1) { des += "0"; } des += tmp; } return des; } }
          
package cn.jiguang.sms.dev.sample;  
 
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;  
 
/**  
 * Created by jiguang on 2017/4/14.  
 */  
public class CallbackTest {
    private final static String URL = "http://localhost:8088/callback"; // 开发者将自己的回调URL写入
    private final static String APPKEY = "dev_sample_appKey";       // 开发者将自己的appKey写入
    private final static String APPMASTERSECRET = "dev_sample_appMasterSecret"; // 开发者将自己的appMasterSecret写入
    public static void main(String[] args) throws IOException {
        long nonce = new Random().nextLong();
        long timestamp = System.currentTimeMillis();
        String str = String.format("appKey=%s&appMasterSecret=%s&nonce=%s&timestamp=%s",
                APPKEY, APPMASTERSECRET, nonce, timestamp);
        String signature = encrypt(str);
        Map<String, Object> params = new HashMap<>();
        params.put("nonce", nonce);
        params.put("timestamp", timestamp);
        params.put("signature", signature);

        // 测试用户回复消息回调
        ReplyMessage replyMessage = new ReplyMessage();
        replyMessage.setPhone("13720481024");
        replyMessage.setReplyTime(new Date());
        replyMessage.setContent("TD");
        params.put("data", JSON.toJSONString(replyMessage));
        params.put("type", "SMS_REPLY");
        System.out.println("post params: " + JSON.toJSONString(params));
        sendPost(URL, params);

        // 测试短信送达状态回调
        ReportMessage reportMessage = new ReportMessage();
        reportMessage.setMsgId("1652496");
        reportMessage.setStatus(4001);
        reportMessage.setPhone("15822889320");
        reportMessage.setReceiveTime(new Date());
        params.put("data", JSON.toJSONString(reportMessage));
        params.put("type", "SMS_REPORT");
        System.out.println("post params: " + JSON.toJSONString(params));
        sendPost(URL, params);

        // 测试短信模板审核结果回调
        TemplateMessage templateMessage = new TemplateMessage();
        templateMessage.setTempId(57496);
        templateMessage.setStatus(1);
        templateMessage.setRefuseReason(null);
        params.put("data", JSON.toJSONString(templateMessage));
        params.put("type", "SMS_TEMPLATE");
        System.out.println("post params: " + JSON.toJSONString(params));
        sendPost(URL, params);
    }

    private static void sendPost(String url, Map<String, Object> params) throws IOException {
        HttpClient httpClient = HttpClients.custom().build();
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> formParams = new ArrayList<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
        }
        UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formParams, "UTF-8");
        httpPost.setEntity(uefEntity);
        HttpResponse response = httpClient.execute(httpPost);
        System.out.println("response: " + JSON.toJSONString(response));
    }

    private static class ReplyMessage {
        private String phone;
        private Date replyTime;
        private String content;
        public String getPhone() {
            return phone;
        }
        public void setPhone(String phone) {
            this.phone = phone;
        }
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
        public Date getReplyTime() {
            return replyTime;
        }
        public void setReplyTime(Date replayTime) {
            this.replyTime = replayTime;
        }
    }

    private static class ReportMessage {
        private String msgId;
        private Integer status;
        private String phone;
        private Date receiveTime;
        public String getMsgId() {
            return msgId;
        }
        public void setMsgId(String msgId) {
            this.msgId = msgId;
        }
        public Integer getStatus() {
            return status;
        }
        public void setStatus(Integer status) {
            this.status = status;
        }
        public String getPhone() {
            return phone;
        }
        public void setPhone(String phone) {
            this.phone = phone;
        }
        public Date getReceiveTime() {
            return receiveTime;
        }
        public void setReceiveTime(Date receiveTime) {
            this.receiveTime = receiveTime;
        }
    }

    private static class TemplateMessage {
        private Integer tempId;
        private Integer status;
        private String refuseReason;
        public Integer getTempId() {
            return tempId;
        }
        public void setTempId(Integer tempId) {
            this.tempId = tempId;
        }
        public Integer getStatus() {
            return status;
        }
        public void setStatus(Integer status) {
            this.status = status;
        }
        public String getRefuseReason() {
            return refuseReason;
        }
        public void setRefuseReason(String refuseReason) {
            this.refuseReason = refuseReason;
        }
    }

    /**
     * SHA1加密
     *
     * @param strSrc 明文
     * @return 加密之后的密文
     */
    public static String encrypt(String strSrc) {
        MessageDigest md = null;
        String strDes = null;
        byte[] bt = strSrc.getBytes();
        try {
            md = MessageDigest.getInstance("SHA-1");// 将此换成SHA-1、SHA-512、SHA-384等参数
            md.update(bt);
            strDes = bytes2Hex(md.digest()); // to HexString
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
        return strDes;
    }

    /**
     * byte数组转换为16进制字符串
     *
     * @param bts 数据源
     * @return 16进制字符串
     */
    private static String bytes2Hex(byte[] bts) {
        String des = "";
        String tmp = null;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des += "0";
            }
            des += tmp;
        }
        return des;
    }
}

        
This code block is shown in the floating window
Was this document helpful?

Copyright 2011-2026, jiguang.cn, All Rights Reserved. 粤ICP备12056275号-13 Shenzhen Hexun Huagu Information Technology Co., Ltd.

Open in Docs Center