ВКонтакте - пример интеграции
Материал из BiTel WiKi
Dog (Обсуждение | вклад) |
Dog (Обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
Функциональность: | Функциональность: | ||
- | Получение новых(не прочитанных сообщений из паблика VK). | + | * Получение новых(не прочитанных сообщений из паблика VK). |
- | Отображение полученных сообщений в BGCRM -> Сообщения. | + | * Отображение полученных сообщений в BGCRM -> Сообщения. |
- | Оповещение о новых сообщениях в счётчике новых не прочитанных сообщений BGCRM. | + | * Оповещение о новых сообщениях в счётчике новых не прочитанных сообщений 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> >