114 lines
3.7 KiB
C++
114 lines
3.7 KiB
C++
|
#include "CorporationContext.h"
|
||
|
#include "../ServiceManager.h"
|
||
|
#include "BoostLog.h"
|
||
|
#include "NetworkUtility.h"
|
||
|
#include <boost/asio/defer.hpp>
|
||
|
#include <boost/beast/core.hpp>
|
||
|
#include <boost/format.hpp>
|
||
|
#include <boost/json/object.hpp>
|
||
|
#include <boost/json/parse.hpp>
|
||
|
#include <boost/json/serialize.hpp>
|
||
|
|
||
|
CorporationContext::CorporationContext(boost::asio::io_context &ioContext)
|
||
|
: m_ioContext(ioContext), m_timer(ioContext) {
|
||
|
boost::asio::defer([this]() { updateAccessToken(); });
|
||
|
|
||
|
auto manager = Amass::Singleton<ServiceManager>::instance();
|
||
|
if (manager)
|
||
|
manager->registerTopic(NotifyServerChan,
|
||
|
[this](const std::string &text) { sendMessage(MessageType::Text, text); });
|
||
|
}
|
||
|
|
||
|
void CorporationContext::sendMessage(MessageType type, const std::string &message) {
|
||
|
boost::format target("/cgi-bin/message/send?access_token=%1%");
|
||
|
target % m_accessToken;
|
||
|
|
||
|
boost::json::object msg;
|
||
|
msg["content"] = message;
|
||
|
|
||
|
boost::json::object request;
|
||
|
request["touser"] = "@all";
|
||
|
request["agentid"] = agentid;
|
||
|
if (type == MessageType::Markdown) {
|
||
|
request["msgtype"] = "markdown";
|
||
|
request["markdown"] = std::move(msg);
|
||
|
} else {
|
||
|
request["msgtype"] = "text";
|
||
|
request["text"] = std::move(msg);
|
||
|
}
|
||
|
auto body = boost::json::serialize(request);
|
||
|
|
||
|
boost::beast::error_code error;
|
||
|
auto response = Https::post(m_ioContext, host, port, target.str(), body, error);
|
||
|
if (error) {
|
||
|
LOG(error) << error.message();
|
||
|
return;
|
||
|
}
|
||
|
LOG(info) << response;
|
||
|
}
|
||
|
|
||
|
void CorporationContext::notify(const RequestType &request) {
|
||
|
boost::json::error_code error;
|
||
|
auto json = boost::json::parse(request.body(), error);
|
||
|
if (error) {
|
||
|
LOG(error) << "parse: [" << request.body() << "] failed, reason: " << error.message();
|
||
|
return;
|
||
|
}
|
||
|
// LOG(debug) << "parse: [" << request.body() << "] succeed.";
|
||
|
auto &req = json.as_object();
|
||
|
MessageType type = MessageType::Text;
|
||
|
if (req.contains("type")) {
|
||
|
if (req.at("type").as_string() == "markdown") {
|
||
|
type = MessageType::Markdown;
|
||
|
}
|
||
|
}
|
||
|
if (req.contains("msg")) {
|
||
|
std::string msg(req.at("msg").as_string());
|
||
|
sendMessage(type, std::move(msg));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CorporationContext::updateAccessToken() {
|
||
|
boost::beast::error_code error;
|
||
|
|
||
|
boost::format target("/cgi-bin/gettoken?corpid=%1%&corpsecret=%2%");
|
||
|
target % corpid % corpsecret;
|
||
|
|
||
|
auto response = Https::get(m_ioContext, host, port, target.str(), error);
|
||
|
if (error) {
|
||
|
LOG(error) << error.message();
|
||
|
return;
|
||
|
}
|
||
|
if (response.empty()) {
|
||
|
LOG(warning) << "response is empty.";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
auto json = boost::json::parse(response);
|
||
|
auto &accessTokenObject = json.as_object();
|
||
|
int errcode = accessTokenObject.count("errcode") > 0 ? accessTokenObject.at("errcode").as_int64() : -1;
|
||
|
if (errcode != 0) {
|
||
|
LOG(error) << "get access_token failed,code: " << errcode
|
||
|
<< ", message: " << accessTokenObject.at("errmsg").as_string();
|
||
|
return;
|
||
|
}
|
||
|
m_accessToken = accessTokenObject.at("access_token").as_string();
|
||
|
auto expires_in = accessTokenObject.at("expires_in").as_int64();
|
||
|
// LOG(info) << "access_token: " << m_accessToken;
|
||
|
LOG(info) << "re-access_token after " << expires_in << " s.";
|
||
|
m_timer.expires_after(std::chrono::seconds(expires_in));
|
||
|
m_timer.async_wait([this](const boost::system::error_code &error) {
|
||
|
if (error) {
|
||
|
LOG(error) << error.message();
|
||
|
return;
|
||
|
}
|
||
|
updateAccessToken();
|
||
|
});
|
||
|
|
||
|
static bool started = true;
|
||
|
if (started) {
|
||
|
sendMessage(MessageType::Text, "您好,艾玛已上线......");
|
||
|
started = false;
|
||
|
}
|
||
|
}
|