View Javadoc
1   package com.foxinmy.weixin4j.qy.api;
2   
3   import java.util.ArrayList;
4   import java.util.Arrays;
5   import java.util.List;
6   import java.util.Map;
7   
8   import com.alibaba.fastjson.JSON;
9   import com.alibaba.fastjson.JSONObject;
10  import com.foxinmy.weixin4j.exception.WeixinException;
11  import com.foxinmy.weixin4j.http.weixin.ApiResult;
12  import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
13  import com.foxinmy.weixin4j.model.Token;
14  import com.foxinmy.weixin4j.qy.message.CustomeMessage;
15  import com.foxinmy.weixin4j.qy.message.NotifyMessage;
16  import com.foxinmy.weixin4j.qy.model.IdParameter;
17  import com.foxinmy.weixin4j.qy.type.KfType;
18  import com.foxinmy.weixin4j.token.TokenManager;
19  import com.foxinmy.weixin4j.tuple.MpNews;
20  import com.foxinmy.weixin4j.tuple.NotifyTuple;
21  
22  /**
23   * 客服消息API
24   *
25   * @className NotifyApi
26   * @author jinyu(foxinmy@gmail.com)
27   * @date 2014年11月21日
28   * @since JDK 1.6
29   * @see <a href="https://work.weixin.qq.com/api/doc#10167">发送接口说明</a>
30   * @see com.foxinmy.weixin4j.tuple.Text
31   * @see com.foxinmy.weixin4j.tuple.Image
32   * @see com.foxinmy.weixin4j.tuple.Voice
33   * @see com.foxinmy.weixin4j.tuple.Video
34   * @see com.foxinmy.weixin4j.tuple.File
35   * @see com.foxinmy.weixin4j.tuple.News
36   * @see com.foxinmy.weixin4j.tuple.MpNews
37   */
38  public class NotifyApi extends QyApi {
39  
40  	private final TokenManager tokenManager;
41  
42  	public NotifyApi(TokenManager tokenManager) {
43  		this.tokenManager = tokenManager;
44  	}
45  
46  	/**
47  	 * 发送消息提醒(需要管理员对应用有使用权限,对收件人touser、toparty、totag有查看权限,否则本次调用失败)
48  	 * <p>
49  	 * 1) 发送人员列表存在错误的userid:执行发送,开发者需注意返回结果说明</br>
50  	 * 2)发送人员不在通讯录权限范围内:不执行发送任务,返回首个出错的userid</br>
51  	 * 3)发送人员不在应用可见范围内:不执行发送任务,返回首个出错的userid</br>
52  	 * </p>
53  	 *
54  	 * @param message
55  	 *            消息对象
56  	 * @return 如果无权限或收件人不存在,则本次发送失败;如果未关注,发送仍然执行。两种情况下均返回无效的部分(注:由于userid不区分大小写,
57  	 *         返回的列表都统一转为小写</br> { "errcode": 0, "errmsg": "ok", "invaliduser":
58  	 *         "UserID1", "invalidparty":"PartyID1", "invalidtag":"TagID1" }
59  	 * @throws WeixinException
60  	 * @see <a href="https://work.weixin.qq.com/api/doc#10167">发送接口说明</a>
61  	 * @see com.foxinmy.weixin4j.tuple.Text
62  	 * @see com.foxinmy.weixin4j.tuple.Image
63  	 * @see com.foxinmy.weixin4j.tuple.Voice
64  	 * @see com.foxinmy.weixin4j.tuple.Video
65  	 * @see com.foxinmy.weixin4j.tuple.File
66  	 * @see com.foxinmy.weixin4j.tuple.News
67  	 * @see com.foxinmy.weixin4j.tuple.MpNews
68  	 * @see com.foxinmy.weixin4j.qy.message.NotifyMessage
69  	 * @see com.foxinmy.weixin4j.qy.model.IdParameter
70  	 */
71  	public IdParameter sendNotifyMessage(NotifyMessage message)
72  			throws WeixinException {
73  		NotifyTuple tuple = message.getTuple();
74  		if (tuple instanceof MpNews) {
75  			if (((MpNews) tuple).getArticles().isEmpty()) {
76  				throw new WeixinException("notify fail:articles is required");
77  			}
78  		}
79  		Map<String, String> target = message.getTarget().getParameter();
80  		String msgtype = tuple.getMessageType();
81  		JSONObject obj = (JSONObject) JSON.toJSON(message);
82  		obj.put("msgtype", msgtype);
83  		obj.put(msgtype, tuple);
84  		if (target == null || target.isEmpty()) {
85  			obj.put("touser", "@all");
86  		} else {
87  			obj.putAll(target);
88  		}
89  		String message_send_uri = getRequestUri("message_send_uri");
90  		Token token = tokenManager.getCache();
91  		WeixinResponse response = weixinExecutor.post(
92  				String.format(message_send_uri, token.getAccessToken()),
93  				obj.toJSONString());
94  		obj = response.getAsJson();
95  		IdParameter idParameter = IdParameter.get();
96  		if (obj.containsKey("invaliduser")) {
97  			idParameter.setUserIds(Arrays.asList(obj.getString("invaliduser")
98  					.split(IdParameter.SEPARATORS)));
99  		}
100 		if (obj.containsKey("invalidparty")) {
101 			List<Integer> partyIds = new ArrayList<Integer>();
102 			for (String id : obj.getString("invalidparty").split(
103 					IdParameter.SEPARATORS)) {
104 				partyIds.add(Integer.parseInt(id));
105 			}
106 			idParameter.setPartyIds(partyIds);
107 		}
108 		if (obj.containsKey("invalidtag")) {
109 			List<Integer> tagIds = new ArrayList<Integer>();
110 			for (String id : obj.getString("invalidtag").split(
111 					IdParameter.SEPARATORS)) {
112 				tagIds.add(Integer.parseInt(id));
113 			}
114 			idParameter.setTagIds(tagIds);
115 		}
116 		return idParameter;
117 	}
118 
119 	/**
120 	 * 发送客服消息
121 	 *
122 	 * @param message
123 	 *            消息对象
124 	 * @return 发送结果
125 	 * @see <a
126 	 *      href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%9C%8D%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E">客服接口说明</a>
127 	 * @see com.foxinmy.weixin4j.tuple.Text
128 	 * @see com.foxinmy.weixin4j.tuple.Image
129 	 * @see com.foxinmy.weixin4j.tuple.Voice
130 	 * @see com.foxinmy.weixin4j.tuple.Video
131 	 * @see com.foxinmy.weixin4j.tuple.File
132 	 * @see com.foxinmy.weixin4j.qy.message.CustomeMessage
133 	 * @throws WeixinException
134 	 */
135 	public ApiResult sendCustomeMessage(CustomeMessage message)
136 			throws WeixinException {
137 		NotifyTuple tuple = message.getTuple();
138 		String msgtype = tuple.getMessageType();
139 		JSONObject obj = (JSONObject) JSON.toJSON(message);
140 		obj.put("msgtype", msgtype);
141 		obj.put(msgtype, tuple);
142 		String message_kf_send_uri = getRequestUri("message_kf_send_uri");
143 		Token token = tokenManager.getCache();
144 		WeixinResponse response = weixinExecutor.post(
145 				String.format(message_kf_send_uri, token.getAccessToken()),
146 				obj.toJSONString());
147 		return response.getAsResult();
148 	}
149 
150 	/**
151 	 * 获取客服列表
152 	 *
153 	 * @param kfType
154 	 *            客服类型 为空时返回全部类型的客服
155 	 * @return 第一个元素为内部客服(internal),第二个元素为外部客服(external)
156 	 * @see com.foxinmy.weixin4j.qy.model.IdParameter
157 	 * @see <a
158 	 *      href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%9C%8D%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E">客服列表</a>
159 	 * @throws WeixinException
160 	 */
161 	public IdParameter[] getKfList(KfType kfType) throws WeixinException {
162 		String message_kf_list_uri = getRequestUri("message_kf_list_uri");
163 		if (kfType != null) {
164 			message_kf_list_uri += "&type=" + kfType.name();
165 		}
166 		Token token = tokenManager.getCache();
167 		WeixinResponse response = weixinExecutor.get(String.format(
168 				message_kf_list_uri, token.getAccessToken()));
169 		JSONObject obj = response.getAsJson();
170 		return new IdParameter[] {
171 				obj.containsKey("internal") ? obj.getObject("internal",
172 						IdParameter.class) : null,
173 				obj.containsKey("external") ? obj.getObject("external",
174 						IdParameter.class) : null };
175 	}
176 }