ВКонтакте - пример интеграции

Материал из BiTel WiKi

(Различия между версиями)
Перейти к: навигация, поиск
Строка 1: Строка 1:
Функциональность:
Функциональность:
-
Получение новых(не прочитанных сообщений из паблика VK).</br>
+
* Получение новых(не прочитанных сообщений из паблика VK).
-
Отображение полученных сообщений в BGCRM -> Сообщения.</br>
+
* Отображение полученных сообщений в BGCRM -> Сообщения.
-
Оповещение о новых сообщениях в счётчике новых не прочитанных сообщений BGCRM.</br>
+
* Оповещение о новых сообщениях в счётчике новых не прочитанных сообщений BGCRM.
 +
 
 +
дальнейшая обработка сообщений в BGCRM не реализована и заблокирована. Общение происходит в паблике ВК
 +
 
реализация API. Для того чтобы работало в конфигурацию надо добавить:
реализация API. Для того чтобы работало в конфигурацию надо добавить:
Строка 335: Строка 338:
#scheduler.task.4.hours=
#scheduler.task.4.hours=
scheduler.task.4.minutes=10,20,30,40,50,60
scheduler.task.4.minutes=10,20,30,40,50,60
 +
</source>
 +
 +
для того чтобы заблокировать открытие сообщения для дальнейшей обработке в Сообщениях:
 +
 +
<source lang="bash">
 +
# diff /srv/BGCRM/webapps/WEB-INF/jspf/user/message/list.jsp /srv/BGCRM/webapps/WEB-INF/jspf/user/message/list.jsp.orig
 +
190d189
 +
<
 +
193,205c192,197
 +
<                              <c:set var="typeId" value="${item.typeId}"/>
 +
<                              <c:choose>
 +
<                                      <c:when test="${typeId eq 200}">
 +
<
 +
<                                      </c:when>
 +
<                                        <c:otherwise>
 +
<                                              <c:url var="url" value="message.do">
 +
<                                                      <c:param name="typeId" value="${item.typeId}"/>
 +
<                                                      <c:param name="messageId" value="${item.systemId}"/>
 +
<                                                      <c:param name="returnUrl" value="${form.requestUrl}"/>
 +
<                                              </c:url>
 +
<                                      </c:otherwise>
 +
<                              </c:choose>
 +
---
 +
>                              <c:url var="url" value="message.do">
 +
>                                      <c:param name="typeId" value="${item.typeId}"/>
 +
>                                      <c:param name="messageId" value="${item.systemId}"/>
 +
>                                      <c:param name="returnUrl" value="${form.requestUrl}"/>
 +
>                              </c:url>
 +
>
</source>
</source>

Версия 11:12, 10 февраля 2017

Функциональность:

  • Получение новых(не прочитанных сообщений из паблика VK).
  • Отображение полученных сообщений в BGCRM -> Сообщения.
  • Оповещение о новых сообщениях в счётчике новых не прочитанных сообщений BGCRM.

дальнейшая обработка сообщений в BGCRM не реализована и заблокирована. Общение происходит в паблике ВК


реализация API. Для того чтобы работало в конфигурацию надо добавить:

  • vk.access.token - токен авторизации для приложения. брать в настройках паблика.
  • vk.v - версия API. на момент реализации была 5.60
  • vk.pname - отображаемое имя паблика.
package ru.bgcrm.dyn.vk;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
 
import ru.bgcrm.model.message.Message;
import ru.bgcrm.util.Setup;
 
/**
 * @author Сергей
 *
 */
public class VkAPI {
 
	/**
	 * Ключ к API
	 */
	private String VK_ACCESS_TOKEN;
	/**
	 * 
	 */
	private String VK_API_BASE_URI = "https://api.vk.com/method/";
	/**
	 * Версия VK API с которой работаем
	 */
	private String VK_V;
	/**
	 * Отображаемое имя паблика
	 */
	private String VK_PUBLIC_NAME;
 
	public VkAPI(){
		VK_ACCESS_TOKEN = Setup.getSetup().get("vk.access.token", "");
		VK_V = Setup.getSetup().get("vk.v", "5.60");
		VK_PUBLIC_NAME = Setup.getSetup().get("vk.pname", "ООО \"Рога и копыта\"");
	}
 
