ホームページ  >  記事  >  WeChat アプレット  >  WeChatパブリックプラットフォーム開発シリーズ

WeChatパブリックプラットフォーム開発シリーズ

高洛峰
高洛峰オリジナル
2018-05-14 15:28:581668ブラウズ

WeChat パブリック プラットフォームの開発を始めるには、まず WeChat プラットフォームが何をするのに役立つのかを理解する必要があります。

公開アカウントを使用して http://mp.weixin.qq.com/ にログインし、メニュー - [高度な機能] - [開発モード] - [ドキュメントの表示] を選択すると、WeChat によって現在開発されている機能を確認できます。公共のプラットフォーム。

1. コミュニケーションメカニズム

微信公众平台开发系列

パブリックプラットフォームの主な内容は、

  • ユーザーからパブリックアカウントに送信されたメッセージを受け入れること

  • ユーザーにメッセージを返信すること

特別な説明が必要なものつまり、メッセージの送信と返信の消去は、会話内でのみ実行できる一貫したプロセスです。言い換えれば、ユーザーがあなたと会話しなければ、積極的に顧客にメッセージを送信することはできません (大量メッセージングは​​別の状況であり、回数に制限があります。また、WeChat の使用料を支払うことを申請することもできます) CRMプラットフォーム)。送受信されるすべてのメッセージは、WeChat プラットフォームによって転送される必要があります。

2. メッセージの種類

以下では、ユーザーが送信できるメッセージの種類、つまり現在受信しているメッセージの種類を紹介します。

1. メッセージ タイプを受け入れる

1.1 テキスト メッセージ:

これは、テキスト内で言及されているいくつかのキーワードに基づいて判断し、ユーザーの意味を判断して返信することができます。

1.2 画像メッセージ:

現時点では、ユーザーが画像を通じて何を表現したいのかを理解することはまだ難しいため、ほとんどの公開アカウントは画像情報を無視するか、手動で処理することを選択します。ただ一つ言えるのは、絵は綺麗だけど理解できない、ということだけです。

1.3 地理位置情報メッセージ:

ユーザーは自分の位置情報を送信します。これは、ほとんどの公開アカウントにとって重要な情報です。位置情報に基づいて、周囲のホテルを推奨するホテル予約パブリックアカウントなどのサービスを提供できます。 もう 1 つの追加機能は、位置情報を分析してテキスト メッセージに使用できることです。例えば、ユーザが「南京路歩行街」と入力すると、南京路歩行街の関連商店を提供することができる。

1.4 リンク メッセージ:

開発モードでは特に効果的な使用方法はまだありません。買い物や相談の際に、話している相手を明確にするためによく使われるかもしれません。

1.5 イベントプッシュメッセージ:

ユーザーがあなたとの会話に入ったら、最初にユーザーに挨拶することができます。このメッセージは現在バージョン 4.5 のみをサポートしており、まだ開発されていません。たとえば、ユーザーがセッションに入った後、それを振るとどうなるかなど、将来的には考える余地がたくさんあります。

2. 返信メッセージの種類

2.1 テキスト メッセージ
これは、ユーザーのメッセージに応答するために単純なテキストのみが必要な場合に、最もよく送信されるメッセージのタイプです。テキスト メッセージにはリンク アドレスを含めることができます。

微信公众平台开发系列

2.2 グラフィック メッセージ
グラフィック メッセージ、これはプッシュ メッセージでよく見られるメッセージ形式です。コンテンツの各項目をクリックすると、より詳細な情報を表示できます (もちろん、ジャンプできないようにリンクを空に設定することもできます)

微信公众平台开发系列

2.3 音楽メッセージ
返信でユーザーに音声メッセージまたは音楽を提供します。多くのユーザーに支持されています。
パブリックプラットフォームの通信メカニズムとメッセージタイプを理解したら、次に開発環境の準備を始めます

1.開発者モードになるように設定します

WeChat作業プラットフォームにログインし、高度な機能を選択して開発に入りますモードを選択して開発者になります。以下に示すように設定する必要があります。 URL 構成情報は、WeChat のバックエンド サーバーがユーザー メッセージを処理のために URL に送信することを意味します。トークンは、ユーザーと WeChat の間のパスワードであり、メッセージがシステムを攻撃する他のユーザーからではなく、WeChat のサービスから送信されたものであるかどうかを確認するために使用されます。

