View Javadoc
1   package com.foxinmy.weixin4j.mp.api;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import com.alibaba.fastjson.JSON;
7   import com.alibaba.fastjson.JSONObject;
8   import com.foxinmy.weixin4j.exception.WeixinException;
9   import com.foxinmy.weixin4j.http.weixin.ApiResult;
10  import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
11  import com.foxinmy.weixin4j.model.Token;
12  import com.foxinmy.weixin4j.mp.model.Following;
13  import com.foxinmy.weixin4j.mp.model.Tag;
14  import com.foxinmy.weixin4j.mp.model.User;
15  import com.foxinmy.weixin4j.token.TokenManager;
16  
17  /**
18   * 标签相关API
19   * 
20   * @className TagApi
21   * @author jinyu(foxinmy@gmail.com)
22   * @date 2016年4月29日
23   * @since JDK 1.6
24   * @see com.foxinmy.weixin4j.mp.model.Tag
25   */
26  public class TagApi extends MpApi {
27  	private final TokenManager tokenManager;
28  	private final UserApi userApi;
29  
30  	public TagApi(TokenManager tokenManager) {
31  		this.tokenManager = tokenManager;
32  		this.userApi = new UserApi(tokenManager);
33  	}
34  
35  	/**
36  	 * 创建标签
37  	 * 
38  	 * @param name
39  	 *            标签名(30个字符以内)
40  	 * @return 标签对象
41  	 * @throws WeixinException
42  	 * @see com.foxinmy.weixin4j.mp.model.Tag
43  	 * @see <a
44  	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">创建标签</a>
45  	 */
46  	public Tag createTag(String name) throws WeixinException {
47  		String tag_create_uri = getRequestUri("tag_create_uri");
48  		WeixinResponse response = weixinExecutor.post(
49  				String.format(tag_create_uri, tokenManager.getAccessToken()),
50  				String.format("{\"tag\":{\"name\":\"%s\"}}", name));
51  		JSONObject obj = response.getAsJson().getJSONObject("tag");
52  		return new Tag(obj.getIntValue("id"), obj.getString("name"));
53  	}
54  
55  	/**
56  	 * 获取标签
57  	 * 
58  	 * @return 标签列表
59  	 * @throws WeixinException
60  	 * @see com.foxinmy.weixin4j.mp.model.Tag
61  	 * @see <a
62  	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">获取标签</a>
63  	 */
64  	public List<Tag> listTags() throws WeixinException {
65  		String tag_get_uri = getRequestUri("tag_get_uri");
66  		WeixinResponse response = weixinExecutor.get(String.format(tag_get_uri,
67  				tokenManager.getAccessToken()));
68  
69  		return JSON.parseArray(response.getAsJson().getString("tags"),
70  				Tag.class);
71  	}
72  
73  	/**
74  	 * 更新标签
75  	 * 
76  	 * @param tag
77  	 *            标签对象
78  	 * @return 操作结果
79  	 * @throws WeixinException
80  	 * @see com.foxinmy.weixin4j.mp.model.Tag
81  	 * @see <a
82  	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">更新标签</a>
83  	 */
84  	public ApiResult updateTag(Tag tag) throws WeixinException {
85  		String tag_update_uri = getRequestUri("tag_update_uri");
86  		JSONObject obj = new JSONObject();
87  		obj.put("tag", tag);
88  		WeixinResponse response = weixinExecutor.post(
89  				String.format(tag_update_uri, tokenManager.getAccessToken()),
90  				obj.toJSONString());
91  		return response.getAsResult();
92  	}
93  
94  	/**
95  	 * 删除标签
96  	 * 
97  	 * @param tagId
98  	 *            标签id
99  	 * @return 操作结果
100 	 * @throws WeixinException
101 	 * @see <a
102 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">删除标签</a>
103 	 */
104 	public ApiResult deleteTag(int tagId) throws WeixinException {
105 		String tag_delete_uri = getRequestUri("tag_delete_uri");
106 		WeixinResponse response = weixinExecutor.post(
107 				String.format(tag_delete_uri, tokenManager.getAccessToken()),
108 				String.format("{\"tag\":{\"id\":%d}}", tagId));
109 		return response.getAsResult();
110 	}
111 
112 	/**
113 	 * 批量为用户打标签:标签功能目前支持公众号为用户打上最多三个标签
114 	 * 
115 	 * @param tagId
116 	 *            标签ID
117 	 * @param openIds
118 	 *            用户ID
119 	 * @return 操作结果
120 	 * @throws WeixinException
121 	 * @see <a
122 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">批量为用户打标签</a>
123 	 */
124 	public ApiResult taggingUsers(int tagId, String... openIds)
125 			throws WeixinException {
126 		return batchUsers("tag_tagging_uri", tagId, openIds);
127 	}
128 
129 	private ApiResult batchUsers(String batchType, int tagId, String... openIds)
130 			throws WeixinException {
131 		String tag_batch_uri = getRequestUri(batchType);
132 		JSONObject obj = new JSONObject();
133 		obj.put("openid_list", openIds);
134 		obj.put("tagid", tagId);
135 		WeixinResponse response = weixinExecutor.post(
136 				String.format(tag_batch_uri, tokenManager.getAccessToken()),
137 				obj.toJSONString());
138 		return response.getAsResult();
139 	}
140 
141 	/**
142 	 * 批量为用户取消标签
143 	 * 
144 	 * @param tagId
145 	 *            标签ID
146 	 * @param openIds
147 	 *            用户ID
148 	 * @return 操作结果
149 	 * @throws WeixinException
150 	 * @see <a
151 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">批量为用户取消标签</a>
152 	 */
153 	public ApiResult untaggingUsers(int tagId, String... openIds)
154 			throws WeixinException {
155 		return batchUsers("tag_untagging_uri", tagId, openIds);
156 	}
157 
158 	/**
159 	 * 获取标签下粉丝列表
160 	 * 
161 	 * @param tagId
162 	 *            标签ID
163 	 * @param nextOpenId
164 	 *            第一个拉取的OPENID,不填默认从头开始拉取
165 	 * @return 用户openid列表
166 	 * @throws WeixinException
167 	 * @see <a
168 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">获取标签下粉丝列表</a>
169 	 */
170 	public Following getTagFollowingOpenIds(int tagId, String nextOpenId)
171 			throws WeixinException {
172 		String tag_user_uri = getRequestUri("tag_user_uri");
173 		JSONObject obj = new JSONObject();
174 		obj.put("tagid", tagId);
175 		obj.put("next_openid", nextOpenId);
176 		WeixinResponse response = weixinExecutor.post(
177 				String.format(tag_user_uri, tokenManager.getAccessToken()),
178 				obj.toJSONString());
179 
180 		JSONObject result = response.getAsJson();
181 		Following following = JSON.toJavaObject(result, Following.class);
182 
183 		if (following.getCount() > 0) {
184 			following.setOpenIds(JSON.parseArray(result.getJSONObject("data")
185 					.getString("openid"), String.class));
186 		}
187 		return following;
188 	}
189 
190 	/**
191 	 * 获取标签下粉丝列表 <font corlor="red">请慎重使用</font>
192 	 * 
193 	 * @param tagId
194 	 *            标签ID
195 	 * @param nextOpenId
196 	 *            第一个拉取的OPENID,不填默认从头开始拉取
197 	 * @return 被打标签者信息 <font color="red">包含用户的详细信息</font>
198 	 * @throws WeixinException
199 	 * @see <a
200 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">获取标签下粉丝列表</a>
201 	 */
202 	public Following getTagFollowing(int tagId, String nextOpenId)
203 			throws WeixinException {
204 		Following following = getTagFollowingOpenIds(tagId, nextOpenId);
205 		if (following.getCount() > 0) {
206 			List<User> users = new ArrayList<User>(following.getCount());
207 			for (int i = 1; i <= (int) Math.ceil(following.getCount() / 100d); i++) {
208 				users.addAll(userApi.getUsers(following
209 						.getOpenIds()
210 						.subList((i - 1) * 100,
211 								Math.min(i * 100, following.getCount()))
212 						.toArray(new String[] {})));
213 			}
214 			following.setUserList(users);
215 		}
216 		return following;
217 	}
218 
219 	/**
220 	 * 获取标签下全部的粉丝列表 <font corlor="red">请慎重使用</font>
221 	 * 
222 	 * @param tagId
223 	 *            标签ID
224 	 * @return 用户openid列表
225 	 * @throws WeixinException
226 	 * @see #getTagFollowingOpenIds(int,String)
227 	 * @see <a
228 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">获取标签下粉丝列表</a>
229 	 */
230 	public List<String> getAllTagFollowingOpenIds(int tagId)
231 			throws WeixinException {
232 		List<String> openIds = new ArrayList<String>();
233 		String nextOpenId = null;
234 		Following f = null;
235 		for (;;) {
236 			f = getTagFollowingOpenIds(tagId, nextOpenId);
237 			if (f.hasContent()) {
238 				openIds.addAll(f.getOpenIds());
239 				nextOpenId = f.getNextOpenId();
240 				continue;
241 			}
242 			break;
243 		}
244 		return openIds;
245 	}
246 
247 	/**
248 	 * 获取标签下全部的粉丝列表 <font corlor="red">请慎重使用</font>
249 	 * 
250 	 * @param tagId
251 	 *            标签ID
252 	 * @return 被打标签者信息 <font color="red">包含用户的详细信息</font>
253 	 * @throws WeixinException
254 	 * @see #getTagFollowing(int,String)
255 	 * @see <a
256 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">获取标签下粉丝列表</a>
257 	 */
258 	public List<User> getAllTagFollowing(int tagId) throws WeixinException {
259 		List<User> userList = new ArrayList<User>();
260 		String nextOpenId = null;
261 		Following f = null;
262 		for (;;) {
263 			f = getTagFollowing(tagId, nextOpenId);
264 			if (f.hasContent()) {
265 				userList.addAll(f.getUserList());
266 				nextOpenId = f.getNextOpenId();
267 				continue;
268 			}
269 			break;
270 		}
271 		return userList;
272 	}
273 
274 	/**
275 	 * 获取用户身上的标签列表
276 	 * 
277 	 * @param openId
278 	 *            用户ID
279 	 * @return 标签ID集合
280 	 * @throws WeixinException
281 	 * @see <a
282 	 *      href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">
283 	 *      获取用户身上的标签列表</a>
284 	 */
285 	public Integer[] getUserTags(String openId) throws WeixinException {
286 		String tag_userids_uri = getRequestUri("tag_userids_uri");
287 		WeixinResponse response = weixinExecutor.post(
288 				String.format(tag_userids_uri, tokenManager.getAccessToken()),
289 				String.format("{\"openid\":\"%s\"}", openId));
290 		return response.getAsJson().getJSONArray("tagid_list")
291 				.toArray(new Integer[] {});
292 	}
293 
294 	/**
295 	 * 获取公众号的黑名单列表
296 	 * 
297 	 * @param nextOpenId
298 	 *            下一次拉取数据的openid 不填写则默认从头开始拉取
299 	 * @return 拉黑用户列表 <font color="red">不包含用户的详细信息</font>
300 	 * @see <a href=
301 	 *      "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN"
302 	 *      >获取黑名单列表</a>
303 	 * @see com.foxinmy.weixin4j.mp.model.Following
304 	 * @throws WeixinException
305 	 */
306 	public Following getBalcklistOpenIds(String nextOpenId)
307 			throws WeixinException {
308 		JSONObject obj = new JSONObject();
309 		obj.put("begin_openid", nextOpenId == null ? "" : nextOpenId);
310 		String getblacklist_uri = getRequestUri("getblacklist_uri");
311 		Token token = tokenManager.getCache();
312 		WeixinResponse response = weixinExecutor.post(String.format(
313 				getblacklist_uri, token.getAccessToken(), obj.toJSONString()));
314 		JSONObject result = response.getAsJson();
315 		Following following = JSON.toJavaObject(result, Following.class);
316 		if (following.getCount() > 0) {
317 			following.setOpenIds(JSON.parseArray(result.getJSONObject("data")
318 					.getString("openid"), String.class));
319 		}
320 		return following;
321 	}
322 
323 	/**
324 	 * 获取公众号全部的黑名单列表 <font corlor="red">请慎重使用</font>
325 	 * <p>
326 	 * 当公众号关注者数量超过10000时,可通过填写next_openid的值,从而多次拉取列表的方式来满足需求,
327 	 * 将上一次调用得到的返回中的next_openid值,作为下一次调用中的next_openid值
328 	 * </p>
329 	 * 
330 	 * @return 用户openid集合
331 	 * @throws WeixinException
332 	 * @see <a href=
333 	 *      "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN">
334 	 *      获取黑名单列表</a>
335 	 * @see #getFollowingOpenIds(String)
336 	 */
337 	public List<String> getAllBalcklistOpenIds() throws WeixinException {
338 		List<String> openIds = new ArrayList<String>();
339 		String nextOpenId = null;
340 		Following f = null;
341 		for (;;) {
342 			f = getBalcklistOpenIds(nextOpenId);
343 			if (f.hasContent()) {
344 				openIds.addAll(f.getOpenIds());
345 				nextOpenId = f.getNextOpenId();
346 				continue;
347 			}
348 			break;
349 		}
350 		return openIds;
351 	}
352 
353 	/**
354 	 * 黑名单操作
355 	 * 
356 	 * @param blacklist
357 	 *            true=拉黑用户,false=取消拉黑用户
358 	 * @param openIds
359 	 *            用户ID列表
360 	 * @return 操作结果
361 	 * @see <a
362 	 *      href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN">黑名单操作</a>
363 	 * @throws WeixinException
364 	 */
365 	public ApiResult batchBlacklist(boolean blacklist, String... openIds)
366 			throws WeixinException {
367 		JSONObject obj = new JSONObject();
368 		obj.put("openid_list", openIds);
369 		String blacklist_url = blacklist ? getRequestUri("batchblacklist_uri")
370 				: getRequestUri("batchunblacklist_uri");
371 		WeixinResponse response = weixinExecutor.post(
372 				String.format(blacklist_url, tokenManager.getAccessToken()),
373 				obj.toJSONString());
374 		return response.getAsResult();
375 	}
376 }