	/**
	 * Получение диалогов
	 * 
	 * @param unanswered 0 - все; 1 - только не отвеченные сообщения;
	 * @param important 0 - все; 1 - только важные;
	 * @param unread 0 - все; 1 - только не прочитанные; 
	 * @return 
	 */
	public List<VkDialog> getDialogs(Integer unanswered, Integer important, Integer unread){
		List<VkDialog> result = new ArrayList<VkDialog>();
		String method = "messages.getDialogs";
		String body = "";
		body = "unanswered=" + unanswered + "&important" + important + "&unread=" + unread;
		try {
			String response = sendRequest(method, body);
			JSONObject jsonResponse = new JSONObject(response);
			JSONArray jsonArrayDialogs = jsonResponse.getJSONObject("response").getJSONArray("items");
			if (jsonArrayDialogs.length() > 0){
				for(int i=0; i<jsonArrayDialogs.length(); i++){
					VkDialog vkDialog = new VkDialog(jsonArrayDialogs.getJSONObject(i).getJSONObject("message").getInt("user_id"), 
							jsonArrayDialogs.getJSONObject(i).getInt("in_read"),
							jsonArrayDialogs.getJSONObject(i).getInt("out_read"),
							jsonArrayDialogs.getJSONObject(i).getJSONObject("message"));
					result.add(vkDialog);
				}
			}
		} catch (ParseException | IOException e) {
			e.printStackTrace();
		}
		return result;
	}
 
	/**
	 * Конвертируем лист сообщений VK в лист сообщений CRM
	 * 
	 * @param vkMessageList
	 * @return
	 */
	public List<Message> toMessageList(List<VkMessage> vkMessageList){
		List<Message> result = new ArrayList<Message>();
		for (VkMessage vkMessage : vkMessageList){
			Message message = new Message();
			message.setDirection(Message.DIRECTION_INCOMING);
			message.setFrom(String.valueOf(vkMessage.fromId));
			message.setFromTime(new Date((long)vkMessage.date*1000));
			message.setText(vkMessage.body);
			message.setSubject(vkMessage.body);
			message.setTo(VK_PUBLIC_NAME);
			message.setTypeId(200);
			message.setProcessed(false);
			message.setSystemId(String.valueOf(vkMessage.fromId));
			result.add(message);
		}
		return result;
	}
 
	/**
	 * Отсылаем запрос. Возвращаем JSON
	 * 
	 * @param method
	 * @param body
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	private String sendRequest(String method, String body) throws ParseException, IOException{
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
		body = body + "&access_token=" + VK_ACCESS_TOKEN + "&v=" + VK_V;
 
		HttpPost request = new HttpPost(VK_API_BASE_URI + method + "?" + body);
        request.addHeader("content-type", "application/json");
 
        HttpResponse result = httpClient.execute(request);
        String jsonString = EntityUtils.toString(result.getEntity(), "UTF-8");
 
        System.out.println(jsonString);
        httpClient.close();
 
        return jsonString;		
	}
 
}

класс сообщения VK

package ru.bgcrm.dyn.vk;
 
public class VkMessage {
 
	public int id;
	public int userId;
	public int fromId;
	public int date;
	public int readState;
	public int out;
	public String body;
 
	public VkMessage(int id, int user_id, int from_id, int date, int read_state, int out, String body) {
		this.id = id;
		this.userId = user_id;
		this.fromId = from_id;
		this.date = date;
		this.readState = read_state;
		this.out = out;
		this.body = body;
	}
 
}

класс MessageTypeVK:

package ru.bgcrm.dyn.vk;
 
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
 
import org.apache.log4j.Logger;
 
import ru.bgcrm.dao.message.MessageType;
import ru.bgcrm.model.BGException;
import ru.bgcrm.model.message.Message;
import ru.bgcrm.struts.form.DynActionForm;
import ru.bgcrm.util.ParameterMap;
import ru.bgcrm.util.sql.ConnectionSet;
 
public class MessageTypeVK extends MessageType {
 
	private static final Logger log = Logger.getLogger(MessageTypeVK.class);
 
	public MessageTypeVK(int id, ParameterMap config) throws BGException {
		super(id, config.get("title"), config);
	}
 
	protected MessageTypeVK(int id, String title, ParameterMap config)	throws BGException {
		super(id, config.get("title"), config);
	}
 
 
	@Override
	public void updateMessage(Connection con, DynActionForm form,
			Message message) throws BGException {
	}
 
	/* (non-Javadoc)
	 * @see ru.bgcrm.dao.message.MessageType#newMessageList(ru.bgcrm.util.sql.ConnectionSet)
	 * 
	 * Получаем последние сообщения из неотвеченных диалогов в ВК
	 */
	public List<ru.bgcrm.model.message.Message> newMessageList(ConnectionSet conSet) throws BGException {
		log.info((new StringBuilder("Fetching new message list.")));
 
		VkAPI VkApi = new VkAPI();
 
		List<VkMessage> vkMessageList = getNewMessageList(VkApi);
 
		return VkApi.toMessageList(vkMessageList);
	}
 
