Skip to content

多元推送

你可以配置 admin_notify,让 ArtalkGo 以多种方式通知管理员。

支持 Telegram飞书钉钉BarkSlackLINE,并且多种方式可以同时启用。

完整的 admin_notify 配置如下:

点击显示
# 多元推送
admin_notify:
  # 通知模版
  notify_tpl: "default"
  noise_mode: false
  # 邮件通知管理员
  email:
    enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知
    mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复"
  # Telegram
  telegram:
    enabled: false
    api_token: ""
    receivers:
      - 7777777
  # 飞书
  lark:
    enabled: false
    webhook_url: ""
  # 钉钉
  ding_talk:
    enabled: false
    token: ""
    secret: ""
  # Bark
  bark:
    enabled: false
    server: "http://day.app/xxxxxxx/"
  # Slack
  slack:
    enabled: false
    oauth_token: ""
    receivers:
      - "CHANNEL_ID"
  # LINE
  line:
    enabled: false
    channel_secret: ""
    channel_access_token: ""
    receivers:
      - "USER_ID_1"
      - "GROUP_ID_1"
  # WebHook
  webhook:
    enabled: false
    url: ""
# 多元推送
admin_notify:
  # 通知模版
  notify_tpl: "default"
  noise_mode: false
  # 邮件通知管理员
  email:
    enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知
    mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复"
  # Telegram
  telegram:
    enabled: false
    api_token: ""
    receivers:
      - 7777777
  # 飞书
  lark:
    enabled: false
    webhook_url: ""
  # 钉钉
  ding_talk:
    enabled: false
    token: ""
    secret: ""
  # Bark
  bark:
    enabled: false
    server: "http://day.app/xxxxxxx/"
  # Slack
  slack:
    enabled: false
    oauth_token: ""
    receivers:
      - "CHANNEL_ID"
  # LINE
  line:
    enabled: false
    channel_secret: ""
    channel_access_token: ""
    receivers:
      - "USER_ID_1"
      - "GROUP_ID_1"
  # WebHook
  webhook:
    enabled: false
    url: ""

邮件通知

admin_notify:
  enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知
  mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复"
admin_notify:
  enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知
  mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复"

当使用其他推送方式时,可以关闭管理员邮件通知。

配置项 mail_subject 为发送给管理员的邮件标题。

在这之前,你需要配置全局邮件发送功能:参考此处

Telegram

admin_notify:
  # Telegram
  telegram:
    enabled: true
    api_token: ""
    receivers:
      - 7777777
admin_notify:
  # Telegram
  telegram:
    enabled: true
    api_token: ""
    receivers:
      - 7777777
  • api_token:TG Bot 的 API Token。
  • receivers:消息接受者的数字 ID,可设置多个。

创建 TG Bot

搜索 @BotFather 回复 /newbot 并按提示创建新的 TG 机器人。

标红的文字就是你之后需要在 ArtalkGo 配置中填入的 api_token

配置中的 receivers 填入需要接受消息的账号数字 ID,可以搜索机器人 @RawDataBot 获取如图:

详情可参考:“Bots: An introduction for developers - Telegram”

TIP

鉴于复杂的网络环境,如需使用代理,请在 ArtalkGo 启动之前配置环境变量,例如:

export https_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890

飞书

admin_notify:
  # 飞书
  lark:
    enabled: true
    webhook_url: ""
admin_notify:
  # 飞书
  lark:
    enabled: true
    webhook_url: ""
  • webhook_url:填入创建群组机器人时得到的 WebHook 地址。

创建群组机器人

点击顶部的加号,创建一个新的群组:

找到右侧的「群设置」-「群机器人」- 点击「添加机器人」- 选择「自定义机器人」并按照提示创建。

复制如上图的 WebHook 地址,并修改 ArtalkGo 的 webhook_url 配置即可。

可参考:“飞书帮助中心文档”

钉钉

admin_notify:
  # 钉钉
  ding_talk:
    enabled: true
    token: ""
    secret: ""
