Changeset - 1bf36dbf68fe
[Not reviewed]
0 2 0
Jan Kaluza - 9 years ago 2016-01-25 08:24:41
jkaluza@redhat.com
Allow setting main channel using Slack command
2 files changed with 27 insertions and 1 deletions:
0 comments (0 inline, 0 general)
spectrum/src/frontends/slack/SlackSession.cpp
Show inline comments
 
@@ -309,48 +309,62 @@ void SlackSession::handleMessageReceived(const std::string &channel, const std::
 
				msg->setBody("<" + m_rtm->getUserName(user) + "> " + message);
 
				m_component->getFrontend()->onMessageReceived(msg);
 
			}
 
		}
 
		return;
 
	}
 

	
 
	std::vector<std::string> args;
 
	boost::split(args, message, boost::is_any_of(" "));
 

	
 
	if (args.size() < 2 || args[0] != ".spectrum2") {
 
		m_rtm->sendMessage(m_ownerChannel, "Unknown command. Use \".spectrum2 help\" for help.");
 
		return;
 
	}
 

	
 
	if (args[1] == "join.room" && args.size() == 6) {
 
		handleJoinMessage(message, args, quiet);
 
	}
 
	else if (args[1] == "leave.room" && args.size() == 3) {
 
		handleLeaveMessage(message, args, quiet);
 
	}
 
	else if (args[1] == "register" && args.size() == 5) {
 
		handleRegisterMessage(message, args, quiet);
 
	}
 
	else if (args[1] == "set_main_channel" && args.size() == 3) {
 
		std::string slackChannel = SlackAPI::SlackObjectToPlainText(args[2], true);
 

	
 
		m_storageBackend->setUser(m_uinfo);
 
		int type = (int) TYPE_STRING;
 
		m_storageBackend->getUserSetting(m_uinfo.id, "slack_channel", type, slackChannel);
 

	
 
		Swift::Presence::ref presence = Swift::Presence::create();
 
		presence->setFrom(Swift::JID("", m_uinfo.jid, "default"));
 
		presence->setTo(m_component->getJID());
 
		presence->setType(Swift::Presence::Available);
 
		presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
 
		m_component->getFrontend()->onPresenceReceived(presence);
 
	}
 
	else if (args[1] == "list.rooms" && args.size() == 2) {
 
		// .spectrum2 list.rooms
 
		std::string rooms = "";
 
		int type = (int) TYPE_STRING;
 
		m_storageBackend->getUserSetting(m_uinfo.id, "rooms", type, rooms);
 

	
 
		std::string msg = "Spectrum 2 is configured for following channels:\\n";
 
		msg += "```" + rooms  + "```";
 
		m_rtm->sendMessage(m_ownerChannel, msg);
 
	}
 
	else if (args[1] == "reconnect") {
 
		Swift::Presence::ref presence = Swift::Presence::create();
 
		presence->setFrom(Swift::JID("", m_uinfo.jid, "default"));
 
		presence->setTo(m_component->getJID());
 
		presence->setType(Swift::Presence::Available);
 
		presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
 
		m_component->getFrontend()->onPresenceReceived(presence);
 
	}
 
	else if (args[1] == "help") {
 
		std::string msg;
 
		msg =  "Following commands are supported:\\n";
 
		msg += "```.spectrum2 help``` Shows this help message.\\n";
 
		msg += "```.spectrum2 join.room <3rdPartyBotName> <#3rdPartyRoom> <3rdPartyServer> <#SlackChannel>``` Starts transport between 3rd-party room and Slack channel.";
 
		msg += "```.spectrum2 leave.room <#SlackChannel>``` Leaves the 3rd-party room connected with the given Slack channel.";
 
@@ -404,48 +418,58 @@ void SlackSession::handleImOpen(HTTPRequest *req, bool ok, rapidjson::Document &
 
	}
 
	else {
 
		if (m_uinfo.uin.empty()) {
 
			std::string msg;
 
			msg =  "Hi, it seems you have enabled Spectrum 2 transport for your Team. As a Team owner, you should now configure it:\\n";
 
			msg += "1. At first, create new channel in which you want this Spectrum 2 transport to send the messages, or choose the existing one.\\n";
 
			msg += "2. Invite this Spectrum 2 bot into this channel.\\n";
 
			msg += "3. Configure the transportation between 3rd-party network and this channel by executing following command in this chat:\\n";
 
			msg += "```.spectrum2 register 3rdPartyAccount 3rdPartyPassword #SlackChannel```\\n";
 
			msg += "For example to join XMPP account test@xmpp.tld and  transport it into #slack_channel, the command would look like this:\\n";
 
			msg += "```.spectrum2 register test@xmpp.tld mypassword #slack_channel```\\n";
 
			msg += "To get full list of available commands, executa `.spectrum2 help`\\n";
 
			m_rtm->sendMessage(m_ownerChannel, msg);
 
		}
 
		else {
 
			m_storageBackend->getUserSetting(m_uinfo.id, "slack_channel", type, m_slackChannel);
 
			if (!m_slackChannel.empty()) {
 
				Swift::Presence::ref presence = Swift::Presence::create();
 
				presence->setFrom(Swift::JID("", m_uinfo.jid, "default"));
 
				presence->setTo(m_component->getJID());
 
				presence->setType(Swift::Presence::Available);
 
				presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
 
				m_component->getFrontend()->onPresenceReceived(presence);
 
			}
 
			else {
 
				std::string msg;
 
				msg =  "Hi, it seems you have enabled Spectrum 2 transport for your Team. As a Team owner, you should now configure it:\\n";
 
				msg += "1. At first, create new channel in which you want this Spectrum 2 transport to send the messages, or choose the existing one.\\n";
 
				msg += "2. Invite this Spectrum 2 bot into this channel.\\n";
 
				msg += "3. Configure the transportation between 3rd-party network and this channel by executing following command in this chat:\\n";
 
				msg += "```.spectrum2 set_main_channel #SlackChannel```\\n";
 
				msg += "To get full list of available commands, executa `.spectrum2 help`\\n";
 
				m_rtm->sendMessage(m_ownerChannel, msg);
 
			}
 
		}
 
	}
 

	
 
	// Auto-join the rooms configured by the Slack channel owner.
 
	if (!rooms.empty()) {
 
		std::vector<std::string> commands;
 
		boost::split(commands, rooms, boost::is_any_of("\n"));
 

	
 
		BOOST_FOREACH(const std::string &command, commands) {
 
			if (command.size() > 5) {
 
				LOG4CXX_INFO(logger, m_uinfo.jid << ": Sending command from storage: " << command);
 
				handleMessageReceived(m_ownerChannel, "owner", command, "", true);
 
			}
 
		}
 
	}
 
}
 

	
 