	/* (non-Javadoc)
	 * @see ru.bgcrm.dao.message.MessageType#getProcessMessageHeaderColor(ru.bgcrm.model.message.Message)
	 * 
	 * настройка цвета сообщения
	 */
	public String getProcessMessageHeaderColor(Message message) {
		return "#e6fb9d";
	}
 
	/**
         * получаем список неотвеченных сообщений
	 * @param VkAPI
	 * @return
	 */
	private List<VkMessage> getNewMessageList(VkAPI VkApi) {
		List<VkMessage> vkMessageList = new ArrayList<VkMessage>();
		List<VkDialog> vkDialogList = VkApi.getDialogs(1, 0, 0);
 
		log.info(vkDialogList.size() + " unanswered dialogs found.");
 
		for (VkDialog vkDialog : vkDialogList){
			log.info("vkUserId : " + vkDialog.userId);
			vkMessageList.add(vkDialog.lastMessage);
		}
 
		this.unprocessedMessagesCount = Integer.valueOf(vkMessageList.size());
 
		return vkMessageList;
	}
 
	/* (non-Javadoc)
	 * @see ru.bgcrm.dao.message.MessageType#process()
	 * 
	 * Метод обработки сообщений по шедулеру
	 */
	public void process(){
		log.info((new StringBuilder("Starting VK daemon, public name: ")));
		readPublicMessages();
		sendPublicMessages();
	}
 
	/**
	 * Метод чтения сообщений из паблика
	 */
	private void readPublicMessages() {
		log.info((new StringBuilder("Fetching new message list.")));
 
		VkAPI VkApi = new VkAPI();
 
		getNewMessageList(VkApi);
	}
 
	/**
	 * Метод отправки сообщений в паблик
	 */
	private void sendPublicMessages() {
		log.info((new StringBuilder("Public messages sended.")));
	}
 
	/* (non-Javadoc)
	 * @see ru.bgcrm.dao.message.MessageType#isEditable(ru.bgcrm.model.message.Message)
	 * 
	 * Поддерживает ли изменение
	 */
	public boolean isEditable(Message message) {
		return false;
	}
 
	/* (non-Javadoc)
	 * @see ru.bgcrm.dao.message.MessageType#isRemovable(ru.bgcrm.model.message.Message)
	 * 
	 * Поддерживает ли удаление
	 */
	public boolean isRemovable(Message message) {
		return false;
	}
 
	/* (non-Javadoc)
	 * @see ru.bgcrm.dao.message.MessageType#isProcessChangeSupport()
	 * 
	 * Можно ли сменить процесс
	 */
	public boolean isProcessChangeSupport() {
		return false;
	}
 
	/* (non-Javadoc)
	 * @see ru.bgcrm.dao.message.MessageType#isAnswerSupport()
	 * 
	 * ??? Можно ли отвечать ???
	 */
	public boolean isAnswerSupport(){
	    return false;
	}
 
}

в конфигурации BGCRM создаем новый тип сообщений:

Указан неподдерживаемый язык.

Вы должны указать язык следующим образом: <source lang="html">...</source>

Поддерживаемые языки:

abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80

добавляем этот тип сообщений в планировщике, для периодического приёма:

Указан неподдерживаемый язык.

Вы должны указать язык следующим образом: <source lang="html">...</source>

Поддерживаемые языки:

abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80

для того чтобы заблокировать открытие сообщения для дальнейшей обработке в Сообщениях:

# diff /srv/BGCRM/webapps/WEB-INF/jspf/user/message/list.jsp /srv/BGCRM/webapps/WEB-INF/jspf/user/message/list.jsp.orig
190d189
<
193,205c192,197
<                               <c:set var="typeId" value="${item.typeId}"/>
<                               <c:choose>
<                                       <c:when test="${typeId eq 200}">
<
<                                       </c:when>
<                                        <c:otherwise>
<                                               <c:url var="url" value="message.do">
<                                                       <c:param name="typeId" value="${item.typeId}"/>
<                                                       <c:param name="messageId" value="${item.systemId}"/>
<                                                       <c:param name="returnUrl" value="${form.requestUrl}"/>
<                                               </c:url>
<                                       </c:otherwise>
<                               </c:choose>
---
>                               <c:url var="url" value="message.do">
>                                       <c:param name="typeId" value="${item.typeId}"/>
>                                       <c:param name="messageId" value="${item.systemId}"/>
>                                       <c:param name="returnUrl" value="${form.requestUrl}"/>
>                               </c:url>
>
Личные инструменты