1. 程式人生 > >微信開發五 被動回覆使用者訊息

微信開發五 被動回覆使用者訊息

本例中有些引用的類與方法不做過多介紹,之後會提供完整原始碼下載,請自行檢視。

簡述

當用戶傳送訊息給公眾號時(或某些特定的使用者操作引發的事件推送時),會產生一個POST請求,開發者可以在響應包(Get)中返回特定XML結構,來對該訊息進行響應(現支援回覆文字、圖片、圖文、語音、視訊、音樂)。嚴格來說,傳送被動響應訊息其實並不是一種介面,而是對微信伺服器發過來訊息的一次回覆。

微信伺服器在將使用者的訊息發給公眾號的開發者伺服器地址(開發者中心處配置)後,微信伺服器在五秒內收不到響應會斷掉連線,並且重新發起請求,總共重試三次,如果在除錯中,發現使用者無法收到響應的訊息,可以檢查是否訊息處理超時。關於重試的訊息排重,有msgid的訊息推薦使用msgid排重。事件型別訊息推薦使用FromUserName + CreateTime 排重。

如果開發者希望增強安全性,可以在開發者中心處開啟訊息加密,這樣,使用者發給公眾號的訊息以及公眾號被動回覆使用者訊息都會繼續加密(但),詳見被動回覆訊息加解密說明。

假如伺服器無法保證在五秒內處理並回復,必須做出下述回覆,這樣微信伺服器才不會對此作任何處理,並且不會發起重試(這種情況下,可以使用客服訊息介面進行非同步回覆),否則,將出現嚴重的錯誤提示。
“`
/*
* 被動回覆使用者訊息
* http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html
*/
public class BaseRespMsg {

public static XStream xstream = XMLUtil.xstream;

private String ToUserName;          // 開發者微訊號
private String FromUserName;        // 傳送方帳號(一個OpenID)
private long   CreateTime;          // 訊息建立時間 (整型)
private String MsgType;             // 訊息型別(text/image/location/link)

public String getToUserName() {
    return ToUserName;
}
public void setToUserName(String toUserName) {
    ToUserName = toUserName;
}

public String getFromUserName() {
    return FromUserName;
}
public void setFromUserName(String fromUserName) {
    FromUserName = fromUserName;
}

public long getCreateTime() {
    return CreateTime;
}
public void setCreateTime(long createTime) {
    CreateTime = createTime;
}

public String getMsgType() {
    return MsgType;
}
public void setMsgType(String msgType) {
    MsgType = msgType;
}   

}

“`

回覆訊息型別

回覆文字訊息

/*
 * 被動回覆使用者訊息
 * http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html
 */
public class BaseRespMsg {

    public static XStream xstream = XMLUtil.xstream;

    private String ToUserName;          // 開發者微訊號
    private String FromUserName;        // 傳送方帳號(一個OpenID)
    private long   CreateTime;          // 訊息建立時間 (整型)
    private String MsgType;             // 訊息型別(text/image/location/link)

    public String getToUserName() {
        return ToUserName;
    }
    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }

    public String getFromUserName() {
        return FromUserName;
    }
    public void setFromUserName(String fromUserName) {
        FromUserName = fromUserName;
    }

    public long getCreateTime() {
        return CreateTime;
    }
    public void setCreateTime(long createTime) {
        CreateTime = createTime;
    }

    public String getMsgType() {
        return MsgType;
    }
    public void setMsgType(String msgType) {
        MsgType = msgType;
    }   
}

回覆圖片訊息

/*
 * MsgType--->
 * image:圖片訊息
 */
public class ImageRespMsg extends BaseRespMsg {

    private List<Image> Image;

    public List<Image> getImage() {
        if(Image == null) Image = new ArrayList<Image>();
        return Image;
    }
    public void setImage(List<Image> images) {
        Image = images;
    }

    public class Image {
        private String MediaId;     //是 通過素材管理中的介面上傳多媒體檔案,得到的id

        public String getMediaId() {
            return MediaId;
        }
        public void setMediaId(String mediaId) {
            MediaId = mediaId;
        }
    }

    /*
     * 返回的文字示例
     * <xml>
     *   <ToUserName><![CDATA[toUser]]></ToUserName>
     *   <FromUserName><![CDATA[fromUser]]></FromUserName>
     *   <CreateTime>12345678</CreateTime>
     *   <MsgType><![CDATA[image]]></MsgType>
     *   <Image>
     *       <MediaId><![CDATA[media_id]]></MediaId>
     *   </Image>
     * </xml>
     */
    public static String responseMessage(ImageRespMsg imageMessage) {
        imageMessage.setCreateTime(new Date().getTime());
      imageMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_IMAGE);