void SlackSession::handleRTMStarted() {
 
	std::map<std::string, SlackUserInfo> &users = m_rtm->getUsers();
 
	for (std::map<std::string, SlackUserInfo>::iterator it = users.begin(); it != users.end(); it++) {
 
		SlackUserInfo &info = it->second;
 
		if (info.isPrimaryOwner) {
 
			m_ownerId = it->first;
 
			break;
spectrum_manager/src/APIServer.cpp
Show inline comments
 
@@ -61,83 +61,85 @@ void APIServer::send_json(struct mg_connection *conn, const Document &d) {
 
	std::cout << json << "\n";
 
	mg_printf(conn,
 
			"HTTP/1.1 200 OK\r\n"
 
			"Content-Type: text/json\r\n"
 
			"Content-Length: %d\r\n"
 
			"\r\n"
 
			"%s",
 
			(int) json.size(), json.c_str());
 
}
 

	
 
void APIServer::send_ack(struct mg_connection *conn, bool error, const std::string &message) {
 
	Document json;
 
	json.SetObject();
 
	json.AddMember("error", error, json.GetAllocator());
 
	json.AddMember("message", message.c_str(), json.GetAllocator());
 

	
 
	send_json(conn, json);
 
}
 

	
 
void APIServer::serve_instances(Server *server, Server::session *session, struct mg_connection *conn, struct http_message *hm) {
 
	// rapidjson stores const char* pointer to status, so we have to keep
 
	// the std::string stored out of BOOST_FOREACH scope, otherwise the
 
	// const char * returned by c_str() would be invalid during send_json.
 
	std::vector<std::string> statuses;
 
	std::vector<std::string> usernames;
 
	std::vector<std::string> list = show_list(m_config, false);
 

	
 
	Document json;
 
	json.SetObject();
 
	json.AddMember("error", 0, json.GetAllocator());
 

	
 
	Value instances(kArrayType);
 
	BOOST_FOREACH(std::string &id, list) {
 
		Value instance;
 
		instance.SetObject();
 
		instance.AddMember("id", id.c_str(), json.GetAllocator());
 
		instance.AddMember("name", id.c_str(), json.GetAllocator());
 

	
 
		std::string status = server->send_command(id, "status");
 
		if (status.empty()) {
 
			status = "Cannot get the instance status.";
 
		}
 

	
 
		statuses.push_back(status);
 
		instance.AddMember("status", statuses.back().c_str(), json.GetAllocator());
 

	
 
		bool running = true;
 
		if (status.find("Running") == std::string::npos) {
 
			running = false;
 
		}
 
		instance.AddMember("running", running, json.GetAllocator());
 

	
 
		UserInfo info;
 
		m_storage->getUser(session->user, info);
 
		std::string username = "";
 
		int type = (int) TYPE_STRING;
 
		m_storage->getUserSetting(info.id, id, type, username);
 

	
 
		usernames.push_back(username);
 
		instance.AddMember("registered", !username.empty(), json.GetAllocator());
 
		instance.AddMember("username", username.c_str(), json.GetAllocator());
 
		instance.AddMember("username", usernames.back().c_str(), json.GetAllocator());
 

	
 
		instances.PushBack(instance, json.GetAllocator());
 
	}
 

	
 
	json.AddMember("instances", instances, json.GetAllocator());
 
	send_json(conn, json);
 
}
 

	
 
void APIServer::serve_instances_start(Server *server, Server::session *session, struct mg_connection *conn, struct http_message *hm) {
 
	ALLOW_ONLY_ADMIN();
 

	
 
	std::string uri(hm->uri.p, hm->uri.len);
 
	std::string instance = uri.substr(uri.rfind("/") + 1);
 
	start_instances(m_config, instance);
 
	std::string response = get_response();
 

	
 
	// TODO: So far it needs some time to reload Spectrum 2, so just sleep here.
 
	sleep(1);
 

	
 
	send_ack(conn, response.find("OK") == std::string::npos, response);
 
}
 

	
 
void APIServer::serve_instances_stop(Server *server, Server::session *session, struct mg_connection *conn, struct http_message *hm) {
 
	ALLOW_ONLY_ADMIN();
0 comments (0 inline, 0 general)