gogs 发送邮件通知的程序

这是几年以前,写的一个用于 gogs 服务进行推送通知到邮件的程序。那时候还不会写GO程序,于是用C++写的,麻烦得很。用GO来写同样的程序要省事多了。

代码

#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Net/ServerSocket.h>
#include <Poco/Util/ServerApplication.h>
#include <Poco/StreamCopier.h>
#include <Poco/Util/IniFileConfiguration.h>
#include <Poco/URI.h>
#include <Poco/StringTokenizer.h>
#include <Poco/JSON/Parser.h>
#include <Poco/JSON/Object.h>
#include <Poco/Dynamic/Var.h>
#include <Poco/Net/MailMessage.h>
#include <Poco/Net/StringPartSource.h>
#include <Poco/Net/SMTPClientSession.h>
#include <Poco/Net/SecureSMTPClientSession.h>
#include <Poco/Exception.h>
#include <iostream>

using namespace Poco;
using namespace Poco::Net;
using namespace Poco::Util;
using namespace Poco::JSON;

static std::string mailuser,mailpasswd;

class HelloRequestHandler: public HTTPRequestHandler
{
	void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
	{
		Application& app = Application::instance();
		try{
			std::istream& is = request.stream();
			std::string body;
			StreamCopier::copyToString(is,body);

			Poco::Net::HTTPResponse::HTTPStatus status = Poco::Net::HTTPResponse::HTTP_NOT_FOUND;
			Poco::URI uri(request.getURI());
			if(uri.getPath() != "/release"){
				throw status;
			}
			std::string query = uri.getQuery();
			if(query.find("NotifyParty") != 0){
				throw status;
			}
			Poco::StringTokenizer tok(query.substr(sizeof("NotifyParty")),";",1);
			std::vector<std::string> notifyParty(tok.begin(),tok.end());

			Poco::Net::MailMessage message;
			Poco::JSON::Parser jsonparser;
			Poco::Dynamic::Var result = jsonparser.parse(body);
			Object::Ptr rootObj = result.extract<Object::Ptr>();
			Object::Ptr releaseObj = rootObj->getObject("release");
			Object::Ptr repositoryObj = rootObj->getObject("repository");
			Object::Ptr authorObj = releaseObj->getObject("author");
			// 获取邮件标题
			std::string mailSubject = "版本发布:" + repositoryObj->getValue<std::string>("name")
				+ "    " + releaseObj->getValue<std::string>("name");
			message.setSubject(mailSubject);
			// 获取创建时间
			std::string mailDatetime = releaseObj->getValue<std::string>("created_at");
			Poco::DateTime dt; int tzd; /*tzd 用于获取时区差值*/
			Poco::DateTimeParser::parse(Poco::DateTimeFormat::ISO8601_FORMAT, mailDatetime, dt, tzd);
			message.setDate(dt.timestamp() - Poco::Timespan(tzd,0));
			mailDatetime = Poco::DateTimeFormatter::format(dt.timestamp(),"%Y年%m月%d日 %H:%M:%S");

			// 获取发布内容
			std::string mailbody;
			mailbody.append("\n项    目:").append(repositoryObj->getValue<std::string>("name"));
			mailbody.append("\n描    述:").append(repositoryObj->getValue<std::string>("description"));
			mailbody.append("\n版本标题:").append(releaseObj->getValue<std::string>("name"));
			mailbody.append("\n版本标签:").append(releaseObj->getValue<std::string>("tag_name"));
			mailbody.append("\n版本描述:").append(releaseObj->getValue<std::string>("body"));
			mailbody.append("\n发布时间:").append(mailDatetime);
			mailbody.append("\n发布作者:").append(authorObj->getValue<std::string>("full_name"));
			mailbody.append("\n访问地址:").append(repositoryObj->getValue<std::string>("html_url"));

			message.setContentType("text/html;charset=utf-8");
			message.addContent(new Poco::Net::StringPartSource(mailbody));
			//message.setContent(mailbody);

			message.setSender(mailuser);
			for(auto& r: notifyParty) {
				message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, r));
			}

			//app.logger().information("开始登录");
			// 发送邮件
			//Poco::Net::SMTPClientSession smtpSession("smtp.exmail.qq.com");
			Poco::Net::SecureSMTPClientSession smtpSession("smtp.exmail.qq.com");

			smtpSession.open();
			// smtpSession.login(Poco::Net::SMTPClientSession::LoginMethod::AUTH_LOGIN, mailuser, mailpasswd);

			smtpSession.login();
			smtpSession.startTLS();
			smtpSession.login(Poco::Net::SMTPClientSession::LoginMethod::AUTH_LOGIN, mailuser, mailpasswd);

			//app.logger().information("开始发送邮件");
			smtpSession.sendMessage(message);
			// app.logger().information("发送邮件完成");
			smtpSession.close();
		}
		catch (Poco::Exception& e) {
			app.logger().error("Poco Exception(%s)\n", e.displayText());
		}
		catch (std::exception& e) {
			app.logger().error("std Exception(%s)\n", e.what());
		}
		catch(Poco::Net::HTTPResponse::HTTPStatus s){
			response.setStatusAndReason(s);
			response.send();
			return;
		}
		response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_OK);
		response.send();
	}
};

class HelloRequestHandlerFactory: public HTTPRequestHandlerFactory
{
	HTTPRequestHandler* createRequestHandler(const HTTPServerRequest&)
	{
		return new HelloRequestHandler;
	}
};

class WebServerApp: public ServerApplication
{
	void initialize(Application& self)
	{
		loadConfiguration();
		ServerApplication::initialize(self);
	}

	int main(const std::vector<std::string>&)
	{
		try{
			// 读取gogs配置
			AutoPtr<IniFileConfiguration> pConf(new IniFileConfiguration("./custom/conf/app.ini"));
			mailuser = pConf->getString("mailer.USER");
			mailpasswd = pConf->getString("mailer.PASSWD");
			logger().information("Email User is %s",mailuser);
			logger().information("Email Password is %s",mailpasswd);

			UInt16 port = static_cast<UInt16>(config().getUInt("port", 3001));

			HTTPServer srv(new HelloRequestHandlerFactory, port);
			srv.start();
			logger().information("HTTP Server started on port %hu.", port);
			waitForTerminationRequest();
			logger().information("Stopping HTTP Server...");
			srv.stop();

			return Application::EXIT_OK;
		}
		catch (Poco::Exception& e) {
			logger().error("Poco Exception(%s)\n", e.displayText());
		}
		catch (std::exception& e) {
			logger().error("std Exception(%s)\n", e.what());
		}
		catch (...) {
			logger().error("Unknown Exception");
		}
		return Application::EXIT_OK;
	}
};

POCO_SERVER_MAIN(WebServerApp)

Makefile

CXX=g++
LIBS= -lPocoNetSSL  -lPocoNet -lPocoJSON -lPocoUtil -lPocoFoundation -lpthread

all:SendMail

SendMail:SendMail.cpp
	$(CXX) -o $@ -std=c++11 $^ $(LIBS) -Wl,-rpath=/usr/local/lib

clean:
	rm SendMail
posted @ 2020-07-24 20:02  乌合之众  阅读(660)  评论(0编辑  收藏  举报
clear