Changeset - fd9c9af71bfb
[Not reviewed]
0 13 0
Jan Kaluza - 10 years ago 2016-01-26 18:55:22
jkaluza@redhat.com
Slack: Send real team name chosen by user to Web interface, create channel chosen by the user when joining the room if it does not exists
13 files changed with 131 insertions and 25 deletions:
0 comments (0 inline, 0 general)
include/transport/Frontend.h
Show inline comments
 
@@ -94,6 +94,7 @@ class Frontend {
 
		virtual std::string setOAuth2Code(const std::string &code, const std::string &state) { return "OAuth2 code is not needed for this frontend."; }
 
		virtual std::string getOAuth2URL(const std::vector<std::string> &args) { return ""; }
 
		virtual std::string getRegistrationFields() { return "Jabber ID\n3rd-party network username\n3rd-party network password"; }
 
		virtual bool handleAdminMessage(Swift::Message::ref /*message*/) { return false; }
 

	
 
		boost::signal<void (User *, const std::string &name, unsigned int id)> onVCardRequired;
 
		boost::signal<void (User *, boost::shared_ptr<Swift::VCard> vcard)> onVCardUpdated;
libtransport/AdminInterface.cpp
Show inline comments
 
@@ -324,6 +324,9 @@ void AdminInterface::handleQuery(Swift::Message::ref message) {
 
		std::string fields = m_component->getFrontend()->getRegistrationFields();
 
		message->setBody(fields);
 
	}
 
	else if (m_component->getFrontend()->handleAdminMessage(message)) {
 
		LOG4CXX_INFO(logger, "Message handled by frontend");
 
	}
 
	else if (message->getBody().find("help") == 0) {
 
		std::string help;
 
		help += "General:\n";
spectrum/src/frontends/slack/SlackAPI.cpp
Show inline comments
 
@@ -141,6 +141,12 @@ std::string SlackAPI::getChannelId(HTTPRequest *req, bool ok, rapidjson::Documen
 
	return id.GetString();
 
}
 

	
 
void SlackAPI::channelsList( HTTPRequest::Callback callback) {
 
	std::string url = "https://slack.com/api/channels.list?token=" + Util::urlencode(m_token);
 
	HTTPRequest *req = new HTTPRequest(THREAD_POOL(m_component), HTTPRequest::Get, url, callback);
 
	queueRequest(req);
 
}
 

	
 
void SlackAPI::channelsCreate(const std::string &name, HTTPRequest::Callback callback) {
 
	std::string url = "https://slack.com/api/channels.create?name=" + Util::urlencode(name) + "&token=" + Util::urlencode(m_token);
 
	HTTPRequest *req = new HTTPRequest(THREAD_POOL(m_component), HTTPRequest::Get, url, callback);
spectrum/src/frontends/slack/SlackAPI.h
Show inline comments
 
@@ -76,6 +76,8 @@ class SlackAPI : public HTTPRequestQueue {
 
		std::string getOwnerId(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data);
 

	
 
		void channelsCreate(const std::string &name, HTTPRequest::Callback callback);
 
		void channelsList(HTTPRequest::Callback callback);
 

	
 
		void imOpen(const std::string &uid, HTTPRequest::Callback callback);
 
		std::string getChannelId(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data);
 

	
spectrum/src/frontends/slack/SlackFrontend.cpp
Show inline comments
 
@@ -126,6 +126,10 @@ std::string SlackFrontend::getRegistrationFields() {
 
	return "Slack team name\n3rd-party network username\n3rd-party network password";
 
}
 

	
 
bool SlackFrontend::handleAdminMessage(Swift::Message::ref message) {
 
	return static_cast<SlackUserManager *>(m_userManager)->handleAdminMessage(message);
 
}
 

	
 
void SlackFrontend::disconnectFromServer() {
 

	
 
}
spectrum/src/frontends/slack/SlackFrontend.h
Show inline comments
 
@@ -68,6 +68,7 @@ namespace Transport {
 
			virtual std::string setOAuth2Code(const std::string &code, const std::string &state);
 
			virtual std::string getOAuth2URL(const std::vector<std::string> &args);
 
			virtual std::string getRegistrationFields();
 
			virtual bool handleAdminMessage(Swift::Message::ref message);
 
		
 
			void handleMessage(boost::shared_ptr<Swift::Message> message);
 

	
spectrum/src/frontends/slack/SlackSession.cpp
Show inline comments
 
@@ -56,10 +56,16 @@ SlackSession::SlackSession(Component *component, StorageBackend *storageBackend,
 

	
 
	m_onlineBuddiesTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(20000);
 
	m_onlineBuddiesTimer->onTick.connect(boost::bind(&SlackSession::sendOnlineBuddies, this));
 

	
 
	int type = (int) TYPE_STRING;
 
	std::string token;
 
	m_storageBackend->getUserSetting(m_uinfo.id, "access_token", type, token);
 
	m_api = new SlackAPI(m_component, token);
 
}
 

	
 
SlackSession::~SlackSession() {
 
	delete m_rtm;
 
	delete m_api;
 
	m_onlineBuddiesTimer->stop();
 
}
 

	
 
@@ -150,12 +156,11 @@ void SlackSession::setPurpose(const std::string &purpose, const std::string &cha
 
	m_rtm->getAPI()->setPurpose(ch, purpose);
 
}
 

	
 
void SlackSession::handleJoinMessage(const std::string &message, std::vector<std::string> &args, bool quiet) {
 
	// .spectrum2 join.room BotName #room irc.freenode.net channel
 
void SlackSession::joinRoom(std::vector<std::string> args) {
 
	std::string &name = args[2];
 
	std::string legacyRoom = SlackAPI::SlackObjectToPlainText(args[3], true);
 
	std::string legacyServer = SlackAPI::SlackObjectToPlainText(args[4]);
 
	std::string slackChannel = SlackAPI::SlackObjectToPlainText(args[5], true);
 
	std::string &legacyRoom = args[3];
 
	std::string &legacyServer = args[4];
 
	std::string &slackChannel = args[5];
 

	
 
	std::string to = legacyRoom + "%" + legacyServer + "@" + m_component->getJID().toString();
 
	if (!CONFIG_BOOL_DEFAULTED(m_component->getConfig(), "registration.needRegistration", true)) {
 
@@ -169,16 +174,6 @@ void SlackSession::handleJoinMessage(const std::string &message, std::vector<std
 
	m_jid2channel[to] = slackChannel;
 
	m_channel2jid[slackChannel] = to;
 

	
 
	LOG4CXX_INFO(logger, "Setting transport between " << to << " and " << slackChannel);
 

	
 
	if (!quiet) {
 
		std::string rooms = "";
 
		int type = (int) TYPE_STRING;
 
		m_storageBackend->getUserSetting(m_uinfo.id, "rooms", type, rooms);
 
		rooms += message + "\n";
 
		m_storageBackend->updateUserSetting(m_uinfo.id, "rooms", rooms);
 
	}
 

	
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
	presence->setFrom(Swift::JID("", m_uinfo.jid, "default"));
 
	presence->setTo(Swift::JID(to + "/" + name));
 
@@ -187,14 +182,39 @@ void SlackSession::handleJoinMessage(const std::string &message, std::vector<std
 
	m_component->getFrontend()->onPresenceReceived(presence);
 

	
 
	m_onlineBuddiesTimer->start();
 
}
 

	
 
	if (!quiet) {
 
		std::string msg;
 
		msg += "Spectrum 2 is now joining the room. To leave the room later to disable transporting, you can use `.spectrum2 leave.room #" + SlackAPI::SlackObjectToPlainText(args[5], true, true) + "`.";
 
		m_rtm->sendMessage(m_ownerChannel, msg);
 
void SlackSession::handleJoinRoomCreate(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data, std::vector<std::string> args) {
 
	std::string channelId = m_api->getChannelId(req, ok, resp, data);
 
	if (channelId.empty()) {
 
		LOG4CXX_INFO(logger, args[1] << ": Error creating channel " << args[5] << ".");
 
		return;
 
	}
 

	
 
	args[5] = channelId;
 
	joinRoom(args);
 
}
 

	
 
void SlackSession::handleJoinRoomList(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data, std::vector<std::string> args) {
 
	std::map<std::string, SlackChannelInfo> channels;
 
	SlackAPI::getSlackChannelInfo(req, ok, resp, data, channels);
 

	
 
	if (channels.find(args[5]) != channels.end()) {
 
		LOG4CXX_INFO(logger, args[1] << ": Channel " << args[5] << " already exists. Joining the room.");
 
		args[5] = channels[args[5]].id;
 
		joinRoom(args);
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, args[1] << ": Channel " << args[5] << " does not exit. Creating it.");
 
		m_api->channelsCreate(args[5], boost::bind(&SlackSession::handleJoinRoomCreate, this, _1, _2, _3, _4, args));
 
	}
 
}
 

	
 
void SlackSession::handleJoinMessage(const std::string &message, std::vector<std::string> &args, bool quiet) {
 
	LOG4CXX_INFO(logger, args[1] << ": Going to join the room, checking the ID of channel " << args[5]);
 
	m_api->channelsList(boost::bind(&SlackSession::handleJoinRoomList, this, _1, _2, _3, _4, args));
 
}
 

	
 
void SlackSession::handleLeaveMessage(const std::string &message, std::vector<std::string> &args, bool quiet) {
 
	// .spectrum2 leave.room channel
 
	std::string slackChannel = SlackAPI::SlackObjectToPlainText(args[2], true);
spectrum/src/frontends/slack/SlackSession.h
Show inline comments
 
@@ -60,14 +60,18 @@ class SlackSession {
 
		void handleDisconnected();
 
		void handleConnected();
 

	
 
		void handleJoinMessage(const std::string &message, std::vector<std::string> &args, bool quiet = false);
 
		void handleLeaveMessage(const std::string &message, std::vector<std::string> &args, bool quiet = false);
 
		void handleRegisterMessage(const std::string &message, std::vector<std::string> &args, bool quiet = false);
 

	
 
	private:
 
		void handleRTMStarted();
 
		void handleMessageReceived(const std::string &channel, const std::string &user, const std::string &message, const std::string &ts, bool quiet);
 
		void handleImOpen(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data);
 

	
 
		void handleJoinMessage(const std::string &message, std::vector<std::string> &args, bool quiet = false);
 
		void handleLeaveMessage(const std::string &message, std::vector<std::string> &args, bool quiet = false);
 
		void handleRegisterMessage(const std::string &message, std::vector<std::string> &args, bool quiet = false);
 
		void joinRoom(std::vector<std::string> args);
 
		void handleJoinRoomCreate(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data, std::vector<std::string> args);
 
		void handleJoinRoomList(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data, std::vector<std::string> args);
 

	
 
		void sendOnlineBuddies();
 

	
 
@@ -86,6 +90,7 @@ class SlackSession {
 
		std::map<std::string, std::string> m_onlineBuddies;
 
		bool m_disconnected;
 
		std::string m_ownerId;
 
		SlackAPI *m_api;
 
};
 

	
 
}
spectrum/src/frontends/slack/SlackUserManager.cpp
Show inline comments
 
@@ -29,6 +29,8 @@
 
#include "transport/StorageBackend.h"
 
#include "transport/Logging.h"
 

	
 
#include <boost/algorithm/string.hpp>
 

	
 
namespace Transport {
 

	
 
DEFINE_LOGGER(logger, "SlackUserManager");
 
@@ -102,5 +104,52 @@ void SlackUserManager::handleUserCreated(User *user) {
 
	static_cast<SlackUser *>(user)->getSession()->handleConnected();
 
}
 

	
 
bool SlackUserManager::handleAdminMessage(Swift::Message::ref message) {
 
	if (message->getBody().find("get_user_configuration") == 0) {
 
// 		std::string body = message->getBody();
 
// 		std::vector<std::string> args;
 
// 		boost::split(args, body, boost::is_any_of(" "));
 
// 		if (args.size() == 2) {
 
// 			UserInfo uinfo;
 
// 			if (!m_storageBackend->getUser(args[1], uinfo)) {
 
// 				message->setBody("Error: Unknown user");
 
// 				return true;
 
// 			}
 
// 
 
// 			std::string rooms = "";
 
// 			int type = (int) TYPE_STRING;
 
// 			m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms);
 
// 
 
// 			m_storageBackend->getUserSetting(uinfo.id, "slack_channel", type, m_slackChannel);
 
// 		}
 
	}
 
	else if (message->getBody().find("join_room ") == 0) {
 
		std::string body = message->getBody();
 
		std::vector<std::string> args;
 
		boost::split(args, body, boost::is_any_of(" "));
 
		if (args.size() == 6) {
 
			UserInfo uinfo;
 
			if (!m_storageBackend->getUser(args[1], uinfo)) {
 
				message->setBody("Error: Unknown user");
 
				return true;
 
			}
 

	
 
			std::string rooms = "";
 
			int type = (int) TYPE_STRING;
 
			m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms);
 
			rooms += message->getBody() + "\n";
 
			m_storageBackend->updateUserSetting(uinfo.id, "rooms", rooms);
 

	
 
			SlackUser *user = static_cast<SlackUser *>(getUser(args[1]));
 
			if (user) {
 
				user->getSession()->handleJoinMessage("", args, true);
 
			}
 
			message->setBody("Joined the room");
 
			return true;
 
		}
 
	}
 
	return false;
 
}
 

	
 

	
 
}
spectrum/src/frontends/slack/SlackUserManager.h
Show inline comments
 
@@ -62,6 +62,8 @@ class SlackUserManager : public UserManager {
 
		SlackSession *moveTempSession(const std::string &user);
 
		void moveTempSession(const std::string &user, SlackSession *session);
 

	
 
		bool handleAdminMessage(Swift::Message::ref message);
 

	
 
	private:
 
		void handleUserCreated(User *user);
 

	
spectrum/src/frontends/slack/SlackUserRegistration.cpp
Show inline comments
 
@@ -175,7 +175,7 @@ std::string SlackUserRegistration::handleOAuth2Code(const std::string &code, con
 

	
 
	m_component->getFrontend()->reconnectUser(user.jid);
 

	
 
	return "";
 
	return "Registered as " + domain;
 
}
 

	
 
bool SlackUserRegistration::doUserRegistration(const UserInfo &row) {
spectrum_manager/src/server.cpp
Show inline comments
 
@@ -396,7 +396,20 @@ void Server::serve_oauth2(struct mg_connection *conn, struct http_message *hm) {
 
	std::string code = get_http_var(hm, "code");
 
	std::string state = get_http_var(hm, "state");
 

	
 
	send_command(instance, "set_oauth2_code " + code + " " + state);
 
	std::string response = send_command(instance, "set_oauth2_code " + code + " " + state);
 
	if (response.find("Registered as ") == 0) {
 
		std::vector<std::string> args;
 
		boost::split(args, response, boost::is_any_of(" "));
 
		if (args.size() == 3) {
 
			Server:session *session = get_session(hm);
 
			UserInfo info;
 
			m_storage->getUser(session->user, info);
 
			std::string username = "";
 
			int type = (int) TYPE_STRING;
 
			m_storage->getUserSetting(info.id, instance, type, username);
 
			m_storage->updateUserSetting(info.id, instance, args[2]);
 
		}
 
	}
 
	redirect_to(conn, hm, "/instances/");
 
}
 

	
tests/start.py
Show inline comments
 
@@ -195,7 +195,7 @@ configurations = []
 
configurations.append(LibcommuniServerModeSingleServerConf())
 
configurations.append(LibcommuniServerModeConf())
 
configurations.append(JabberServerModeConf())
 
configurations.append(JabberSlackServerModeConf())
 
#configurations.append(JabberSlackServerModeConf())
 
configurations.append(TwitterServerModeConf())
 

	
 
exitcode = 0
0 comments (0 inline, 0 general)