まだ設定することはできません。設定時に、WeChat は設定した URL に対して GET リクエストを実行し、インターフェースが使用できるかどうかを確認します。これは、GET メソッドの準備ができた後にのみ設定できます。

微信公众平台开发系列

2. GET メソッドを実装します

ドキュメントからわかるように、POST メソッドと GET メソッドを実装する必要があります。GET メソッドは WeChat と通信の検証を検証するために使用され、POST は次の目的で使用されます。メッセージ処理。

新しいサーブレット HelloWeChat を作成し、最初に GET メソッドを実装します

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        // TODO 为了简单起见,先不对消息来源进行校验
        response.setContentType("text/html;charset=UTF-8"); 
        PrintWriter pw = response.getWriter(); 
        String echo = request.getParameter("echostr"); 
        echo = new String(echo.getBytes("ISO-8859-1"),"UTF-8"); 
        pw.println(echo); 
    }

http://localhost:8080/QiyadengWeb/HelloWeChat?echostr=hello 中国語をローカルでテストして、問題がなければ、サーバーにデプロイしてから、WeChat パブリック プラットフォームにセットアップできます。 。

3. POST メソッドを実装します

POST メソッドは、まず WeChat パブリック プラットフォームから送信された XML を受信し、メッセージ送信者とメッセージのコンテンツを抽出します。メッセージ送信コンテンツをさらに追加するには、独自の処理ロジックを追加し、最終的にそれを返信メッセージ XML に組み立てて、WeChat パブリック プラットフォームに返すことができます。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        response.setContentType("text/html;charset=UTF-8"); 
        PrintWriter pw = response.getWriter(); 
        String wxMsgXml = IOUtils.toString(request.getInputStream(),"utf-8"); 
        WeChatTextMessage textMsg = null; 
        try { 
            textMsg = getWeChatTextMessage(wxMsgXml); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        StringBuffer replyMsg = new StringBuffer(); 
        if(textMsg != null){ 
            //增加你所需要的处理逻辑,这里只是简单重复消息
            replyMsg.append("您给我的消息是:"); 
            replyMsg.append(textMsg.getContent()); 
        } 
        else{ 
            replyMsg.append(":)不是文本的消息,我暂时看不懂"); 
        } 
        String returnXml = getReplyTextMessage(replyMsg.toString(), textMsg.getFromUserName()); 
        pw.println(returnXml); 
    }

デバッグに関しては、Fiddler が推奨するツールを紹介します。毎回デバッグのためにサーバーにデプロイすることなく、WeChat POST メッセージをローカルにシミュレートできます。 Fiddler の POST データの使用方法については、下図のマークの内容を参照してください。

微信公众平台开发系列

4. デプロイとテスト

最初のステップを完了し、メッセージに返信することに問題がなければ、おめでとうございます

微信公众平台开发系列

5. 依存関係ライブラリ

Maven を使用している学生は、次の依存関係を追加するだけです。 Maven 以外のユーザーの場合は、これらのライブラリを見つけてビルダー パスに追加するだけです。

<dependency> 
    <groupId>joda-time</groupId> 
    <artifactId>joda-time</artifactId> 
    <version>2.2</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.commons</groupId> 
    <artifactId>commons-io</artifactId> 
    <version>1.3.2</version> 
</dependency> 
<dependency> 
    <groupId>com.thoughtworks.xstream</groupId> 
    <artifactId>xstream</artifactId> 
    <version>1.4.3</version> 
</dependency>

6. 完全なコード

package com.qiyadeng.wechat; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.util.Date; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.apache.commons.io.IOUtils; 
import com.thoughtworks.xstream.XStream; 
import com.thoughtworks.xstream.io.xml.DomDriver; 
/**
 * Servlet implementation class HelloWeChat
 */
