summaryrefslogtreecommitdiff
path: root/protocols/Slack/src
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2017-03-16 00:08:16 +0300
committeraunsane <aunsane@gmail.com>2017-03-16 00:09:55 +0300
commitc84b27ebb4eaa5327c601f0b504249bf061ef3b5 (patch)
tree40bd78d7f39eb29edafe0911b0f3ed58510ae009 /protocols/Slack/src
parent131573060e8ddc945c671ed312b9480ce59d2e9f (diff)
Slack: added im message send
Diffstat (limited to 'protocols/Slack/src')
-rw-r--r--protocols/Slack/src/api/api_chat.h34
-rw-r--r--protocols/Slack/src/api/api_im.h18
-rw-r--r--protocols/Slack/src/slack_accounts.cpp4
-rw-r--r--protocols/Slack/src/slack_connection.cpp9
-rw-r--r--protocols/Slack/src/slack_contacts.cpp2
-rw-r--r--protocols/Slack/src/slack_messages.cpp79
-rw-r--r--protocols/Slack/src/slack_options.cpp23
-rw-r--r--protocols/Slack/src/slack_options.h14
-rw-r--r--protocols/Slack/src/slack_proto.cpp25
-rw-r--r--protocols/Slack/src/slack_proto.h31
-rw-r--r--protocols/Slack/src/slack_requests.cpp18
-rw-r--r--protocols/Slack/src/slack_utils.cpp5
-rw-r--r--protocols/Slack/src/stdafx.h2
13 files changed, 194 insertions, 70 deletions
diff --git a/protocols/Slack/src/api/api_chat.h b/protocols/Slack/src/api/api_chat.h
new file mode 100644
index 0000000000..434b612943
--- /dev/null
+++ b/protocols/Slack/src/api/api_chat.h
@@ -0,0 +1,34 @@
+#ifndef _SLACK_API_CHAT_H_
+#define _SLACK_API_CHAT_H_
+
+class SendMessageRequest : public HttpRequest
+{
+public:
+ SendMessageRequest(const char *token, const char *channel, const char *message) :
+ HttpRequest(HttpMethod::HttpPost, SLACK_API_URL "/chat.postMessage")
+ {
+ Headers
+ << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
+ Content
+ << CHAR_VALUE("token", token)
+ << CHAR_VALUE("channel", channel)
+ << CHAR_VALUE("text", message);
+ }
+};
+
+class SendActionRequest : public HttpRequest
+{
+public:
+ SendActionRequest(const char *token, const char *channel, const char *message) :
+ HttpRequest(HttpMethod::HttpPost, SLACK_API_URL "/chat.meMessage")
+ {
+ Headers
+ << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
+ Content
+ << CHAR_VALUE("token", token)
+ << CHAR_VALUE("channel", channel)
+ << CHAR_VALUE("text", message);
+ }
+};
+
+#endif //_SLACK_API_CHAT_H_ \ No newline at end of file
diff --git a/protocols/Slack/src/api/api_im.h b/protocols/Slack/src/api/api_im.h
new file mode 100644
index 0000000000..ae4076a788
--- /dev/null
+++ b/protocols/Slack/src/api/api_im.h
@@ -0,0 +1,18 @@
+#ifndef _SLACK_API_IM_H_
+#define _SLACK_API_IM_H_
+
+class OpenImChannelRequest : public HttpRequest
+{
+public:
+ OpenImChannelRequest(const char *token, const char *user) :
+ HttpRequest(HttpMethod::HttpPost, SLACK_API_URL "/im.open")
+ {
+ Headers
+ << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
+ Content
+ << CHAR_VALUE("token", token)
+ << CHAR_VALUE("user", user);
+ }
+};
+
+#endif //_SLACK_API_IM_H_ \ No newline at end of file
diff --git a/protocols/Slack/src/slack_accounts.cpp b/protocols/Slack/src/slack_accounts.cpp
index 1887c9fc95..50640ae37a 100644
--- a/protocols/Slack/src/slack_accounts.cpp
+++ b/protocols/Slack/src/slack_accounts.cpp
@@ -37,7 +37,7 @@ int CSlackProto::OnAccountLoaded(WPARAM, LPARAM)
return 0;
}
-INT_PTR CSlackProto::OnAccountManagerInit(WPARAM, LPARAM lParam)
+INT_PTR CSlackProto::OnAccountManagerInit(WPARAM, LPARAM)
{
- return (INT_PTR)(CSlackOptionsMain::CreateAccountManagerPage(this, (HWND)lParam))->GetHwnd();
+ return NULL;// (INT_PTR)(CSlackOptionsMain::CreateAccountManagerPage(this, (HWND)lParam))->GetHwnd();
} \ No newline at end of file
diff --git a/protocols/Slack/src/slack_connection.cpp b/protocols/Slack/src/slack_connection.cpp
index b8b0652618..0cbb73992a 100644
--- a/protocols/Slack/src/slack_connection.cpp
+++ b/protocols/Slack/src/slack_connection.cpp
@@ -1,5 +1,10 @@
#include "stdafx.h"
+bool CSlackProto::IsOnline()
+{
+ return !isTerminated && m_iStatus > ID_STATUS_OFFLINE;
+}
+
void CSlackProto::Login()
{
ptrA token(getStringA("TokenSecret"));
@@ -29,7 +34,7 @@ void CSlackProto::Login()
PushRequest(request, &CSlackProto::OnAuthorize);
}
-void CSlackProto::OnAuthorize(JSONNode &root)
+void CSlackProto::OnAuthorize(JSONNode &root, void*)
{
if (!root)
{
@@ -56,7 +61,7 @@ void CSlackProto::OnAuthorize(JSONNode &root)
CMStringW teamName = root["team_name"].as_mstring();
setWString("TeamName", teamName);
- if (!teamName.IsEmpty() > 0 && !Clist_GroupExists(teamName))
+ if (!teamName.IsEmpty() && !Clist_GroupExists(teamName))
Clist_GroupCreate(0, teamName);
json_string teamId = root["team_id"].as_string();
diff --git a/protocols/Slack/src/slack_contacts.cpp b/protocols/Slack/src/slack_contacts.cpp
index 185d5110b8..5054e6003c 100644
--- a/protocols/Slack/src/slack_contacts.cpp
+++ b/protocols/Slack/src/slack_contacts.cpp
@@ -94,7 +94,7 @@ void CSlackProto::OnGotUserProfile(MCONTACT hContact, JSONNode &root)
setWString(hContact, "LastName", lastName);
}
-void CSlackProto::OnGotUserList(JSONNode &root)
+void CSlackProto::OnGotUserList(JSONNode &root, void*)
{
if (!root)
{
diff --git a/protocols/Slack/src/slack_messages.cpp b/protocols/Slack/src/slack_messages.cpp
index f78ba3e9db..012e9451de 100644
--- a/protocols/Slack/src/slack_messages.cpp
+++ b/protocols/Slack/src/slack_messages.cpp
@@ -26,9 +26,84 @@ int CSlackProto::OnReceiveMessage(MCONTACT hContact, PROTORECVEVENT *pre)
/* MESSAGE SENDING */
// outcoming message flow
-int CSlackProto::OnSendMessage(MCONTACT hContact, int flags, const char *szMessage)
+void CSlackProto::OnMessageSent(JSONNode &root, void *arg)
{
- return 0;
+ SendMessageParam *param = (SendMessageParam*)arg;
+
+ if (!root)
+ {
+ ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)param->hMessage, (LPARAM)Translate("Unable to send message."));
+ return;
+ }
+
+ bool isOk = root["ok"].as_bool();
+ if (!isOk)
+ {
+ json_string error = root["error"].as_string();
+ debugLogA(__FUNCTION__": %s", error);
+ ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)param->hMessage, (LPARAM)error.c_str());
+ return;
+ }
+
+ ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)param->hMessage, 0);
+}
+
+void CSlackProto::OnImChannelOppened(JSONNode &root, void *arg)
+{
+ SendMessageParam *param = (SendMessageParam*)arg;
+
+ if (!root)
+ {
+ ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)param->hMessage, (LPARAM)Translate("Unable to open im channel."));
+ mir_free(param->message);
+ mir_free(param);
+ return;
+ }
+
+ bool isOk = root["ok"].as_bool();
+ if (!isOk)
+ {
+ json_string error = root["error"].as_string();
+ debugLogA(__FUNCTION__": %s", error);
+ ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)param->hMessage, (LPARAM)error.c_str());
+ mir_free(param->message);
+ mir_free(param);
+ return;
+ }
+
+ JSONNode channel = root["channel"].as_node();
+ json_string channelId = channel["id"].as_string();
+
+ ptrA token(getStringA("TokenSecret"));
+
+ char *message = param->message;
+ HttpRequest *request;
+ if (mir_strncmpi(message, "/me ", 4) == 0)
+ {
+ message += 4;
+ request = new SendActionRequest(token, channelId.c_str(), message);
+ }
+ else
+ request = new SendMessageRequest(token, channelId.c_str(), message);
+
+ SendRequest(request, &CSlackProto::OnMessageSent, param);
+}
+
+void CSlackProto::SendMessageThread(void *arg)
+{
+ Thread_SetName("SLACK: SendMessageThread");
+
+ SendMessageParam *param = (SendMessageParam*)arg;
+
+ ptrA token(getStringA("TokenSecret"));
+ ptrA user(getStringA(param->hContact, "UserId"));
+ SendRequest(new OpenImChannelRequest(token, user), &CSlackProto::OnImChannelOppened, param);
+}
+
+void CSlackProto::SendMessageAckThread(void *arg)
+{
+ Sleep(100);
+ ProtoBroadcastAck((MCONTACT)arg, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)1, (LPARAM)Translate("You cannot send when you are offline"));
}
// message is received by the other side
diff --git a/protocols/Slack/src/slack_options.cpp b/protocols/Slack/src/slack_options.cpp
index 49544935c1..c057017bf4 100644
--- a/protocols/Slack/src/slack_options.cpp
+++ b/protocols/Slack/src/slack_options.cpp
@@ -1,25 +1,13 @@
#include "stdafx.h"
CSlackOptionsMain::CSlackOptionsMain(CSlackProto *proto, int idDialog)
- : CSuper(proto, idDialog, false),
- m_team(this, IDC_TEAM), m_email(this, IDC_EMAIL),
- m_password(this, IDC_PASSWORD), m_group(this, IDC_GROUP)
+ : CSuper(proto, idDialog, false)
{
-
- CreateLink(m_team, "Team", L"");
- CreateLink(m_email, "Email", L"");
- CreateLink(m_password, "Password", L"");
- CreateLink(m_group, "DefaultGroup", _A2W(MODULE));
}
void CSlackOptionsMain::OnInitDialog()
{
CSuper::OnInitDialog();
-
- SendMessage(m_team.GetHwnd(), EM_LIMITTEXT, 21, 0);
- SendMessage(m_email.GetHwnd(), EM_LIMITTEXT, 40, 0);
- SendMessage(m_password.GetHwnd(), EM_LIMITTEXT, 40, 0);
- SendMessage(m_group.GetHwnd(), EM_LIMITTEXT, 64, 0);
}
void CSlackOptionsMain::OnApply()
@@ -30,14 +18,5 @@ void CSlackOptionsMain::OnApply()
int CSlackProto::OnOptionsInit(WPARAM wParam, LPARAM)
{
- OPTIONSDIALOGPAGE odp = { 0 };
- odp.szTitle.w = m_tszUserName;
- odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE | ODPF_DONTTRANSLATE;
- odp.szGroup.w = LPGENW("Network");
-
- odp.szTab.w = LPGENW("Account");
- odp.pDialog = CSlackOptionsMain::CreateOptionsPage(this);
- //Options_AddPage(wParam, &odp);
-
return 0;
}
diff --git a/protocols/Slack/src/slack_options.h b/protocols/Slack/src/slack_options.h
index e0eeda70a3..5d0356f8b7 100644
--- a/protocols/Slack/src/slack_options.h
+++ b/protocols/Slack/src/slack_options.h
@@ -6,10 +6,6 @@ class CSlackOptionsMain : public CProtoDlgBase<CSlackProto>
typedef CProtoDlgBase<CSlackProto> CSuper;
private:
- CCtrlEdit m_team;
- CCtrlEdit m_email;
- CCtrlEdit m_password;
- CCtrlEdit m_group;
protected:
void OnInitDialog();
@@ -17,16 +13,6 @@ protected:
public:
CSlackOptionsMain(CSlackProto *proto, int idDialog);
-
- static CDlgBase *CreateAccountManagerPage(void *param, HWND owner)
- {
- CSlackOptionsMain *page = new CSlackOptionsMain((CSlackProto*)param, IDD_ACCOUNT_MANAGER);
- page->SetParent(owner);
- page->Show();
- return page;
- }
-
- static CDlgBase *CreateOptionsPage(void *param) { return new CSlackOptionsMain((CSlackProto*)param, IDD_OPTIONS_MAIN); }
};
#endif //_SLACK_OPTIONS_H_
diff --git a/protocols/Slack/src/slack_proto.cpp b/protocols/Slack/src/slack_proto.cpp
index 8a37838c28..e3731794d4 100644
--- a/protocols/Slack/src/slack_proto.cpp
+++ b/protocols/Slack/src/slack_proto.cpp
@@ -1,7 +1,8 @@
#include "stdafx.h"
CSlackProto::CSlackProto(const char* protoName, const TCHAR* userName) :
- PROTO<CSlackProto>(protoName, userName), requestQueue(1)
+ PROTO<CSlackProto>(protoName, userName), requestQueue(1),
+ hMessageProcess(1)
{
InitNetlib();
@@ -20,11 +21,11 @@ DWORD_PTR CSlackProto::GetCaps(int type, MCONTACT)
switch (type)
{
case PFLAGNUM_1:
- return PF1_IM;
+ return PF1_IMSEND;
case PFLAGNUM_2:
- return PF2_ONLINE | PF2_LONGAWAY;
+ return PF2_ONLINE;
case PFLAGNUM_3:
- return PF2_ONLINE | PF2_LONGAWAY;
+ return PF2_ONLINE;
case PFLAG_UNIQUEIDTEXT:
return (INT_PTR)"User Id";
case PFLAG_UNIQUEIDSETTING:
@@ -57,7 +58,21 @@ int CSlackProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre)
int CSlackProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
{
- return OnSendMessage(hContact, flags, msg);
+ if (!IsOnline())
+ {
+ ForkThread(&CSlackProto::SendMessageAckThread, (void*)hContact);
+ return 1;
+ }
+
+ UINT hMessage = InterlockedIncrement(&hMessageProcess);
+
+ SendMessageParam *param = (SendMessageParam*)mir_calloc(sizeof(SendMessageParam));
+ param->hContact = hContact;
+ param->hMessage = hMessage;
+ param->message = mir_strdup(msg);
+ ForkThread(&CSlackProto::SendMessageThread, param);
+
+ return hMessage;
}
int CSlackProto::SetStatus(int iNewStatus)
diff --git a/protocols/Slack/src/slack_proto.h b/protocols/Slack/src/slack_proto.h
index f47c70f946..25b667eea2 100644
--- a/protocols/Slack/src/slack_proto.h
+++ b/protocols/Slack/src/slack_proto.h
@@ -6,13 +6,21 @@ struct CSlackProto : public PROTO<CSlackProto>
friend class CSlackOptionsMain;
friend class CSlackOAuth;
- typedef void(CSlackProto::*HttpCallback)(HttpResponse&);
- typedef void(CSlackProto::*JsonCallback)(JSONNode&);
+ typedef void(CSlackProto::*HttpCallback)(HttpResponse&, void*);
+ typedef void(CSlackProto::*JsonCallback)(JSONNode&, void*);
struct RequestQueueItem
{
HttpRequest *request;
HttpCallback httpCallback;
JsonCallback jsonCallback;
+ void *param;
+ };
+
+ struct SendMessageParam
+ {
+ MCONTACT hContact;
+ UINT hMessage;
+ char *message;
};
public:
@@ -60,14 +68,15 @@ private:
HANDLE hRequestsQueueEvent;
HANDLE hRequestQueueThread;
LIST<RequestQueueItem> requestQueue;
+ ULONG hMessageProcess;
// requests
void SendRequest(HttpRequest *request);
- void SendRequest(HttpRequest *request, HttpCallback callback);
- void SendRequest(HttpRequest *request, JsonCallback callback);
+ void SendRequest(HttpRequest *request, HttpCallback callback, void *param = NULL);
+ void SendRequest(HttpRequest *request, JsonCallback callback, void *param = NULL);
void PushRequest(HttpRequest *request);
- void PushRequest(HttpRequest *request, HttpCallback callback);
- void PushRequest(HttpRequest *request, JsonCallback callback);
+ void PushRequest(HttpRequest *request, HttpCallback callback, void *param = NULL);
+ void PushRequest(HttpRequest *request, JsonCallback callback, void *param = NULL);
void __cdecl RequestQueueThread(void*);
// network
@@ -90,7 +99,7 @@ private:
// login
void Login();
void LogOut();
- void OnAuthorize(JSONNode &root);
+ void OnAuthorize(JSONNode &root, void*);
// icons
static IconItemT Icons[];
@@ -114,7 +123,7 @@ private:
void OnGotUserProfile(JSONNode &root);
void OnGotUserProfile(MCONTACT hContact, JSONNode &root);
- void OnGotUserList(JSONNode &root);
+ void OnGotUserList(JSONNode &root, void*);
INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM lParam);
INT_PTR __cdecl OnGrantAuth(WPARAM hContact, LPARAM);
@@ -123,7 +132,11 @@ private:
// messages
int OnReceiveMessage(MCONTACT hContact, PROTORECVEVENT *pre);
- int OnSendMessage(MCONTACT hContact, int flags, const char *message);
+
+ void OnMessageSent(JSONNode &root, void *arg);
+ void OnImChannelOppened(JSONNode &root, void *arg);
+ void __cdecl SendMessageThread(void*);
+ void __cdecl SendMessageAckThread(void*);
int OnUserIsTyping(MCONTACT hContact, int type);
diff --git a/protocols/Slack/src/slack_requests.cpp b/protocols/Slack/src/slack_requests.cpp
index 7fd0ef4805..ad99b198a3 100644
--- a/protocols/Slack/src/slack_requests.cpp
+++ b/protocols/Slack/src/slack_requests.cpp
@@ -7,23 +7,23 @@ void CSlackProto::SendRequest(HttpRequest *request)
delete request;
}
-void CSlackProto::SendRequest(HttpRequest *request, HttpCallback callback)
+void CSlackProto::SendRequest(HttpRequest *request, HttpCallback callback, void *param)
{
NETLIBHTTPREQUEST *pResp = Netlib_HttpTransaction(m_hNetlibUser, (NETLIBHTTPREQUEST*)request);
HttpResponse response(request, pResp);
if (callback)
- (this->*callback)(response);
+ (this->*callback)(response, param);
delete request;
}
-void CSlackProto::SendRequest(HttpRequest *request, JsonCallback callback)
+void CSlackProto::SendRequest(HttpRequest *request, JsonCallback callback, void *param)
{
NETLIBHTTPREQUEST *pResp = Netlib_HttpTransaction(m_hNetlibUser, (NETLIBHTTPREQUEST*)request);
HttpResponse response(request, pResp);
if (callback)
{
JSONNode root = JSONNode::parse(response.Content);
- (this->*callback)(root);
+ (this->*callback)(root, param);
}
delete request;
}
@@ -39,11 +39,12 @@ void CSlackProto::PushRequest(HttpRequest *request)
SetEvent(hRequestsQueueEvent);
}
-void CSlackProto::PushRequest(HttpRequest *request, HttpCallback callback)
+void CSlackProto::PushRequest(HttpRequest *request, HttpCallback callback, void *param)
{
RequestQueueItem *item = new RequestQueueItem();
item->request = request;
item->httpCallback = callback;
+ item->param = param;
{
mir_cslock lock(requestQueueLock);
requestQueue.insert(item);
@@ -51,11 +52,12 @@ void CSlackProto::PushRequest(HttpRequest *request, HttpCallback callback)
SetEvent(hRequestsQueueEvent);
}
-void CSlackProto::PushRequest(HttpRequest *request, JsonCallback callback)
+void CSlackProto::PushRequest(HttpRequest *request, JsonCallback callback, void *param)
{
RequestQueueItem *item = new RequestQueueItem();
item->request = request;
item->jsonCallback = callback;
+ item->param = param;
{
mir_cslock lock(requestQueueLock);
requestQueue.insert(item);
@@ -81,9 +83,9 @@ void CSlackProto::RequestQueueThread(void*)
requestQueue.remove(0);
}
if (item->httpCallback)
- SendRequest(item->request, item->httpCallback);
+ SendRequest(item->request, item->httpCallback, item->param);
else if (item->jsonCallback)
- SendRequest(item->request, item->jsonCallback);
+ SendRequest(item->request, item->jsonCallback, item->param);
else
SendRequest(item->request);
delete item;
diff --git a/protocols/Slack/src/slack_utils.cpp b/protocols/Slack/src/slack_utils.cpp
index bd40f58ee7..40a6680788 100644
--- a/protocols/Slack/src/slack_utils.cpp
+++ b/protocols/Slack/src/slack_utils.cpp
@@ -1,10 +1,5 @@
#include "stdafx.h"
-bool CSlackProto::IsOnline()
-{
- return false;
-}
-
void CSlackProto::ShowNotification(const TCHAR *caption, const TCHAR *message, int flags, MCONTACT hContact)
{
if (Miranda_IsTerminated())
diff --git a/protocols/Slack/src/stdafx.h b/protocols/Slack/src/stdafx.h
index ce5ebf1a80..8a24cb29f7 100644
--- a/protocols/Slack/src/stdafx.h
+++ b/protocols/Slack/src/stdafx.h
@@ -52,6 +52,8 @@ struct CSlackProto;
#include "slack_proto.h"
#include "api\api_users.h"
+#include "api\api_chat.h"
+#include "api\api_im.h"
extern HINSTANCE g_hInstance;