admin_notify:
  # 钉钉
  ding_talk:
    enabled: true
    token: ""
    secret: ""

可参考:“钉钉开放文档”

Bark

admin_notify:
  # Bark
  bark:
    enabled: true
    server: "http://day.app/xxxxxxx/"
admin_notify:
  # Bark
  bark:
    enabled: true
    server: "http://day.app/xxxxxxx/"

Bark 是一款开源的 iOS App,并且支持自托管,你能使用 Bark 轻松地推送消息给你的 iOS 设备。

你可以在 App Store 搜索下载,并获得需要填入 ArtalkGo 的 server 配置项:

Slack

admin_notify:
  # Slack
  slack:
    enabled: true
    oauth_token: ""
    receivers:
      - "CHANNEL_ID"
admin_notify:
  # Slack
  slack:
    enabled: true
    oauth_token: ""
    receivers:
      - "CHANNEL_ID"

LINE

admin_notify:
  # LINE
  line:
    enabled: true
    channel_secret: ""
    channel_access_token: ""
    receivers:
      - "USER_ID_1"
      - "GROUP_ID_1"
admin_notify:
  # LINE
  line:
    enabled: true
    channel_secret: ""
    channel_access_token: ""
    receivers:
      - "USER_ID_1"
      - "GROUP_ID_1"

通知模版

admin_notify:
  notify_tpl: "default"
admin_notify:
  notify_tpl: "default"

配置项 admin_notify.notify_tpl 可设置为自定义通知模版「文件路径」,默认的通知模版为:

@{{reply_nick}}:

{{reply_content}}

{{link_to_reply}}
@{{reply_nick}}:

{{reply_content}}

{{link_to_reply}}

可用变量和邮件模板相同,可参考:“邮件模版”

嘈杂模式 noise_mode

admin_notify:
  noise_mode: false
admin_notify:
  noise_mode: false

noise_mode 默认为关闭状态,当该项设置为 false 时,站内仅向管理员回复的消息会发送通知,例如「普通用户 A」回复「普通用户 B」,这两个用户之间的通讯不会通知管理员。

注:当 moderator.pending_defaulttrue 时,noise_mode 为始终开启状态。

WebHook 回调

开启 WebHook 后,创建新评论将以 POST 方式携带 application/json 类型的 Body 数据请求设定的 WebHook 地址。

你可以编写自己的 Server 端代码,处理来自 ArtalkGo 的请求。

ArtalkGo 配置文件

admin_notify:
    webhook:
      enabled: true
      url: "http://localhost:8080/"
admin_notify:
    webhook:
      enabled: true
      url: "http://localhost:8080/"

Body 数据内容

application/json 类型

Key描述类型备注
notify_subject通知标题String对应 admin_notify.notify_subject 配置项
notify_body通知内容String根据 admin_notify.notify_tpl 模版渲染
comment评论内容Object新创建的评论数据对象
parent_comment评论回复的目标ObjectRoot 根节点评论类型改项为 null

Body 数据样本

{
  "notify_subject": "",
  "notify_body": "@测试用户:\n\n测试内容\n\nhttps://127.0.0.1/index.html?atk_comment=1057",
  "comment": {
    "id": 1057,
    "content": "测试内容",
    "user_id": 226,
    "nick": "测试用户",
    "email_encrypted": "654236c1e78i4c09a17c4869c9d43910",
    "link": "https://qwqaq.com",
    "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_4_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36",
    "date": "2022-05-23 17:00:23",
    "is_collapsed": false,
    "is_pending": false,
    "is_pinned": false,
    "is_allow_reply": false,
    "rid": 0,
    "badge_name": "",
    "badge_color": "",
    "visible": true,
    "vote_up": 0,
    "vote_down": 0,
    "page_key": "/index.html",
    "page_url": "https://127.0.0.1/index.html",
    "site_name": "ArtalkDocs"
  },
  "parent_comment": null
}
{
  "notify_subject": "",
  "notify_body": "@测试用户:\n\n测试内容\n\nhttps://127.0.0.1/index.html?atk_comment=1057",
  "comment": {
    "id": 1057,
    "content": "测试内容",
    "user_id": 226,
    "nick": "测试用户",
    "email_encrypted": "654236c1e78i4c09a17c4869c9d43910",
    "link": "https://qwqaq.com",
    "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_4_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36",
    "date": "2022-05-23 17:00:23",
    "is_collapsed": false,
    "is_pending": false,
    "is_pinned": false,
    "is_allow_reply": false,
    "rid": 0,
    "badge_name": "",
    "badge_color": "",
    "visible": true,
    "vote_up": 0,
    "vote_down": 0,
    "page_key": "/index.html",
    "page_url": "https://127.0.0.1/index.html",
    "site_name": "ArtalkDocs"
  },
  "parent_comment": null
}