public class HelloWeChat extends HttpServlet { 
    private static final long serialVersionUID = 1L; 
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloWeChat() { 
        super(); 
    } 
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        // TODO 为了简单起见,先不对消息来源进行校验
        response.setContentType("text/html;charset=UTF-8"); 
        PrintWriter pw = response.getWriter(); 
        String echo = request.getParameter("echostr"); 
        echo = new String(echo.getBytes("ISO-8859-1"),"UTF-8"); 
        pw.println(echo); 
    } 
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        response.setContentType("text/html;charset=UTF-8"); 
        PrintWriter pw = response.getWriter(); 
        String wxMsgXml = IOUtils.toString(request.getInputStream(),"utf-8"); 
        WeChatTextMessage textMsg = null; 
        try { 
            textMsg = getWeChatTextMessage(wxMsgXml); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        StringBuffer replyMsg = new StringBuffer(); 
        if(textMsg != null){ 
            //增加你所需要的处理逻辑,这里只是简单重复消息
            replyMsg.append("您给我的消息是:"); 
            replyMsg.append(textMsg.getContent()); 
        } 
        else{ 
            replyMsg.append(":)不是文本的消息,我暂时看不懂"); 
        } 
        String returnXml = getReplyTextMessage(replyMsg.toString(), textMsg.getFromUserName()); 
        pw.println(returnXml); 
    } 
    private WeChatTextMessage getWeChatTextMessage(String xml){ 
        XStream xstream = new XStream(new DomDriver()); 
        xstream.alias("xml", WeChatTextMessage.class); 
        xstream.aliasField("ToUserName", WeChatTextMessage.class, "toUserName"); 
        xstream.aliasField("FromUserName", WeChatTextMessage.class, "fromUserName"); 
        xstream.aliasField("CreateTime", WeChatTextMessage.class, "createTime"); 
        xstream.aliasField("MsgType", WeChatTextMessage.class, "messageType"); 
        xstream.aliasField("Content", WeChatTextMessage.class, "content"); 
        xstream.aliasField("MsgId", WeChatTextMessage.class, "msgId"); 
        WeChatTextMessage wechatTextMessage = (WeChatTextMessage)xstream.fromXML(xml);  
        return wechatTextMessage; 
    } 
    private String getReplyTextMessage(String content, String weChatUser){ 
        WeChatReplyTextMessage we = new WeChatReplyTextMessage(); 
        we.setMessageType("text"); 
        we.setFuncFlag("0"); 
        we.setCreateTime(new Long(new Date().getTime()).toString()); 
        we.setContent(content); 
        we.setToUserName(weChatUser); 
        we.setFromUserName("shanghaiweather");//TODO 你的公众帐号微信号
        XStream xstream = new XStream(new DomDriver());  
        xstream.alias("xml", WeChatReplyTextMessage.class); 
        xstream.aliasField("ToUserName", WeChatReplyTextMessage.class, "toUserName"); 
        xstream.aliasField("FromUserName", WeChatReplyTextMessage.class, "fromUserName"); 
        xstream.aliasField("CreateTime", WeChatReplyTextMessage.class, "createTime"); 
        xstream.aliasField("MsgType", WeChatReplyTextMessage.class, "messageType"); 
        xstream.aliasField("Content", WeChatReplyTextMessage.class, "content"); 
        xstream.aliasField("FuncFlag", WeChatReplyTextMessage.class, "funcFlag"); 
        String xml =xstream.toXML(we); 
        return xml; 
    } 
}

位置識別は、ユーザーの位置を把握することで特別な製品やショッピング モールの推奨事項をユーザーに提供する実際のアプリケーション、特に多くの販売業者でよく使用されるメッセージです。ユーザーは次の 2 種類のメッセージを送信できます:

1. WeChat の位置情報

2. 道路名、ランドマークの建物、またはショッピング モールの名前

1. WeChat の位置情報メッセージについて理解しましょう。

<xml> 
<ToUserName><![CDATA[toUser]]></ToUserName> 
<FromUserName><![CDATA[fromUser]]></FromUserName> 
<CreateTime>1351776360</CreateTime> 
<MsgType><![CDATA[location]]></MsgType> 
<Location_X>23.134521</Location_X> 
<Location_Y>113.358803</Location_Y> 
<Scale>20</Scale> 
<Label><![CDATA[位置信息]]></Label> 
<MsgId>1234567890123456</MsgId> 
</xml>

