这款插件是我找deepseek写的,主要功能是把typecho发布的内容自动同步到Memos上。应该是绝大部分博主都用不上,各取所需吧!也是想说,AI成熟了,我们每位都是程序员,都可以让AI写出自己想要的功能的代码!
一直以来,除老张博客外,还有一个后花园,老张随笔。老张随笔就是每天记一些点滴,发一点牢骚!字数都是在一两百字,到目前为止,也记录了近一千五百篇日志了。老张随笔最初选用的是较轻量的Typecho程序,后来Memos在博客圈流行的时候,老张随笔便换成了Memos程序,这样能更好的和五木大佬开发的哔哔广场融合。Typecho数据导入到Memos数据库中也非常的简单,这篇《简单几步,Typecho博客文章轻松导入到Memos》教程,便可以教大家很方便的把Typecho的文章导入到Memos中。Memos也使用了两三年吧,但是由于作者的任性更新,版本一直还停留在0.18.1上。加之大家对Memos热度的减少,现在玩Memos的人很少了,原来五木大佬的哔哔广场,每天都好几十条哔文,现在基本上很少有人发了。种种原因,老张随笔又换回了Typecho程序,但是老张又舍不得Memos,所以在Typecho上发布一篇文章后,便手动复制到Memos上,也算是做为备份吧!每天手动甚是麻烦,便有了这款Typecho插件-MemosSync,Memos同步插件。
插件功能特点:
-
✅ 文章发布时自动同步到Memos
-
✅ 支持将文章分类作为Memos标签
-
✅ 可配置可见性(公开/受保护/私有)
-
✅ 完整的错误处理,不影响文章发布
-
✅ 后台配置界面
安装和使用说明
1.安装插件
将下面的文件上传到 /usr/plugins/MemosSync/ 目录
在Typecho后台启用插件
2.配置插件:
进入插件设置页面
填写Memos地址(例如:https://memos.example.com)
输入Access Token(在Memos设置中生成)
选择可见性设置
启用同步功能
3.获取Access Token:
登录您的Memos实例
进入设置 → 权限 → Access Tokens
生成新的Token并复制到插件设置中
注意事项
-
确保您的Typecho服务器可以访问Memos实例
-
如果同步失败,会在Typecho日志中记录错误信息
-
标签会自动过滤特殊字符,只保留字母、数字、中文和下划线
插件结构
/usr/plugins/MemosSync/
├── Plugin.php ├── config.xml └── form.php
1. config.xml
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<name>MemosSync</name>
<description>将Typecho文章同步到Memos</description>
<author>Your Name</author>
<version>1.0.0</version>
<module>MemosSync</module>
</plugin>
2. form.php
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<h2>Memos 同步设置</h2>
<div class="typecho-page-title">
<h2>Memos 配置</h2>
</div>
<div class="typecho-option">
<label class="typecho-label" for="memos_url">Memos 地址</label>
<input type="text" class="text" name="memos_url" id="memos_url" value="<?php $this->options->memos_url(); ?>" />
<p class="description">请输入完整的Memos地址,例如:https://memos.example.com</p>
</div>
<div class="typecho-option">
<label class="typecho-label" for="memos_token">Access Token</label>
<input type="text" class="text" name="memos_token" id="memos_token" value="<?php $this->options->memos_token(); ?>" />
<p class="description">在Memos设置中生成的Access Token</p>
</div>
<div class="typecho-option">
<label class="typecho-label" for="memos_visibility">可见性</label>
<select name="memos_visibility" id="memos_visibility">
<option value="PUBLIC" <?php if($this->options->memos_visibility == 'PUBLIC') echo 'selected'; ?>>公开</option>
<option value="PROTECTED" <?php if($this->options->memos_visibility == 'PROTECTED') echo 'selected'; ?>>受保护</option>
<option value="PRIVATE" <?php if($this->options->memos_visibility == 'PRIVATE') echo 'selected'; ?>>私有</option>
</select>
<p class="description">选择同步到Memos的可见性设置</p>
</div>
<div class="typecho-option">
<label class="typecho-label">
<input type="checkbox" name="memos_enable_sync" value="1" <?php if($this->options->memos_enable_sync == '1') echo 'checked'; ?> />
启用同步功能
</label>
<p class="description">启用后,发布文章时会自动同步到Memos</p>
</div>
<div class="typecho-option">
<label class="typecho-label">
<input type="checkbox" name="memos_include_tags" value="1" <?php if($this->options->memos_include_tags == '1') echo 'checked'; ?> />
包含分类作为标签
</label>
<p class="description">将文章分类作为Memos的标签</p>
</div>
3. Plugin.php
<?php
/**
* MemosSync - Typecho文章同步到Memos插件
*
* @package MemosSync
* @author Your Name
* @version 1.0.0
* @link https://yourblog.com
*/
class MemosSync_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件
*/
public static function activate()
{
Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishPublish = array('MemosSync_Plugin', 'syncToMemos');
Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishSave = array('MemosSync_Plugin', 'syncToMemos');
return _t('插件已激活,请配置Memos设置');
}
/**
* 禁用插件
*/
public static function deactivate()
{
return _t('插件已禁用');
}
/**
* 插件配置面板
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
require_once 'form.php';
}
/**
* 个人用户的配置面板
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form) {}
/**
* 同步到Memos
*/
public static function syncToMemos($contents, $post)
{
// 获取插件配置
$options = Typecho_Widget::widget('Widget_Options');
$memosUrl = $options->plugin('MemosSync')->memos_url;
$memosToken = $options->plugin('MemosSync')->memos_token;
$memosVisibility = $options->plugin('MemosSync')->memos_visibility;
$enableSync = $options->plugin('MemosSync')->memos_enable_sync;
$includeTags = $options->plugin('MemosSync')->memos_include_tags;
// 检查是否启用同步
if (!$enableSync) {
return;
}
// 验证必要配置
if (empty($memosUrl) || empty($memosToken)) {
return;
}
try {
// 准备请求数据
$apiUrl = rtrim($memosUrl, '/') . '/api/v1/memos';
$content = $contents['text'];
// 如果启用了标签功能,获取分类作为标签
$tags = array();
if ($includeTags && isset($contents['category'])) {
$category = $contents['category'];
if (is_array($category)) {
$tags = $category;
} else {
$tags = array($category);
}
}
// 构建内容,包含标签
$memoContent = $content;
if (!empty($tags)) {
$tagString = '';
foreach ($tags as $tag) {
$tagString .= ' #' . self::formatTag($tag);
}
$memoContent .= "\n\n" . $tagString;
}
// 准备请求数据
$postData = array(
'content' => $memoContent,
'visibility' => $memosVisibility
);
// 发送请求到Memos
$http = Typecho_Http_Client::get();
if ($http) {
$http->setHeader('Authorization', 'Bearer ' . $memosToken)
->setHeader('Content-Type', 'application/json')
->setData(json_encode($postData))
->setTimeout(30)
->send($apiUrl);
$response = $http->getResponseBody();
$status = $http->getResponseStatus();
if ($status != 200) {
throw new Exception('Memos API 返回错误: ' . $status . ' - ' . $response);
}
}
} catch (Exception $e) {
// 记录错误日志,但不影响文章发布
Typecho_Log::write('MemosSync Error: ' . $e->getMessage(), Typecho_Log::WARN);
}
}
/**
* 格式化标签
*/
private static function formatTag($tag)
{
// 移除特殊字符,只保留字母、数字、中文、下划线
$tag = preg_replace('/[^\p{L}\p{N}_]/u', '', $tag);
return $tag;
}
}



相当实用的插件了