Node.js express 处理示例

const express = require('express');

const app = express();

app.use(express.json()); // Use JSON middleware

app.post('/', function(request, response){
  console.log(request.body);

  const notifySubject = request.body.notify_subject
  const notifyBody    = request.body.notify_body
  console.log(notifySubject, notifyBody);

  response.send(request.body);
});

app.listen(8080);
const express = require('express');

const app = express();

app.use(express.json()); // Use JSON middleware

app.post('/', function(request, response){
  console.log(request.body);

  const notifySubject = request.body.notify_subject
  const notifyBody    = request.body.notify_body
  console.log(notifySubject, notifyBody);

  response.send(request.body);
});

app.listen(8080);

Node.js http 处理示例

const http = require("http");

const requestListener = function (req, res) {
  // receive json request
  let body = "";
  req.on("data", function (data) {
    body += data;
  });
  req.on("end", function () {
    let json = "";
    try {
      json = JSON.parse(body);
    } catch {}

    // do something with json
    console.log(json);
    res.end();
  });

  res.writeHead(200);
  res.end("Hello, World!");
};

const server = http.createServer(requestListener);
server.listen(8080);
const http = require("http");

const requestListener = function (req, res) {
  // receive json request
  let body = "";
  req.on("data", function (data) {
    body += data;
  });
  req.on("end", function () {
    let json = "";
    try {
      json = JSON.parse(body);
    } catch {}

    // do something with json
    console.log(json);
    res.end();
  });

  res.writeHead(200);
  res.end("Hello, World!");
};

const server = http.createServer(requestListener);
server.listen(8080);

PHP Laravel 处理示例

Route::get('/', function (Request $request) {
    $data = $request->json()->all();
    $notify_subject = $data["notify_subject"];
    $notify_body    = $data["notify_body"];
});
Route::get('/', function (Request $request) {
    $data = $request->json()->all();
    $notify_subject = $data["notify_subject"];
    $notify_body    = $data["notify_body"];
});

Golang net/http 处理示例

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type ArtalkGoNotify struct {
	NotifySubject string      `json:"notify_subject"`
	NotifyBody    string      `json:"notify_body"`
	Comment       interface{} `json:"comment"`
	ParentComment interface{} `json:"parent_comment"`
}

func webhookHandler(rw http.ResponseWriter, req *http.Request) {
    decoder := json.NewDecoder(req.Body)
    var notify ArtalkGoNotify
    err := decoder.Decode(&notify)
    if err != nil {
        panic(err)
    }
    log.Println(notify.NotifyBody)
}

func main() {
    http.HandleFunc("/webhook", webhookHandler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}
package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type ArtalkGoNotify struct {
	NotifySubject string      `json:"notify_subject"`
	NotifyBody    string      `json:"notify_body"`
	Comment       interface{} `json:"comment"`
	ParentComment interface{} `json:"parent_comment"`
}

func webhookHandler(rw http.ResponseWriter, req *http.Request) {
    decoder := json.NewDecoder(req.Body)
    var notify ArtalkGoNotify
    err := decoder.Decode(&notify)
    if err != nil {
        panic(err)
    }
    log.Println(notify.NotifyBody)
}

func main() {
    http.HandleFunc("/webhook", webhookHandler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}