├── .gitignore
├── logs
└── .gitignore
├── .gitattributes
├── screenshot.png
├── README.md
├── guest.html
├── owner1.html
├── owner.html
├── guest1.html
└── Plugin.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *_log.php
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * linguist-language=PHP
2 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oott123/CommentMailPlus/HEAD/screenshot.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CommentMailPlus
2 |
3 | ## 评论邮件通知插件
4 |
5 | 一款 Typecho 评论邮件提醒插件
6 |
7 | - 基于 PHP 插件 cURL 实现
8 | - 基于 MailGun API 实现
9 |
10 | ### 安装方法
11 |
12 | 进入插件目录
13 |
14 | ```bash
15 | $ cd typecho/usr/plugins/
16 | ```
17 |
18 | > 小贴士:此处路径请根据实际网址路径进行调整,此处仅为样例。
19 |
20 | 克隆插件文件
21 |
22 | ```bash
23 | $ git clone https://github.com/oott123/CommentMailPlus.git
24 | ```
25 |
26 | 在后台启用即可
27 |
28 | ### 适用环境
29 |
30 | 本插件发送邮件利用 cURL 组件连接 MailGun 的 HTTPS 接口,具有到达率高,延迟低等特点,适合于无法使用 SMTP 的环境使用。
31 |
32 | 若当前 PHP 环境无法修改以支持 cURL 组件,可以尝试使用 [CommentToMail](http://docs.typecho.org/plugins/commenttomail) 插件,然后参照 [MailGun User Manual](https://documentation.mailgun.com/en/latest/user_manual.html#introduction) 上的相关说明设置 SMTP 服务。
33 |
34 | 经测试,SAE可用。
35 |
36 | ### 感谢
37 |
38 | [@Cain](https://github.com/Vndroid)
39 |
40 | ### 其它问题
41 |
42 | 有问题请发 issues ,欢迎提交代码。其他关于 MailGun 说明可在[官方文档](https://documentation.mailgun.com/en/latest/)中查看。
--------------------------------------------------------------------------------
/guest.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | | 来自 {site} 的回应 |
6 |
7 |
8 | {author}回复:
{text} |
9 |
10 |
11 | | 回复地址:{permalink} |
12 |
13 |
14 | {author_p}的原文:
{text_p} |
15 |
16 |
17 | | 本邮件为{site}自动发送,请勿回复! |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/owner1.html:
--------------------------------------------------------------------------------
1 |
5 |
10 |
11 |
作者:{author} <{mail}>
12 |
时间:{time}
13 |
内容:
14 |
{text}
16 |
17 |
您可以点击 查看回复的完整內容
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/owner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | | {site}:《{title}》有新的评论 |
6 |
7 |
8 | | 作者:{author} {mail} |
9 |
10 |
11 | | 时间:{time} |
12 |
13 |
14 | | 状态:{status} [管理评论] |
15 |
16 |
17 | | 链接:{permalink} |
18 |
19 |
20 | 内容:
{text} |
21 |
22 |
23 | | 本邮件为{site}自动发送,请勿回复! |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/guest1.html:
--------------------------------------------------------------------------------
1 |
5 |
10 |
11 |
{author_p}, 您好!
12 |
您曾在 [{site}] 的文章《{title}》上发表评论:
13 |
{text_p}
15 |
{author} 给您的回复如下:
16 |
{text}
18 |
您可以点击 查看回复的完整內容
19 |
欢迎再次光临 {site}
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Plugin.php:
--------------------------------------------------------------------------------
1 | finishComment = array('CommentMailPlus_Plugin', 'toMail');
24 | return _t('请到设置面板正确配置 MailGun 才可正常工作。');
25 | }
26 |
27 | /**
28 | * 禁用插件方法,如果禁用失败,直接抛出异常
29 | *
30 | * @static
31 | * @access public
32 | * @return void
33 | * @throws Typecho_Plugin_Exception
34 | */
35 | public static function deactivate() {
36 | Helper::removeAction('comment-mail-plus');
37 | }
38 |
39 | /**
40 | * 获取插件配置面板
41 | *
42 | * @access public
43 | * @param Typecho_Widget_Helper_Form $form 配置面板
44 | * @return void
45 | */
46 | public static function config(Typecho_Widget_Helper_Form $form) {
47 | $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL,
48 | _t('收件人邮箱'),_t('接收邮件用的信箱,为空则使用文章作者个人设置中的邮箱!'));
49 | $form->addInput($mail->addRule('email', _t('请填写正确的邮箱!')));
50 |
51 | $status = new Typecho_Widget_Helper_Form_Element_Checkbox('status',
52 | array('approved' => '提醒已通过评论',
53 | 'waiting' => '提醒待审核评论',
54 | 'spam' => '提醒垃圾评论'),
55 | array('approved', 'waiting'), '提醒设置',_t('该选项仅针对博主,访客只发送已通过的评论。'));
56 | $form->addInput($status);
57 |
58 | $other = new Typecho_Widget_Helper_Form_Element_Checkbox('other',
59 | array('to_owner' => '有评论及回复时,发邮件通知博主',
60 | 'to_guest' => '评论被回复时,发邮件通知评论者',
61 | 'to_me'=>'自己回复自己的评论时(同时针对博主和访客),发邮件通知',
62 | 'to_log' => '记录邮件发送日志'),
63 | array('to_owner','to_guest'), '其他设置',_t('如果勾选“记录邮件发送日志”选项,则会在 ./CommentMailPlus/logs/mail_log.php 中记录发送信息。
64 | 关键性错误日志将自动记录到 ./CommentMailPlus/logs/error_log.php 中。
65 | '));
66 | $form->addInput($other->multiMode());
67 | $key = new Typecho_Widget_Helper_Form_Element_Text('key', NULL, 'xxxxxxxxxxxxxxxxxxx-xxxxxx-xxxxxx',
68 | _t('MailGun API 密钥'), _t('请填写在 MailGun 申请的密钥,可在个人页中查看 '));
69 | $form->addInput($key->addRule('required', _t('密钥不能为空')));
70 | $domain = new Typecho_Widget_Helper_Form_Element_Text('domain', NULL, 'samples.mailgun.org',
71 | _t('MailGun 域名'), _t('请填写您的邮件域名,若使用官方提供的测试域名可能存在其他问题'));
72 | $form->addInput($domain->addRule('required', _t('邮件域名不能为空')));
73 | $mailAddress = new Typecho_Widget_Helper_Form_Element_Text('mailAddress', NULL, 'no-reply@samples.mailgun.org',
74 | _t('发件人邮箱'));
75 | $form->addInput($mailAddress->addRule('required', _t('发件人地址不能为空')));
76 | $senderName = new Typecho_Widget_Helper_Form_Element_Text('senderName', NULL, '评论提醒',
77 | _t('发件人显示名'));
78 | $form->addInput($senderName);
79 |
80 | $titleForOwner = new Typecho_Widget_Helper_Form_Element_Text('titleForOwner',null,"[{site}]:《{title}》有新的评论",
81 | _t('博主接收邮件标题'));
82 | $form->addInput($titleForOwner);
83 |
84 | $titleForGuest = new Typecho_Widget_Helper_Form_Element_Text('titleForGuest',null,"[{site}]:您在《{title}》的评论有了回复",
85 | _t('访客接收邮件标题'));
86 | $form->addInput($titleForGuest);
87 | }
88 |
89 | /**
90 | * 个人用户的配置面板
91 | *
92 | * @access public
93 | * @param Typecho_Widget_Helper_Form $form
94 | * @return void
95 | */
96 | public static function personalConfig(Typecho_Widget_Helper_Form $form) {
97 |
98 | }
99 |
100 | /**
101 | * 组合邮件内容
102 | *
103 | * @access public
104 | * @param $post 调用参数
105 | * @return void
106 | */
107 | public static function toMail($post) {
108 | //发送邮件
109 | $settings=Helper::options()->plugin('CommentMailPlus');
110 | $options = Typecho_Widget::widget('Widget_Options');
111 | //邮件模板变量
112 | $tempinfo['site'] = $options->title;
113 | $tempinfo['siteUrl'] = $options->siteUrl;
114 | $tempinfo['title'] = $post->title;
115 | $tempinfo['cid'] = $post->cid;
116 | $tempinfo['coid'] = $post->coid;
117 | $tempinfo['created'] = $post->created;
118 | $tempinfo['timezone'] = $options->timezone;
119 | $tempinfo['author'] = $post->author;
120 | $tempinfo['authorId'] = $post->authorId;
121 | $tempinfo['ownerId'] = $post->ownerId;
122 | $tempinfo['mail'] = $post->mail;
123 | $tempinfo['ip'] = $post->ip;
124 | $tempinfo['title'] = $post->title;
125 | $tempinfo['text'] = $post->text;
126 | $tempinfo['permalink'] = $post->permalink;
127 | $tempinfo['status'] = $post->status;
128 | $tempinfo['parent'] = $post->parent;
129 | $tempinfo['manage'] = $options->siteUrl."admin/manage-comments.php";
130 | $_db = Typecho_Db::get();
131 | $original = $_db->fetchRow($_db::get()->select('author', 'mail', 'text')
132 | ->from('table.comments')
133 | ->where('coid = ?', $tempinfo['parent']));
134 | //var_dump($original);die();
135 |
136 | //判断发送
137 | //1.发送博主邮件
138 | //无需判断,先发为敬。
139 | if(in_array('to_owner', $settings->other) && in_array($tempinfo['status'], $settings->status)){
140 | $this_mail = $tempinfo['mail'];
141 | $to_mail = $settings->mail;
142 | if(!$to_mail){
143 | Typecho_Widget::widget('Widget_Users_Author@' . $tempinfo['cid'], array('uid' => $tempinfo['authorId']))->to($user);
144 | $to_mail = $user->mail;
145 | }
146 | if($this_mail != $to_mail || in_array('to_me',$settings->other)){
147 | //判定可以发送邮件
148 | $from_mail = $settings->mailAddress;
149 | $title = self::_getTitle(false,$settings,$tempinfo);
150 | $body = self::_getHtml(false,$tempinfo);
151 | self::_sendMail($to_mail,$from_mail,$title,$body,$settings);
152 | }
153 | }
154 | //2.发送评论者邮件
155 | //判断是否为回复评论,是则发,否则跳。
156 | if (!empty($original)){
157 | $tempinfo['originalMail'] = $original['mail'];
158 | $tempinfo['originalText'] = $original['text'];
159 | $tempinfo['originalAuthor'] = $original['author'];
160 | if(in_array('to_guest', $settings->other) && 'approved'==$tempinfo['status'] && $tempinfo['originalMail']){
161 | $to_mail = $tempinfo['originalMail'];
162 | $from_mail = $settings->mailAddress;
163 | $title = self::_getTitle(true,$settings,$tempinfo);
164 | $body = self::_getHtml(true,$tempinfo);
165 | self::_sendMail($to_mail,$from_mail,$title,$body,$settings);
166 | }
167 | }
168 |
169 | }
170 | public static function _getTitle($toGuest,$settings,$tempinfo){
171 | //获取发送标题
172 | $title = '';
173 | if($toGuest){
174 | $title = $settings->titleForGuest;
175 | }else{
176 | $title = $title = $settings->titleForOwner;
177 | }
178 | return str_replace(array('{title}','{site}'), array($tempinfo['title'],$tempinfo['site']), $title);
179 | }
180 | public static function _getHtml($toGuest,$tempinfo){
181 | //获取发送模板
182 | $dir = dirname(__FILE__).'/';
183 | $time = date("Y-m-d H:i:s",$tempinfo['created']+$tempinfo['timezone']);
184 | $search=$replace=array();
185 | if($toGuest){
186 | $dir.='guest.html';
187 | $search = array('{site}','{siteUrl}', '{title}','{author_p}','{author}','{mail}','{permalink}','{text}','{text_p}','{time}');
188 | $replace = array($tempinfo['site'],$tempinfo['siteUrl'],$tempinfo['title'],$tempinfo['originalAuthor'],$tempinfo['author'], $tempinfo['mail'],$tempinfo['permalink'],$tempinfo['text'],$tempinfo['originalText'],$time);
189 | }else{
190 | $dir.='owner.html';
191 | $status = array(
192 | "approved" => '通过',
193 | "waiting" => '待审',
194 | "spam" => '垃圾'
195 | );
196 | $search = array('{site}','{siteUrl}', '{title}','{author}','{ip}','{mail}','{permalink}','{manage}','{text}','{time}','{status}');
197 | $replace = array($tempinfo['site'],$tempinfo['siteUrl'],$tempinfo['title'],$tempinfo['author'],$tempinfo['ip'],$tempinfo['mail'],$tempinfo['permalink'],$tempinfo['manage'],$tempinfo['text'],$time,$status[$tempinfo['status']]);
198 | }
199 | $html = file_get_contents($dir);
200 | return str_replace($search, $replace, $html);
201 | }
202 | public static function _sendMail($to_mail,$from_mail,$title,$body,$settings){
203 | //发送邮件
204 | //self::_log($to_mail,'debug');return;
205 | $api_key = $settings->key;
206 | $domain = $settings->domain;
207 | $from_mail = $settings->senderName.' <'.$from_mail.'>';
208 | $postData = array(
209 | 'from' => $from_mail,
210 | 'to' => $to_mail,
211 | 'subject' => $title,
212 | 'html' => $body,
213 | );
214 | $url = 'https://api.mailgun.net/v3/'.$domain.'/messages';
215 | $ch = curl_init();
216 | curl_setopt($ch, CURLOPT_USERPWD,'api:'.$api_key);
217 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
218 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
219 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
220 | curl_setopt($ch, CURLOPT_POST, true);
221 | curl_setopt($ch, CURLOPT_URL, $url);
222 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
223 | curl_setopt($ch, CURLOPT_HEADER, true);
224 | self::_log('curl prepareing...'.print_r(curl_getinfo($ch),1),'debug');
225 | $result = curl_exec($ch);
226 | self::_log('API return...'.$result,'debug');
227 | $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
228 | $result = substr($result, $headerSize);
229 | $res = json_decode($result,1);
230 | self::_log('curl excuted...'.print_r(curl_getinfo($ch),1),'debug');
231 | self::_log($to_mail.' '.'Sending: '.$res['message']);
232 | }
233 | public static function _log($msg,$file='error'){
234 | //记录日志
235 | $settings=Helper::options()->plugin('CommentMailPlus');
236 | if(!in_array('to_log', $settings->other)) return false;
237 | //开发者模式
238 | if($file=='debug' && true) return false;
239 | $filename = dirname(__FILE__).'/logs/'.$file.'_log.php';
240 | if(!is_file($filename)){
241 | file_put_contents($filename, '