        xstream.alias("xml", imageMessage.getClass());  
        xstream.addImplicitCollection(imageMessage.getClass(), "Image");  
        xstream.alias("Image", imageMessage.new Image().getClass());
        return xstream.toXML(imageMessage);
    }

    public static String test(String xmlStr) {
        String response = "ImageRespMsg-->error";
        try {
            ImageReqMsg imageReqMsg = ImageReqMsg.requestMessage(xmlStr);
            ImageRespMsg imageRespMsg = new ImageRespMsg();
          imageRespMsg.setToUserName(imageReqMsg.getFromUserName());
          imageRespMsg.setFromUserName(imageReqMsg.getToUserName());
            int images = 1;
            for(int i=0; i<images; i++) {
                ImageRespMsg.Image image = imageRespMsg.new Image();
                image.setMediaId(imageReqMsg.getMediaId());
                imageRespMsg.getImage().add(image);
            }
            response = responseMessage(imageRespMsg);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}

回覆語音訊息

/*
 * MsgType--->
 * voice:語音訊息
 */
public class VoiceRespMsg extends BaseRespMsg {

    private List<Voice> Voice;

    public List<Voice> getVoice() {
        if(Voice == null) Voice = new ArrayList<Voice>();
        return Voice;
    }
    public void setVoice(List<Voice> voice) {
        Voice = voice;
    }

    public class Voice {
        private String MediaId;     //是 通過素材管理中的介面上傳多媒體檔案,得到的id

        public String getMediaId() {
            return MediaId;
        }
        public void setMediaId(String mediaId) {
            MediaId = mediaId;
        }
    }

    /*
     * 返回的文字示例
     * <xml>
     *   <ToUserName><![CDATA[toUser]]></ToUserName>
     *   <FromUserName><![CDATA[fromUser]]></FromUserName>
     *   <CreateTime>12345678</CreateTime>
     *   <MsgType><![CDATA[voice]]></MsgType>
     *   <Voice>
     *       <MediaId><![CDATA[media_id]]></MediaId>
     *   </Voice>
     * </xml>
     */
    public static String responseMessage(VoiceRespMsg voiceMessage) {
        voiceMessage.setCreateTime(new Date().getTime());
      voiceMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_VOICE);

        xstream.alias("xml", voiceMessage.getClass());
        xstream.addImplicitCollection(voiceMessage.getClass(), "Voice");  
        xstream.alias("Voice", voiceMessage.new Voice().getClass());
        return xstream.toXML(voiceMessage);
    }

    public static String test(String xmlStr) {
        String response = "VoiceRespMsg-->error";
        try {
            VoiceReqMsg voiceReqMsg = VoiceReqMsg.requestMessage(xmlStr);
            VoiceRespMsg voiceRespMsg = new VoiceRespMsg();
          voiceRespMsg.setToUserName(voiceReqMsg.getFromUserName());
          voiceRespMsg.setFromUserName(voiceReqMsg.getToUserName());
            int voices = 1;
            for(int i=0; i<voices; i++) {
                VoiceRespMsg.Voice voice = voiceRespMsg.new Voice();
                voice.setMediaId(voiceReqMsg.getMediaID());
                voiceRespMsg.getVoice().add(voice);
            }
            response = responseMessage(voiceRespMsg);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}

回覆視訊訊息

/*
 * MsgType--->
 * video:視訊訊息
 */
public class VideoRespMsg extends BaseRespMsg {

    private List<Video> Video;

    public List<Video> getVideo() {
        if(Video == null) Video = new ArrayList<Video>();
        return Video;
    }
    public void setImage(List<Video> video) {
        Video = video;
    }

    public class Video {
        private String MediaId;     //是 通過素材管理中的介面上傳多媒體檔案,得到的id
        private String Title;       //否 視訊訊息的標題
        private String Description; //否 視訊訊息的描述

        public String getMediaId() {
            return MediaId;
        }
        public void setMediaId(String mediaId) {
            MediaId = mediaId;
        }

        public String getTitle() {
            return Title;
        }
        public void setTitle(String title) {
            Title = title;
        }

        public String getDescription() {
            return Description;
        }
        public void setDescription(String description) {
            Description = description;
        }
    }

    /*
     * 返回的文字示例
     * <xml>
     *   <ToUserName><![CDATA[toUser]]></ToUserName>
     *   <FromUserName><![CDATA[fromUser]]></FromUserName>
     *   <CreateTime>12345678</CreateTime>
     *   <MsgType><![CDATA[video]]></MsgType>
     *   <Video>
     *      <MediaId><![CDATA[media_id]]></MediaId>
     *      <Title><![CDATA[title]]></Title>
     *      <Description><![CDATA[description]]></Description>
     *   </Video> 
     * </xml>
     */
    public static String responseMessage(VideoRespMsg videoMessage) {
        videoMessage.setCreateTime(new Date().getTime());
      videoMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_VIDEO);

        xstream.alias("xml", videoMessage.getClass());  
        xstream.addImplicitCollection(videoMessage.getClass(), "Video");  
        xstream.alias("Video", videoMessage.new Video().getClass());
        return xstream.toXML(videoMessage);
    }

    public static String test(String xmlStr) {
        String response = "VideoRespMsg-->error";
        try {
            VideoReqMsg videoReqMsg = VideoReqMsg.requestMessage(xmlStr);
            VideoRespMsg videoRespMsg = new VideoRespMsg();
          videoRespMsg.setToUserName(videoReqMsg.getFromUserName());
          videoRespMsg.setFromUserName(videoReqMsg.getToUserName());
            int videos = 1;
            for(int i=0; i<videos; i++) {
                VideoRespMsg.Video video = videoRespMsg.new Video();
                video.setMediaId(WeChatCertificate.VIDEO_MEDIAID);
                video.setTitle("title");
                video.setDescription("description");
                videoRespMsg.getVideo().add(video);
            }
            response = responseMessage(videoRespMsg);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}

回覆音樂訊息

/*
 * MsgType--->
 * music:音樂訊息
 */
public class MusicRespMsg extends BaseRespMsg {

    private List<Music> Music;

    public List<Music> getMusic() {
        if(Music == null) Music = new ArrayList<Music>();
        return Music;
    }
    public void setMusic(List<Music> music) {
        Music = music;
    }

    public class Music {
        private String Title;           //否 音樂標題
        private String Description;     //否 音樂描述
        private String MusicUrl;        //否 音樂連結
        private String HQMusicUrl;      //否 高質量音樂連結,WIFI環境優先使用該連結播放音樂
        private String ThumbMediaId;    //是 縮圖的媒體id,通過素材管理中的介面上傳多媒體檔案,得到的id

        public String getTitle() {
            return Title;
        }
        public void setTitle(String title) {
            Title = title;
        }

        public String getDescription() {
            return Description;
        }
        public void setDescription(String description) {
            Description = description;
        }

        public String getMusicUrl() {
            return MusicUrl;
        }
        public void setMusicUrl(String musicURL) {
            MusicUrl = musicURL;
        }

        public String getHQMusicUrl() {
            return HQMusicUrl;
        }
        public void setHQMusicUrl(String hQMusicUrl) {
            HQMusicUrl = hQMusicUrl;
        }

        public String getThumbMediaId() {
            return ThumbMediaId;
        }
        public void setThumbMediaId(String thumbMediaId) {
            ThumbMediaId = thumbMediaId;
        }
    }

    /*
     * 返回的文字示例
     * <xml>
     *   <ToUserName><![CDATA[toUser]]></ToUserName>
     *   <FromUserName><![CDATA[fromUser]]></FromUserName>
     *   <CreateTime>12345678</CreateTime>
     *   <MsgType><![CDATA[music]]></MsgType>
     *   <Music>
     *      <Title><![CDATA[TITLE]]></Title>
     *      <Description><![CDATA[DESCRIPTION]]></Description>
     *      <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
     *      <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
     *      <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
     *   </Music>
     * </xml>
     */
    public static String responseMessage(MusicRespMsg musicMessage) {
        musicMessage.setCreateTime(new Date().getTime());
      musicMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_MUSIC);

        xstream.alias("xml", musicMessage.getClass());
        xstream.addImplicitCollection(musicMessage.getClass(), "Music");  
        xstream.alias("Music", musicMessage.new Music().getClass());
        return xstream.toXML(musicMessage);
    }

    public static String test(String xmlStr) {
        String response = "MusicRespMsg-->error";
        try {
            TextReqMsg textReqMsg = TextReqMsg.requestMessage(xmlStr);
            MusicRespMsg musicRespMsg = new MusicRespMsg();
          musicRespMsg.setToUserName(textReqMsg.getFromUserName());
          musicRespMsg.setFromUserName(textReqMsg.getToUserName());
            int musics = 1;
            for(int i=0; i<musics; i++) {
                MusicRespMsg.Music music = musicRespMsg.new Music();
                music.setTitle("殘酷月光");
                music.setDescription(" 林宥嘉 詞:向月娥 曲:陳小霞");
                music.setMusicUrl("http://wma.5282.cc/2008-11//20140226/1.mp3");
                music.setHQMusicUrl("http://wma.5282.cc/2008-11//20140226/1.mp3");
                musicRespMsg.getMusic().add(music);
            }
            response = responseMessage(musicRespMsg);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}

回覆圖文訊息

/*
 * MsgType--->
 * news:圖文訊息
 */
public class NewsRespMsg extends BaseRespMsg {

    private int ArticleCount;       //是 圖文訊息個數,限制為10條以內
    private List<Article> Articles; //是 多條圖文訊息資訊,預設第一個item為大圖,注意,如果圖文數超過10,則將會無響應

    public int getArticleCount() {
        return ArticleCount;
    }
    public void setArticleCount(int articleCount) {
        ArticleCount = articleCount;
    }

    public List<Article> getArticles() {
        if(Articles == null) Articles = new ArrayList<Article>();
        return Articles;
    }
    public void setArticles(List<Article> articles) {
        Articles = articles;
    }

    public class Article{
        private String Title;               //否 圖文訊息標題
        private String Description;         //否 圖文訊息描述
        private String PicUrl;              //否 圖片連結,支援JPG、PNG格式,較好的效果為大圖360*200,小圖200*200
        private String Url;                 //否 點選圖文訊息跳轉連結

        public String getTitle() {
            return Title;
        }
        public void setTitle(String title) {
            Title = title;
        }

        public String getDescription() {
            return Description;
        }
        public void setDescription(String description) {
            Description = description;
        }

        public String getPicUrl() {
            return PicUrl;
        }
        public void setPicUrl(String picUrl) {
            PicUrl = picUrl;
        }

        public String getUrl() {
            return Url;
        }
        public void setUrl(String url) {
            Url = url;
        }
    }

    /*
     * 返回的文字示例
     * <xml>
     *   <ToUserName><![CDATA[toUser]]></ToUserName>
     *   <FromUserName><![CDATA[fromUser]]></FromUserName>
     *   <CreateTime>12345678</CreateTime>
     *   <MsgType><![CDATA[news]]></MsgType>
     *   <ArticleCount>2</ArticleCount>
     *   <Articles>
     *      <item>
     *          <Title><![CDATA[title1]]></Title> 
     *          <Description><![CDATA[description1]]></Description>
     *          <PicUrl><![CDATA[picurl]]></PicUrl>
     *          <Url><![CDATA[url]]></Url>
     *      </item>
     *      <item>
     *          <Title><![CDATA[title]]></Title>
     *          <Description><![CDATA[description]]></Description>
     *          <PicUrl><![CDATA[picurl]]></PicUrl>
     *          <Url><![CDATA[url]]></Url>
     *      </item>
     *   </Articles>
     * </xml>
     */
    public static String responseMessage(NewsRespMsg newsMessage) {
        newsMessage.setCreateTime(new Date().getTime());
      newsMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_NEWS);

        xstream.alias("xml", newsMessage.getClass());
        xstream.alias("item", newsMessage.new Article().getClass());
        return xstream.toXML(newsMessage);
    }

    public static String test(String xmlStr) {
        String response = "NewsRespMsg-->error";
        try {
            TextReqMsg textReqMsg = TextReqMsg.requestMessage(xmlStr);
            NewsRespMsg newsRespMsg = new NewsRespMsg();
          newsRespMsg.setToUserName(textReqMsg.getFromUserName());
          newsRespMsg.setFromUserName(textReqMsg.getToUserName());
            int articleCount = 3;
            newsRespMsg.setArticleCount(articleCount);
            for(int i=0; i<articleCount; i++) {
                NewsRespMsg.Article articla = newsRespMsg.new Article();
                articla.setTitle("title"+i);
                articla.setDescription("description"+i);
              articla.setPicUrl("http://img5.imgtn.bdimg.com/it/u=1938623644,625001929&fm=11&gp=0.jpg");
                articla.setUrl("http://www.baidu.com");
                newsRespMsg.getArticles().add(articla);
            }
            response = responseMessage(newsRespMsg);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}