含まれる主な情報は、ラベルの経度、緯度、位置です。ラベルに記載された位置情報をもとに、利用者に対応したサービスを提供することができます。ユーザーの経度と緯度の情報に基づいて、最新の製品や地域の製品を提供することもできます。

微信公众平台开发系列 まず、WeChatの地理的位置情報に基づいてWeChatLocationMessageクラスを定義し、XmlをWeChatLocationMessageオブジェクトに変換します

public class WeChatLocationMessage { 
    private String toUserName; 
    private String fromUserName; 
    private String createTime; 
    private String msgType; 
    private String locationx; 
    private String localtiony; 
    private String scale; 
    private String label; 
    private String msgId; 
    public static WeChatLocationMessage getWeChatLocationMessage(String xml){ 
        XStream xstream = new XStream(new DomDriver()); 
        WeChatLocationMessage  message = null; 
        xstream.alias("xml", WeChatLocationMessage.class); 
        xstream.aliasField("ToUserName", WeChatLocationMessage.class, "toUserName"); 
        xstream.aliasField("FromUserName", WeChatLocationMessage.class, "fromUserName"); 
        xstream.aliasField("CreateTime", WeChatLocationMessage.class, "createTime"); 
        xstream.aliasField("MsgType", WeChatLocationMessage.class, "msgType"); 
        xstream.aliasField("Location_X", WeChatLocationMessage.class, "locationx"); 
        xstream.aliasField("Location_Y", WeChatLocationMessage.class, "localtiony"); 
        xstream.aliasField("Scale", WeChatLocationMessage.class, "scale"); 
        xstream.aliasField("Label", WeChatLocationMessage.class, "label"); 
        xstream.aliasField("MsgId", WeChatLocationMessage.class, "msgId"); 
        message = (WeChatLocationMessage)xstream.fromXML(xml); 
        return message; 
    } 
//getter and setter
}

この記事では、例としてBaiduの地図APIを使用して最寄りの銀行を検索します。

public String getPalace(String query,String lat,String lng) throws ClientProtocolException, IOException{ 
    HttpClient httpClient = new DefaultHttpClient(); 
    String url = palceRequestUrl(query,lat,lng); 
    logger.log(Level.INFO, url); 
    HttpGet httpget = new HttpGet(url); 
    ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
    String responseBody = httpClient.execute(httpget, responseHandler); 
    logger.log(Level.INFO,"baidu response:"+responseBody); 
    return responseBody; 
} 

public String palceRequestUrl(String query,String lat,String lng) throws UnsupportedEncodingException { 
    String url = WeChatConstant.BASEURL + "place/search?query=" + URLEncoder.encode(query,"UTF-8") + "&key="
            + WeChatConstant.MAPKEY +"&location="+lat+","+lng +"&radius=2000"+"&output=" + WeChatConstant.OUTPUTFORMAT; 
    return url; 
}

結果を出力

<PlaceSearchResponse> 
    <status>OK</status> 
    <results> 
        <result> 
            <name>中国工商银行东长安街支行</name> 
            <location> 
                <lat>39.915891</lat> 
                <lng>116.41867</lng> 
            </location> 
            <address>东城区东长安街1号东方广场西三办公楼1楼</address> 
            <uid>a025683c73033c35a21de987</uid> 
            <detail_url>http://api.map.baidu.com/place/detail?uid=a025683c73033c35a21de987&amp;amp;output=html&amp;amp;source=placeapi
            </detail_url> 
            <tag>银行,王府井/东单</tag> 
        </result> 
      </results> 
</PlaceSearchResponse>

次に、百度地図に反映された最近の位置情報をグラフィックメッセージの形式でWeChatユーザーに表示します

    public static String getWeChatReplyNewsMessageByBaiduPlace(List<BaiduPlaceResponse> placeList, double lat, double lng,String userName, int size){ 
        WeChatReplyNewsMessage newsMessage = new WeChatReplyNewsMessage(); 
        List<Item> items = new ArrayList<Item>(); 
        StringBuffer strBuf = new StringBuffer(); 
        logger.log(Level.INFO,"placeList count="+placeList.size()); 
        newsMessage.setItems(items); 
        if(placeList.size()>size){ 
            newsMessage.setArticleCount(size); 
        } 
        else{ 
            newsMessage.setArticleCount(placeList.size()); 
        } 
        logger.log(Level.INFO,"article count="+newsMessage.getArticleCount()); 
        newsMessage.setCreateTime(new Date().getTime()+""); 
        newsMessage.setMsgType("news"); 
        newsMessage.setFuncFlag("0"); 
        newsMessage.setToUserName(userName); 
        newsMessage.setFromUserName(WeChatConstant.FROMUSERNAME); 
        for(int i = 0;i <newsMessage.getArticleCount();i++){ 
            BaiduPlaceResponse place = placeList.get(i); 
            Double distance = GeoUtil.DistanceOfTwoPoints(Double.valueOf(place.getLng()), Double.valueOf(place.getLat()), lng, lat, GaussSphere.Beijing54); 
            Item item = new Item(); 
            item.setTitle(place.getName()+"["+distance+"米]"+"\n"+place.getAddress()+"\n"+place.getTelephone()); 
            item.setPicUrl(""); 
            item.setUrl(place.getDetailUrl()); 
            item.setDescription(""); 
            items.add(item); 
        } 
logger.log(Level.INFO,"newMessage="+newsMessage.toString()); 
        strBuf = strBuf.append(getWeChatNewsMessage(newsMessage)); 
        return strBuf.toString(); 
    } 
    public static String getWeChatNewsMessage(WeChatReplyNewsMessage newsMessage){ 
        XStream xstream = new XStream(new DomDriver()); 
        xstream.alias("xml", WeChatReplyNewsMessage.class); 
        xstream.aliasField("ToUserName", WeChatReplyNewsMessage.class, "toUserName"); 
        xstream.aliasField("FromUserName", WeChatReplyNewsMessage.class, "fromUserName"); 
        xstream.aliasField("CreateTime", WeChatReplyNewsMessage.class, "createTime"); 
        xstream.aliasField("MsgType", WeChatReplyNewsMessage.class, "msgType"); 
        xstream.aliasField("ArticleCount", WeChatReplyNewsMessage.class, "articleCount"); 
        xstream.aliasField("Content", WeChatReplyNewsMessage.class, "content"); 
        xstream.aliasField("FuncFlag", WeChatReplyNewsMessage.class, "funcFlag"); 
        xstream.aliasField("Articles", WeChatReplyNewsMessage.class, "items"); 
        xstream.alias("item", Item.class); 
        xstream.aliasField("Title", Item.class, "title"); 
        xstream.aliasField("Description", Item.class, "description"); 
        xstream.aliasField("PicUrl", Item.class, "picUrl"); 
        xstream.aliasField("Url", Item.class, "url"); 
        return xstream.toXML(newsMessage); 
    }

2. 道路名、ランドマークの建物、またはショッピングモールの名前

はい 道路などの情報については名前やランドマークの建物の情報を取得する場合でも、入力された位置情報の経度と緯度を決定するために、この方法は依然としてサードパーティの地図情報を使用します。

この記事では、Baidu Map API を使用して、探している場所の経度と緯度を特定します。

経度と緯度を決定した後は、最初のメッセージタイプと同じ問題になり、経度と緯度に応じて対応する処理が行われます。

public String getGeoCode(String query) throws ClientProtocolException, IOException{ 
        HttpClient httpClient = new DefaultHttpClient(); 
        String url = geoCodeRequestUrl(query); 
        logger.log(Level.INFO, url); 
        HttpGet httpget = new HttpGet(url); 
        ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
        String responseBody = httpClient.execute(httpget, responseHandler); 
        logger.log(Level.INFO,"baidu response:"+responseBody); 
        return responseBody; 
    } 
    public String geoCodeRequestUrl(String query) throws UnsupportedEncodingException{ 
        String url = WeChatConstant.BASEURL + "geocoder?address=" + URLEncoder.encode(query,"UTF-8") + "&key="
                + WeChatConstant.MAPKEY + "&output=" + WeChatConstant.OUTPUTFORMAT; 
        return url; 
    }
微信公众平台开发系列 その他の WeChat パブリック プラットフォーム開発シリーズ関連記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。