ctBridgeBot Wiki (Lite)

Eddy Lv2

本程序助您桥接TelegramWeChat、互通消息,且提供最大化的自定义性!

一. 部署指南

1. 获取代码

1/1. Docker方式(一般推荐)

在安装了GNU/Linux的机器上,我们推荐使用Docker以快速启动 (bootstrap) 本项目。对于该版本,您只需操作一个文件夹——data。您需要手动管理该文件夹,而其余文件将由Docker镜像管理。

  1. 首先请在您的设备上寻找合适的地方,存放程序配置文件(程序将会频繁读取,但是数据量不大,推荐放在SSD上),此处假设存放在 /opt/data_ct下 ;

  2. 运行下列命令 ,静待镜像下载完成后,容器即会立刻启动;

docker run -v /opt/data_ct:/bot/data --name ct cryan2409/ctbr

意为:将宿主机 /opt/data_ct 文件夹映射到容器内的 /bot/data 下;将新容器命名为ct;采用Docker Hub的 cryan2409/ctbr 镜像。

  1. 此后,由于data文件夹下找不到有效的配置文件,自检失败,容器将停止运行。请按照后续步骤,手动前往配置目录、修改模板文件,即可再次尝试启动容器。
  2. 待容器成功启动后,请通过docker logs ct命令查看容器日志,以便扫描二维码并登录。

1/2. 手动部署(适合高级用户)

本方法需要您的机器上安装有Node.js运行环境,若无可以前往 Node.js 官网 手动下载安装,推荐选择LTS版。请注意,Windows 7 所能安装的最新Node版本12.16仍无法满足依赖项的要求,请谨慎部署,或考虑借助Linux虚拟机。

  1. GitHub Release下载最新版源码压缩包,解压到合适位置,记为项目根目录;
  2. 在项目根目录打开终端/命令提示符,输入 npm i,安装依赖项;(若此步出现问题,请检查您的网络/科学上网情况;如果多次重试仍无法完成安装,请向我索要包含了node_modules的分发包)
  3. 按照后续步骤,修改配置文件以及proxy后,在终端输入npm run pnpm start,运行代码,等待二维码出现后扫码登录。

​ 提示:Docker版中,程序将会自动创建需要的模板文件;所以为了节省您的时间,我们编写了两个脚本,2.entry.sh用于 *NIX系统,以及init-project.bat用于Windows系统,这两个文件可以在static文件夹内找到。运行它们时,会在data目录下创建程序所需的两个配置文件的模板 {CHANGE_ME)user.conf.jsproxy.js},稍后只需对它们做出修改即可。

2. 配置环境

本项目有以下两点需要用户注意,其一是代理地址,其二为用户级配置文件。

请进入data文件夹,首先编辑proxy.js,该文件指示程序如何连接到Telegram服务器。其已经内置部分HTTP代理地址和端口的示例,请据此修改字符串为合适的值;其中IP地址可以不做改动,端口视您所用的科学上网软件而定,需要http代理端口或mixed端口。

如果没找到该文件,可以手动将下述内容填入文件:

1
2
3
4
5
6
7
8
9
// This is a device-specific proxy setting, which is used to bypass the firewall.
// When updating the code, you could make no change to this file.
// =====================================================================

// Please write your HTTP proxy with patterns below, eg. NekoRay
// module.exports = "http://127.0.0.1:7080" ;

// Or, If you don't want to use proxy at all, just keep empty:
module.exports = "" ;

其次,CHANGE_ME)user.conf.js表示这是等待用户修改的配置文件,请首先依据 {3. 初始化配置文件} 编辑该文件(填入必要的凭据以及设置),然后将其改名为user.conf.js

3. 初始化配置文件

本程序的配置文件采用“叠加”制,即config/def.conf.js文件包含所有的配置项及其默认值,并在版本更新时被覆盖;而data/user.conf.js包含用户修改过的各配置项,因此只需为def配置的子集,无需包含前者中所有配置项;在启动时程序会先加载def配置文件,然后将user中的配置逐条覆盖,因此若需要修改任何配置项,请在复制到user配置文件后再做出修改。

对于想要bootstrap本项目的用户,您既可以从完整的配置文件开始,精简任何您未作出更改的配置项(user.conf.js中的内容可以基于def.conf.js,或是由初始化脚本创建的“CHANGE ME“文件);也可以从最少配置文件minimum_user.conf.js开始,添加您所需要的配置项。

以下提供了一些必需配置项的解释,大体按照重要程度排序,并且基于此版本(v3.5.0)所附带def.conf.js,仅供参考。若在后续版本中有增加的配置项但本文档未及时更新,请参考def.conf.js中所附的英文注释或耐心等待文档更新;在此版块未涉及的配置项,请前往 {配置文件参考} 专题查阅,谢谢。

#接下来请按步骤操作,分别填充配置文件的各项。(1、2、3、6为必选项,其余为可选项)

  1. /tgbot/botToken 改成您创建的Telegram Bot 的访问 token;

    /tgbot/botName 改成该Bot的用户名,此举是为了处理用户发送的带有机器人用户名的聊天指令。

    提示/tgbot/botToken这一表示方法指,从module.exports开始,首先寻找名为tgbot的对象,再其内继续寻找botToken,而开头/的含义类似绝对路径与相对路径,下同。

    如果您未曾创建过bot,那么请按照以下步骤操作:
    在Telegram主页搜索botfather,点击Menu按钮选择/newbot,然后分别在聊天区输入Bot的显示名称、Bot用户名(以_bot结尾),即可在收到的回复的中间部分找到Bot Token.
    请注意,在运行本项目前,务必点击由BotFather发送的、您机器人的链接,打开与机器人的聊天窗口,再点击下方的Start按钮,才能允许机器人向您发送消息!
    格式如下:6000000004:AA..(Skip 32 chars)..A

  2. /tgbot/tgAllowList规定机器人将对哪些用户的消息做出转发或回应,若不在此列表,发出的消息将会被忽略。请向该数组中添加您自己的Telegram ID,以数字形式、无需引号;

  3. /class/def,即 默认频道的相关配置,请将tgid改为您的Telegram ID / 群id;(默认频道者,也就是不满足任何一条配置规则的其他所有消息都会被递送/转发到这里)

    关于简称

    在下文中,可能会把 ”启用了Topic功能的某个超级群组中的某个Thread/topic“ 简写为”某个thread/线程/topic“,将这样的超级群简称为”话题群“;
    也可能会混用”递送“与”转发“:这两个词均表示本程序把一个平台上的消息搬运到另一平台这一行为(一般指从wx到tg)

    提示:由于设计问题,本条目暂不支持设置为超级群组中的某个线程Thread,若强行设定到话题群的General线程,那么会出现异常行为,请注意!

    个人Telegram ID获取方法:
    在主界面搜索raw_info_bot,点击开始,第一行的输出即为所求;
    群的创建及获取id的方法:
    首先新建群聊,名称随意填写,然后将您的Bot拉入此群(可能必须在搜索框输入bot的用户名才能看到bot),再在群管理设置中选择Administrator菜单,将Bot提升为管理员,并把倒数第二个开关Remain Anonymous打开,保存后等待1s,向群聊发送任意一条消息,对其右键即会出现Copy Message Link选项,点击复制并粘贴,其数据形似:https://t.me/c/1954444465/2,此时请提取中间部分的整数,再在其之前附加-100,得到类似-1001954444465这样的数,即为此群的id.

  4. /ctToken:由于24年3月9日的一项举措,在本项目代码开源后,启用了这样一个配置项作为捐赠者识别凭证,如果您尚未成为捐助者,也可以前往 此网站 注册试用版token,以字符串形式填到这里即可。

关于 ctToken 的相关说明

获取方式:①若您此前已经支持过本人,那么请劳驾前往爱发电平台(传送门: 商品链接 )私信中查收我已为您生成的赞助版Token(其实也可以选择在tg上联络我,效果一样);

②若您只想试用本程序或者暂时不想支持,那么请前往 此网站 (https://ctbr.ryancc.top/startTrial) 自行生成试用版ctToken,生成时只需填写 您想要注册为token的字符串 和 联系方式(选填) 再提交即可,也无次数限制,因此可放心使用(因此希望各位切勿滥用该生成器,一人一次即可,网安高手们也不要尝试发掘我这破页面上的漏洞,我并没有使用任何SQL)

当您完成以上步骤得到token后,请将token填入您的 user.conf.js 首部对应区域即可。本程序在微信登录成功后将会把token,微信昵称(并非微信号,不具备定位到个人的效力)以及客户端版本号 发往服务器,仅用作统计与分析程序使用情况,因此请放心。在我看来并不会泄露使用者的隐私,若您不同意可自行删除相关代码。

[ 同时这一代码可能会在适当的时间点,于控制台中输出捐赠提示文字,不会影响其他功能的正常使用,请忽略。]

此外程序中的一些 耗费作者大量精力的功能在未来也会调整为仅限捐助者使用,请谅解。(目前仅有 tg大会员emoji转wx原生表情 这一项为专有功能,其余功能均不受限)

  1. /misc/deliverPushMessage,指示了订阅号推送以及服务消息应当如何被递送/转发。

    • 若设置为 false,则程序将忽略所有的公众号消息;
    • 若设置为 true,则这些消息将被发送到特定的聊天。可参考第3步操作,专门新建一个群并把id填入/class/push/tgid,但如果懒得建群的话,也可暂时性的设置为您的Telegram ID。
  2. /filtering/wxNameFilterStrategy:您可以在此,让本程序选择性地忽略部分聊天对象发来的所有消息,比如不得不加但不关心其内容的某些wx群,减少程序运行压力。

    欲使用该功能,请先决定您需要指定的是黑名单还是白名单,据此设置./useBlackList为true或false,同一时刻只有一个名单会生效;
    然后请在下方对应名单对应的数组里,以字符串形式追加关键词,结果类似这样即可:blackList: ["美团","饿了么"],

  3. /notification:Bark推送的相关设置项,本质是在程序出现问题(例如在连接tg服务器的过程中多次中断)需要用户介入时,向一个指定URL发送GET请求,后者会向用户个人手机发送推送通知以吸引您的注意力;后续正在考虑建立第三方bot,以期通过tg推送这样的消息;如不使用相关功能,请保持默认设置不变,理论上将不会再产生与此有关的报错。

    send_relogin_via_tg指示在使用/relogin命令时,是否要把wx登录二维码发送到默认频道以供扫描。默认为开,若想关闭请将其设为0.

  4. /misc/deliverSticker,决定了聊天消息中遇到wx用户发送的Sticker贴纸将如何递送。

    • 若设置为 false,则程序将忽略所有的sticker,仅在日志中输出提示信息,在tg侧将表现为对方未发送此消息;

    • 若设置为 true,则这些sticker将被发送到特定的聊天。建议另建一群,覆盖tgid值并删除threadId项,避免干扰正常聊天消息;当然也可指定到某thread中。

    • ./urlPrefix项旨在让用户点击sticker文字链接后可以直接跳转到sticker频道的对应消息,以便查看对方发送了何种表情,但这一功能需要略为复杂的调试。示例为https://t.me/c/1944700018/1411/",具体解析法请见第三步注释。若您未使用话题群,那么该prefix应当只包含一个数字,否则加上threadId应当如示例所示拥有两串数字。最后请以/结尾,因为程序还需要在该prefix的末尾追加sticker图片所在的消息id。

    在此,您可以考虑新建一个超级群并开启Topic功能,这样一个群可当多个群使用,从而节省您tg聊天列表的空间,具体方法如下:
    首先新建群,按照上文方法添加机器人,然后在群设置开启Topic功能,随后新建话题,名称随意起,在新话题中发送消息并复制链接,类似https://t.me/c/1788888875/4/401,取其中第二组数字4,即为threadId

    恭喜🎉

    至此您已经完成了所有的必需设置,现在运行程序应当不会再出现问题。不过为了更好的体验,我们推荐继续按照下列步骤,完成一些影响体验的可选配置。)

  5. /class/C2C,建议您启用C2C功能,并创建多个C2C Pair,这将会大幅提升您在tg侧的聊天体验,同时善用此功能也能让您创建更少的群,节省精力。对于每个C2C Pair,即/class/C2C/*

    • tgid数值参考前述步骤,同时如果指定到话题群,那么请设置threadId为话题号;

    • wx数组的第一项是您期望聊天对象的名字(微信昵称/群名称/您自行设置的备注都可以,我们会按照此顺序依次查找),第二项是isGroup,请根据聊天对象是否为群聊自行填入truefalse

/class/C2C_generator是为了进一步节省您精力而增设的,提供了为同一话题群中的不同话题添加对应的C2C Pair的快捷方法。(比如我个人就创建了一个话题群“From WX”,最常用联系人单独创建群,因为这样可以独立设置头像、显示名称;而次常用的联系人全部作为该话题群的子话题,方便管理。)
请先算出您话题群的tgid,即-100开头的形式,作为键,而值为一个空数组;然后在后者数组中添加数个长度为3或4的子数组,从左到右分别是,threadId,wx名称,wx类型,flag。并请保留/* |autoCreateTopic Anchor| */这一注释,其被后续的/create_topic指令需要。按照上文操作后,结果应为:

“C2C_generator”: {
“-1001888888888”: [
/* |autoCreateTopic Anchor| */
[1, “name of group 1”, “Group”, “flags_here”],
[4, “name of person 1”, “Person”, “”],
],
},

  1. /filtering/wxContentReplaceList,如字面意思,wx中收到的消息会经此表过滤后再转发到tg。示例中的写法会将微信中的部分自带表情如发怒、捂脸等替换为(通用的)emoji,如果您不想在输出消息中看到emoji可以清空该数组;

请注意如果您登录微信的手机语言为中文,可能还需要另外将 [Pout] [Facepalm] 等英文描述替换为 [发怒] [捂脸]等中文描述,此外还有[BadLuck]=[骷髅]等对应关系,我们暂未添加,未来将推出列表供用户自行选择;
由于我们从上游服务器接收的就是中英文混搭的版本,因此此项的设置取决于您手机语言,后续会改进……

[ This section is recently updated on 2024-05-16. ]

二. 使用教程

1. 启动流程

启动程序后,稍等片刻,程序将检查data目录下是否有ctbridgebot.memory-card.json文件,若有则尝试使用上次的登录信息直接登录,一般能在数秒内完成;如果登录失效了或无登录会话信息,则会在控制台输出一幅二维码和二维码图片链接。手机扫码之后完成登录,日志输出形如I/wx Contact<your_name>已登录.

a)复制”二维码图片链接”到浏览器,可以输出一张二维码图片在浏览器以供手机扫描;
b)请注意,由于微信官方的迷之限制,登录二维码在手机上无法使用非摄像头以外的任何形式识别。也就是说,无论是从相册选取二维码还是在聊天中长按图片识别二维码都无法完成登录(显示二维码失效)因此您可能必须使用两台设备才能完成登录。因此建议不要在不方便的场合通过远程手段重启本项目,以免登录失效却又无法重新登录。
c)由于需要在后台启动一个浏览器进程,所以启动阶段花费的时间在10s-30s不等。为了追踪启动过程所耗时间,启动浏览器所需时间将会输出在第一条日志旁,该时间介于2s-15s不等,视设备性能而定。
d)如果在微信登录消息之前输出了红色的如下内容(Unhandled rejection RequestError: Error: Client network socket disconnected before secure TLS connection was established),说明代理服务器连接出现问题,请查看代理服务器设置;
若输出的错误信息如下(Error: net::ERR_TIMED_OUT at https://wx2.qq.com?lang=zh_CN&target=t)则说明您设备的网络出现问题,无法连接到微信服务器。请即刻停止运行,排除网络问题后重启,可首先检查设备DNS是否异常。
e)如果弹出微信登录二维码后您在30s内未处理,则会通过配置文件/notification/prompt_relogin_required项向手机发送重登录提示(内容可自定义),届时请及时处理,以免漏收消息。
f)如果程序运行中出现日志信息[ERR] Polling - EFATAL: Client network socket disconnected before secure TLS connection was established表明最近一次向tg服务器的poll操作(拉取用户发送的消息)失败,意味着您代理服务器出现网络波动;如果出现频率较低(如30s一次)则不会产生太大影响,但是还是建议切换到更好的代理/节点;如果在10s内连续出现两次,则程序会按照配置文件prompt_network_problematic项向手机发送断网提示,这种情况下若不及时处理可能会影响消息递送的及时性甚至漏收消息等。
(有些科学上网节点提供商限制同时在线设备数,也就是同时运行的客户端数量,所以当您网络出现异常时除了切换节点也可考虑排查 是否超出了在线设备限制

2. 接收wx消息

程序运行后,您微信上的所有消息即会按照配置文件中所定义的,通过本程序“递送”到Telegram。

a.文字消息及合并

归属于默认频道(参考部署指南.3)的文字消息,根据是否来自群,有以下两种显示形式:📨[#备注名] <消息内容> / 📬[说话者微信昵称/#群名称] <消息内容>

请注意,本项目并不会查询某聊天对象在微信中是否已经设为免打扰状态,换言之,您必须 在配置文件中指定黑/白名单才能按您的需求屏蔽某些来源的消息。

“合并消息“功能打开时(默认打开),依据配置文件中设定的时间间隔,当新消息与上一条消息的时间之差不超过设定值时,新消息将会被附加到旧消息的末尾,并且对旧消息的格式作出相应修改以提升观感。
例如聊天对象是某联系人A,间隔默认为15s,若他的第二条消息内容为2且在上一条消息15s内发出,则上一条消息从 📨[#联系人A] 1 变为 如下,也就是在保留首部标题与联系人信息的同时,将他的所有新消息前加上时间或序号(均可自定义)。

📨⛓️ [#联系人A] - - - -
[13:35:35] 1
2|→ 2nd msg
3|→ 3rd msg

若聊天对象是群聊,程序会舍弃时间显示,改为在 [ ] 内显示说话者名称,并将首部标题内符号‘📨’替换为‘📬’。

此外,当[ ] 内容一致时(例如群内同一说话者连续三条消息且未被其他人打断,或某联系人在1s内发送多条消息),程序不会在新消息中显示[ ] ,反而是采用等宽字体显示其计数(如2|→)。这可以表明该说话者连发了多少条消息。此项可在配置文件中/c11n/titleForSameTalkerInMergedRoomMsg中自定义。

请注意,此合并功能目前仍是全局共享,也就是说如果您有两个以上的群会经常输出消息,那么合并功能将经常被打断(因为第二个群合并的过程中第一个群的新消息会打断这一过程,并重置记忆,导致第二个群的新消息将无法再被合并)。我们正在尝试重写这部分代码以使“合并”功能的行为更加符合预期。

b. 图片/文件/视频 多媒体消息

  • 图片消息将会先被下载到/downloaded/photo中,以${消息发出者alias}-${wxdata.filename}形式保存,再发送到其对应的接收对象中,并且这些图片的标题(caption,即图片下方出现的文字)显示为 ‘ from 发送者名称 ’(规则同上述a,根据是否为群/是否为C2C拥有不同行为)
  • 对于文件消息,将先向您发送一条提示,包含该文件的发送者、原始文件名和大小。形如:📨[#联系人] 📎[文件.docx], 0.101MB.
    • 若大小满足配置文件中wxAutoDownloadThreshold项设置的最小阈值,则会自动尝试下载并显示Trying download as size is smaller than threshold.,在下载完后将删除原先的提示信息。
    • 若大小大于上述阈值,则显示Send a single OK to retrieve that. 此时如果您仍希望接收此文件,则需对此提示消息点击回复,并发送OK(全大写或全小写均可),此后文件将会在后台下载并遵循上述步骤发送到tg。
  • 对于视频消息,由于微信某次更新取消了视频大小的显示,故软件只能自动下载。在🎦(Downloading...)提示出现后,请耐心等待,视频正在后台下载并发送到tg,其中大小大于49MB的将不会被发送;反之则会即时发送。(经测试,此过程主要取决于科学上网的速度。)

c. 推送消息

所有的公众号文章消息(是否收到来自某公众号的推送消息,取决于是否在微信设置中选择“接收文章”/“Receive Articles”)都会被handlePushMessage()处理成富文本形式发送到配置文件中/class/push指定的push频道。具体格式包含订阅号名称(标题上带有#号以便快捷查找其所有文章),每篇文章的标题(点击标题则打开链接)及其简介(取决于公众号运营者的填写,或长或短,甚至没有;以斜体展示)。

点击链接后可在任意浏览器查看,但无法查看评论(微信侧限制,非登录用户无法查看评论)

d. 语音消息

语音消息同样会被先下载到/downloaded/audio中,以日期-时间-备注名.mp3形式保存。

如果在配置文件中开启了语音识别功能/txyun并提供了有效的API Key,则

  • 每条语音在进一步发送前都会先发往腾讯云“一句话识别”系统(该系统能在数秒内给出语音转文字结果,支持多种方言且最大长度为60s,刚好满足最大长度为60s的语音这一情况),得到转录文字后附加到语音消息的caption部分,发送到tg。但请注意,由于tg app的限制,手机端在通知消息预览中无法看到已转出文字的内容,只显示🎤 Voice Message,此时您需要点击通知进入app才能看到转文字内容。
  • 否则,caption部分将只包含说话者信息。

e. 文字中包含的引用消息

在UOS版本微信,如果对端给您发来带有引用消息的消息,那么默认会显示为如下;很明显观感很差且占用过多行。假如我们试图把这样的引用表现为tg消息间的互相回复的话,不仅与“合并”功能冲突,且技术难度较大,需要把所有历史消息都存入数据库才能做到,同时也造成很多不便。因此我们做了这样的特殊处理,也就是将此部分转换为消息末尾的一行斜体小字(说话者💬"内容"),这样就可以清晰地表示消息间引用关系。其中“内容”部分是被引用消息的内容的前8个字符,您可以根据该前缀向上搜索找到对应的原消息,至于“说话者”是该用户的昵称还是群名片,这一项由微信侧决定,一般情况下是后者。

“说话者A: 第一条消息”
— — — — — — — — — —
第二条消息

3. 在tg上发送消息

不仅是wx侧,本项目在tg侧也拥有良好的操作性,支持多种消息格式与指令。

提示

本文档初次撰写时,C2C尚未发展完全,仍以def频道为主,而在后续开发中,各项功能均向利好C2C的方向发展,因此此处介绍的很多指令,比如查找和锁定功能,实际用处并不大。我们也推荐用户多使用C2C与/create_topic指令(将def频道中的聊天对象自动转换到C2C),这样便可以为每个聊天定义更加详细的规则,以增强聊天体验。

a. 支持的消息种类

(以/class/def频道举例)

  • 文字消息,将会经tgContentReplaceList过滤后,直接发送给“上一个聊天对象”,若无上次聊天的记录则会发出提醒,Nothing to do upon your message,这时这条消息将会被忽略。

“上一个聊天对象”,代码中为lastTalker,指代def频道中上次收到消息的对象,若无已启用的/lock,则def频道中每收到一条消息,lastTalker都会被更新。

​ 如果这条消息是对另一条消息的回复,则这条消息会被直接发送到“被回复的消息”的发送者处。

​ (例:我的“上一个聊天对象”是B,但我对“A”发给我的消息选择了“回复”,并且输入了我想说的话,那么这时这条消息会被发送给A而非B。)

  • 图片/文件/视频消息,将会被下载到本地后再发送给“上一个聊天对象”,所以如果需要准确地发送给某个人(以免在发送过程中有其他人的消息插入导致消息被错发),请利用c)节提到的lock功能确定您想要发送的对象。

  • 语音消息 和 Sticker(贴纸)消息,请详见d节介绍。

    除了上述种类以外,其他所有的消息都会被忽略,包括但不限于tg侧的群名称/头像更改事件、投票、在移动端通过长按语音按钮拍摄的VideoNote……但会在日志中体现。

b. 使用预定义的指令

(现有的博客系统的目录不支持h4标题,为了方便用户点击目录跳转,该部分已移动为单独的一小节,请前往下方 {tg侧指令一览} 查阅 )

c. 查找、行内查找与相关指令

  • 本程序支持交互式查找聊天对象,具体方法是直接发送/find指令,在得到程序反馈Entering find mode; enter token to find it.后,直接输入您想要查找的对象的微信昵称/群名称/您设置的备注,(由于UOS微信的限制,完成此步骤需要数秒)在查找成功后将会回复消息Found Person: name=……,此时若“聊天对象”锁未启用,则“上一个聊天对象”也会被设置成当前查找到的目标。

    (在未来的升级中,此项可能升级为模糊查找,即列出联系人列表并尝试在其中模糊查找,给可能匹配的每一位都分配上唯一id,并将后者返回到用户侧,这样做可以避免名称中出现非法字符等等)

  • “行内查找”指的是,当需要向一位新的聊天对象发送消息时,将查找和发送两步合并到一条消息内完成。具体操作方法是,首先输入查找对象的名称(“微信昵称/群名称/您设置的备注”三种情况均可接受,详见上文),紧随其后输入两个冒号,中英文均可;接下来请换行后直接输入您要发送的消息,最后发送即可。当您看到聊天界面顶部显示机器人的状态从“typing”变为“choosing sticker”则表示查找并发送成功。

    本功能的原理是先调用查找函数找到您欲发送消息的唯一对象,将其设为“上一个聊天对象”后按照正常消息的步骤再发送给目标。因此当“聊天对象”锁已启用时,本功能可能无法正常工作。(这也是一个问题,将在以后的更新中修复【TODO】)

  • 另外,您可以通过“@锁”方式,灵活地设置当前的聊天对象。例如,当您一时间收到来自两个联系人的多条消息时,为了避免互相干扰,您可以先选中其中一位的消息,回复它“@”,此时该联系人会被设置为“上一个聊天对象”且“聊天对象”锁也会被启用(并设为2状态),接下来您直接发送的所有消息都会被转发到该联系人。此后,只需选择另一位联系人的消息并同样回复“@”,即可专心回复ta的消息。并且通过这种方式设置的锁,在您“回复”其他消息时会自动解除。

d. Sticker与语音识别

  • 语音消息,如果腾讯云语音识别已启用,则程序会输出您这段语音的识别结果并设置为monospace样式,此时您可以点击文字部分自动复制语音识别后的结果。但是,这条语音并不会被转发到wx。

  • 对于来自tg的Sticker(贴纸)消息,按照默认配置,此贴纸将会取缩略图后由sharp库 转换为gif,以图片形式发往wx。根据配置的不同,也可能通过upyun(又拍云)实现图片格式的转换。

    a)由于tg的贴纸要求为webp格式,而wx不支持前者,所以需要设法转换之。已知又拍云提供简单的方案(指不需要通过事件id和查询请求确定转换状态)可以完成上述操作,因此需要您提供此upyun API Key。 经热心用户提醒,sharp库利用libvips可以高效地实现图片格式的转换,因此为了降低用户使用成本,我们已将默认配置改为sharp方案,若未出现问题则不需要调整此选项。
    b)请注意,目前您的所有媒体消息中携带的caption都不会被递送。因此,请不要在媒体消息的caption中填写您想要传达的讯息,因为您可能需要复制后以纯文本形式单独发送。这一问题日后将会被解决。【TODO】
    c)如果您购买了Telegram Premium并发送了第三方emoji表情,那么它将会被解析成普通emoji(这一行为取决于emoji上传者为其设定的替代emoji是哪一个)并发送。所以如果想要发送微信原生emoji,您将需要利用此项tgContentReplaceList达到目的。 作为大会员用户的替代方案,请添加 这个Emoji Pack ,然后便可在聊天中随意使用其中的表情,均会被正确识别。

e.机器人行为的指示

​ 本节将介绍,在您的特定行为下,机器人将会更新自己的chatAction到何种状态,以便您无需查看日志即可确定消息是否被成功转发,或者了解程序是否正在处理消息。

Telegram Bot API中的 sendChatAction 方法允许开发者把机器人端正在发生的事,以“正在输入状态”的形式告诉用户。

  • 当您从tg侧发送文字消息时,机器人状态将在发送后变为choose_sticker
  • 从tg发送多媒体及文件消息时,在从tg服务器下载资源到本地的阶段,状态为upload_${文件类型} ;在把资源上传到wx服务器的阶段,状态为record_video ;发送后状态变为choose_sticker
  • 当正在执行查找联系人操作时,状态将变为typing,并在查找成功后消除。
  • 当您对待下载的wx文件消息做出确认并下载时,在下载期间状态将为typing;成功后状态变为choose_sticker
  • 当接收到大部分的“预定义指令”时,状态都会变为typing
  • 收到来自tg的语音时,状态将变为record_voice
    • 收到来自wx的语音消息时,状态将变为record_voice;对于wx视频消息同理。

4. tg侧指令一览

以下指令可在聊天框中发送,也可打出/后点击命令列表选择目标指令。

请注意,绝大多数指令只能单独使用,在本消息“回复”了其他消息的情况下均不会生效,而是会原样发送到wx,因此发送前请务必检查。

  • /clear,即“软重启”,主要作用是调用softReboot(),清除大多数记忆数据,以减少bug以及提升性能。发送后程序会返回Soft Reboot Successful. Reason: User triggered.,表示软重启成功。这条提示消息会在数秒后自动消失。

主要清除的数据:“上一个聊天对象”、“合并”功能作用对象、定时函数错误计数、“合并”错误致回退次数计数、全局网络错误次数计数

  • /spoiler(本消息只能在“回复”图片消息时起作用)为当前指向的图片消息添加遮罩,其实是借用tg的相关功能,为图片添加一层模糊(在点击后消除),很好地在聊天窗口和消息记录列表保护您的隐私。设置后永久有效。

  • /lock,可开关“聊天对象”锁的状态。当此锁:

    • 值为0时表示不启用锁;
    • 值为1时表示锁是通过本指令设置的,期间将屏蔽所有新来消息对“上一个聊天对象”这一变量的更改,不过您还是可以通过“引用消息”的方式向其他聊天对象发送消息;
    • 值为2时表示锁是通过c)节介绍的“@锁”方式设置的,此时同样会屏蔽“上一个聊天对象”的更改,不同的是,在这种情况下若您对任意消息发送了引用,则锁就会被解除。您也可以使用本/lock指令自行将“2状态”的锁重置回“0状态”。
  • /slet:在默认频道中使用“上一个显式指定的聊天对象”去覆盖“上一个聊天对象”。这么说可能有些抽象,举例表示,如果默认频道中存在分别来自A、B两位的数条消息,那么可先“回复”A的某条消息,然后输入该指令,这样A即为“上一个聊天对象”,后续直接发送的消息也将被递送到A处;此后再回复一次B的消息,再次使用此指令,即可让其后所有未显式指定回复的消息都发往B处。

  • /help,可在当前聊天界面输出一个带有更多指令的列表(这么做主要是为了让tg的指令列表不太累赘)

以上命令均可在Telegram的Bot命令列表中找到,而如下命令只能通过/help指令间接发起,当然您直接在聊天框输入也是允许的。

  • /log,可在当前聊天界面得到程序目前一定数量的日志。

由于tg侧限制,消息不宜太长,因此默认输出的日志数量是末尾1000字符,您也可以通过/log 2000的形式手动覆盖输出的日志数量。
本消息不会自动删除,查看完日志后请手动删除本消息。

  • /placeholder,可在当前聊天窗口输出一段空白消息,以将上方的其他消息“顶出”视野,从而保护隐私。此功能在需要将设备交由他人查看时非常有用。关于此功能的升级也正在规划中,届时将可以在任意消息之间插入空白消息。

  • /drop_on & /drop_off,可开启Drop模式,在此模式下程序将忽略来自tg侧的任何其他消息,启用此模式后(可以机器人正在typing为启用成功标志)您可以放心地在本程序所绑定的群聊里发送任何消息,均会被程序忽略,具体忽略了多少条消息可在日志中找到。请注意,为了防止忘记关闭此开关导致无法发送消息到wx,我们设定了默认为500s的自动关闭定时器/misc/keep_drop_on_x5s,达到时间后该模式将会被关闭,因此请时刻留意Drop模式是否仍在开启状态。

  • /sync_on & /sync_off,可开启Sync模式,在此模式下您在wx中发送的消息也将会被程序转发,就像是来自群内另一成员一样,启用此模式后,您通过手机wx发送的消息(如语音等)也会被程序记录甚至转成文字,有助于消息记录的完整性。

  • /reloginWX_2,旨在一键快速重启程序并刷新wx状态,发送指令后wx登录信息即被清空,然后程序终止。如果部署时使用了Docker等管理技术,那么程序会被自动重启,届时只需重新扫码即可完成重新启动过程。由于直接重新启动很有可能保留先前的登录信息,而先前处理过的聊天记录在启动时会被wx全部发送过来,虽然他们在校验后会被丢弃,但仍会造成初期卡顿的现象,因此该功能还是很有必要的。

  • /reboot:类似重登录指令,重新启动程序,但保留登录信息。可以每隔一段时间发送此指令,提升稳定性,因为基于浏览器的puppet方案在连续运行时间过长时可能会出现bug。

    经测试,wx服务器中给每次UOS微信扫码登录后的session设定了为期7天的超时时间,也就是说,距离上次扫码登录的时间168小时以后,会话将立刻失效,但并不会有任何提示。在本程序内如果会话“失效”,那么将无法收到任何消息,也无法正常发出任何消息(但不会有报错)。因此,定时/reboot可以使程序稳定运行的时长达到7天(若不定期重启的话,每隔几天可能就会出现奇奇怪怪的浏览器错误,此时如果未及时发现错误并重启,导致程序与wx服务器之间的心跳包中断,那么几小时后会话将直接“过期”,再次启动时就必须重新扫码登录了),但必然无法超过这个时限。

  • /create_topic ,本功能旨在快速将联系人绑定到配置好的超级群的新话题,这样不用重启程序也能应用新的C2C设置,提升聊天体验。假如默认频道中收到了来自新联系人的消息,您想要将ta保存为C2C,这样便可以更愉快地聊天了,那么可直接发送本指令,稍后,在预设的话题群中将会出现一个新话题,以联系人名称命名;随后您只需切换到该话题并加以回复即可,以后的所有聊天行为均和其他C2C一样;与此同时,新C2C的相关信息也已写入用户配置文件的/class/C2C_generator项中,从而保证重启程序也不会丢失该条目。

    为了能够正确使用此功能,您需要有一个用来承载新话题的话题群组,将其群id写入/class/C2C_generator中,然后在数组中括号内保留/* |autoCreateTopic Anchor| */注释,新创建的C2C条目会在编码为JSON后插入该注释之后,这样便实现了重启不丢失,同时方便用户进行更改。在部署阶段,您设置好该注释后,可以测试一次本指令,若新C2C的功能正常,且在重启后未出现配置文件无法解析的错误,那么以后便可放心使用此功能了。

    关于本指令,以后将改进的内容:自动为所有新联系人创建C2C条目;在创建C2C后将先前def频道中的相关消息转发过去;。

  • /try_edit :这是一个实验性功能,以如下结构“回复”某条来自机器人的消息:{/try_edit 112233},那么被回复的消息将会被直接覆盖为112233。若tg的相关规则限制了机器人对超出时限的历史消息的修改,则本指令会失效。

  • /eval *Debug指令,需预先在配置文件debug_evalEnabled启用本项:在该命令后追加js代码并发送,即可在BotIndex.js的上下文中执行该代码。若您并非对JavaScript语言有较好的理解,请不要启用该功能,以免引入远程代码执行漏洞。

三. 配置文件参考

本章将对模板配置文件def.conf.js中的各项进行尽可能详细的解释。标星号者表示作者认为您用到它的概率不大,可以忽略。

由于本程序仍在 快速发展,因此配置文件的变动可能会比较频繁,我将尽力做到至少在两个次版本号(如3.4.0->3.5.0)之间更新本章节内容,若下文有与dev分支最新源码不匹配者,请参考后者之英文注释,谢谢!

  • /ctToken节请参阅 { 部署指南 –> 初始化配置文件 } ,并务必填写您自己的 ctToken。

/tgbot

  • botToken:请填写从@BotFather处取得的Bot Token,以数字+冒号开头。

  • botName:与上述token对应的Bot的用户名。

  • tgAllowList数组:以数字形式存储有权向Bot发送消息的tg用户的id。对于此列表以外的tg用户,无论是对Bot私聊还是在有Bot的群组中发言,均会被忽略。

  • webHookUrlPrefix:使用webhook启动tg bot时,将需要此处的参数。

    (Incomplete Function) 当您想要以webhook而非polling模式启动tg bot时,将需要通过内网穿透等方案自行把本地的监听端口8443暴露到公网,并得到映射后的URL。例如,启动项目时使用的命令为npm run h1则webHook号为1,此时若https://example.com/webHook1/可以指向 https://localhost:8443,那么此处请填写https://example.com/webHook。此外,还需自行申请SSL证书并按照src/init-tg.js内的代码,将公私钥放置于特定位置。 因此不建议使用此功能,一是配置过程十分繁琐,二是将更难发现潜在的网络问题。如需要换用webHook模式,可联系作者。

  • statusReport:该项定义了/info指令所生成的报告应存放在哪里。

    • switch定义整个项的开关状态;

    • host将要收到报告的目标服务器的域名;

    • path为接收脚本所放置的具体位置。

      本功能开发于初期,现已不建议使用,作用是将当前运行环境中的部分变量信息以及部分日志 通过Web服务器的中转发往tg用户。

      使用此功能需要您拥有任意安装有PHP的Web服务器,并把/static/ctBotReport.php放置到任一可执行的目录中。随后按照实际情况填写配置文件即可。

  • polling

    • pollFailNoticeThres:该项定义了将在多少次失败的telegram poll操作后发出网络问题警示。
    • interval:该项定义每两次poll之间应间隔的毫秒数,如果您希望机器人可以更快地接收来自tg的消息,则可调整此项,但过小的值可能造成网络异常出现频率加大。

/class

  • def:默认频道的配置。类型为connObj,但不支持话题群,请单独为其创建群,或采用私聊。

    本文档中会经常涉及到connObj及它的子类。最简单的形如这样:{tgid:-100010203};若为话题群内的话题,则可以添加threadId属性,变成这样:{tgid:-100010203, threadId: 5}

  • push:推送频道的配置。类型为connObj

  • C2C数组:包含各C2C配置资料。其中每个C2C Pair应如下所示:

    1
    2
    3
    4
    5
    {
    "tgid": -1001006,
    "wx": ["wx Contact 1's name", true],
    "flag": "",
    }

    也就是在connObj的基础上增加了wx数组和flag字符串。具体内容请参见前文 {初始化配置文件}。

  • C2C_generator对象:包含 启用了生成器的各话题群及其详细配置。在启动时,它们会被自动转换为C2C Pair格式,但在配置过程中可降低用户工作量。具体内容也请参见前文 {初始化配置文件}。

/filtering

  • wxFindNameReplaceList :*定义了在使用查找联系人功能时,需要替换哪些字符串。原意是将需要频繁查找的对象名进行简写并存储短语,下次查找联系人只需输入短语即可。
  • wxContentReplaceList:定义了从wx接收的消息中,哪些字符串需要被替换。举例:将以文字形式显示的wx自带表情(如[Pout])转换为自设emoji。
  • tgContentReplaceList:与上一项类似,但是替换对象是从tg接收的消息。举例:在未购买Telegram Premium的情况下,将一些emoji手动映射为wx自带emoji,这样便可在聊天中方便地发送wx表情了。
  • wxNameFilterStrategy:前文 {初始化配置文件} 中有提及,该功能可以屏蔽或只允许部分对象的消息经过转发,以提升程序效率。
    • useBlackList:true表示仅启用黑名单;false表示仅启用白名单。
    • blackList & whiteList:略
  • wxMessageExcludeKeyword数组:*当wx消息中包含任一关键词时,丢弃整个消息。
  • wxPostOriginBlackList数组:定义了屏蔽其推送消息的订阅号名称列表。

/notification

本项中的大多数功能需要您先配置好Bark才能使用;如果您拥有自建的、以HTTP GET方式就能触发的推送服务,那么也可在此处设置。

  • baseUrl:Bark推送服务的URL。该URL应当可以在直接访问的情况下成功推送。可以包含通知标题。形如https://example.com/BridgeBot_WARN/
  • default_arg每次执行推送时,应在URL末尾附加的参数。对于Bark,可以在此定义通知分组信息和推送消息头像,当然也可采用默认配置。
  • prompt_network_problematic:当网络出现问题(特指Polling)而又恢复了时,发送的推送通知的正文部分。
  • prompt_relogin_required:当需要重新扫码登录时,发送的通知内容。
  • prompt_wx_stuck:当wx puppet发生意外崩溃导致大概率无法正常工作时。
  • prompt_network_issue_happened:当网络出现问题且没有自动恢复时。
  • incoming_call_webhook函数:该项应当在被调用时返回一个URL,当收到来自wx的通话时,该URL将被访问。如果仍使用Bark作为推送服务的话,您需要将完整的URL填写至此。
  • send_relogin_via_tg:布尔型,为1表示将会在需要重新扫码登录时将二维码发送到默认频道;为0表示禁用该功能。

/misc

  • deliverPushMessage定义是否转发订阅号推送消息:设为false表示不转发;true表示转发到/class/push频道;设为connObj会把消息转发到前者。

  • deliverSticker定义是否转发wx侧的动画表情:设为false表示完全不转发;也可设为connObject+urlPrefix,其中urlPrefix请将tg目标的相关参数填入URL中,以便在实际聊天中,点击Sticker字样可以跳转到由deliverSticker指定的动画表情所在地;具体用例请参照配置文件模板。

  • deliverRoomRedPacketInAdvance:是否监听所有群聊中的红包并通过def频道发送提醒;0表示不启用;1表示仅在“未被黑白名单过滤掉的群聊”中监听;2表示所有群聊。

  • mergeResetTimeout:该对象定义了对于私聊和群聊,当两条消息的时间间隔大于多少秒时,重置上次合并状态,直接发送消息。

  • onceMergeCapacity:该对象定义了单次合并中,满足何种条件时重置合并状态并重新开始。

    • timeSpan:当第一条消息距今多少秒时,重置合并。
    • mediaCount:当合并消息中包含多少个媒体消息时,重置合并。此项可避免聊天中包含过多图片时,文字与其所对应的图片距离太远。
    • messageCount:当合并消息中包含多少条消息时重置。此项同样是为了避免合并后的消息过长。
  • debug_evalEnabled(调试用途)启用/eval命令,使您可以在tg中远程执行代码。该功能可能引入极大的安全隐患,无必要请勿启用。

  • display_ctToken_info:控制是否在程序启动时,显示与您的ctToken相关的信息。设为0来阻止它们。

  • debug_add_console_timers(调试用途)是否在程序执行特定耗时操作(例如寻找wx联系人)时,在控制台显示该操作所耗时间。有助于您追踪耗时操作的用时以及设备性能。

  • savePostRawDataInDetailedLog:*是否在msgDT日志中保存收到的订阅号推送消息的原始版本。

  • addHashCtLinkToMsg:是否在wx侧发来网页链接时,在链接末尾附加#ctLink标志,因为一旦启用了deliverSticker,那么聊天中将充斥大量 t.me 链接,如果需要方便地查找wx好友发来的链接,那么可以启用此项。

  • passUnrecognizedCmdNext:是否把程序未能识别的tg聊天命令(例如,以/开头者)当成文本继续发送到聊天对象。若关闭,则在发送以/为开头的消息时可能会被误判为命令。(当然,在斜杠前加上空格即可避免)

  • service_type_on_webp_conversion:在tg sticker的格式转换过程中使用何种服务。2为采用本地模块sharp,推荐使用;1为又拍云在线检测,需要对应的API Key填写于/upyun中;0为不转换,直接把.webp格式的图像发往wx,可能会在他人设备中显示为无法预览的文件。

  • add_identifier_to_merged_image:是否在合并消息包含的图片消息的caption部分,添加四位随机数以标识图片和文字的对应关系,有助于查清对方发送图片的次序,因为转发过程中可能因网络等问题导致对方发来的媒体消息失序。设为0表示不启用;设为1表示仅在群聊中适用;设为2则适用于所有聊天。

  • status_report_interval*:控制每两次控制台status Report之间需要间隔至少多少秒。

  • keep_drop_on_x5s*:/drop_on打开时,若一直未手动关闭,则在多少个5秒后系统将自动关闭该功能。

  • wxAutoDownloadSizeThreshold:wx侧收到的文件中,大小大于多少字节的文件将不会被默认下载,而是发送提示给用户询问是否下载。默认值为3 MiB

  • tgCmdPlaceholder:在/placeholder指令发出后,向当前聊天框输出什么样的占位符。保持默认即可。

/chatOptions

本节定义了默认情况下每个C2C(以及默认频道)的特定选项值。

  • mixed:是否允许混合消息制,即以*开头的任何tg消息都将被忽略,适合在部分消息不希望让wx侧的聊天对象知晓的情况下指定。
  • merge:是否对此聊天启用合并功能。默认为开。
  • skipSticker:是否忽略该聊天中的所有 wx动画表情。
  • nameType:设定群聊中的群友们该以什么作为其显示名称。为0表示采用他们wx账户的名称;为1表示优先采用您对群友的个人名片中的备注;为2表示优先使用该联系人自行设置的群名片。
  • onlyReceive:表示该C2C是否仅转发来自wx的消息,而不转发来自tg的消息。适合您不想在其中误发言的群聊,例如通知群。

/c11n

本节定义了一些“个性化”选项,以修改一些消息的表现形式。

  • wxQuotedMsgSuffixLine:来自wx的消息包含引用时,UOS版wx默认会显示为不美观的样式,本项会将其转换到消息末尾的斜体括号,尽力与wx客户端保持一致。

  • titleForSameTalkerInMergedRoomMsg:是否把合并消息里,来自同一对象的数条连续消息的标题隐藏(即不会重复显示说话者的名称)。在默认配置下,标题会被替换为数字,其值为说话者连续消息的条数。

  • quotedMsgSuffixLineInPersonChat:基于wxQuotedMsgSuffixLine,在私聊消息中出现引用消息,默认情况下后缀行会采用您和对方的wx名称,通过此项可将其替换为YOU和ta,避免自己和对方的昵称频繁出现。

  • officialAccountParserpersonCardParser:这两项定义如何解析公众号名片和个人名片为字符串,可自定义显示哪些数据,不过建议采用默认配置。

  • systemMsgTitleInRoom:群聊内的系统消息(如红包、修改群名,拉入新成员,新成员与其他人都不是朋友等等)默认以群名作为“说话者:的显示昵称,此项会将其替换为(System)

  • stickerWithLink:基于deliverSticker,经此功能分开递送动画表情之后,需要在当前聊天中输出一个链接以便用户点击后跳转到表情所属聊天,此项定义了这个链接应当如何显示。默认值足矣。

  • stickerSkipped:定义被忽略的动画表情应当如何显示。

  • newTopicCreated:使用/create_topic创建新C2C线程时,在新线程中显示的欢迎消息。(因tg限制,必须设置欢迎消息,否则无法创建线程。)

  • C2C_group_mediaCaption:C2C群聊消息中,群成员发送的媒体消息默认采用什么作为其caption。只需在输出字符串中包含name即可。

  • override_help_text:是否override默认的/help文本。默认设为false,即不覆盖,随版本更新而更新;若需override,请参考common.js中的TGBotHelpCmdText将合适的函数放置于此。

    接下来几项,均为所收到的消息不被UOS版wx完全支持时的替代符(因为原版提示文字一般都会包含”升级版本“等字样,为避免碍眼因此使用emoji代替)。

  • unsupportedSticker:发出或收到不支持的表情(均为在wx客户端点开能看到文字的商城表情)

  • recvCall:收到通话邀请时(很遗憾,UOS版wx不支持视频通话与语音通话的区分,下同)

  • recvSplitBill:收到群内分付账单时

  • recvTransfer:收到转账消息时(并非均为向您的转账,也可能是群聊中指定收款对象的转账)

  • acceptTransfer:转账被接收时

  • msgTypeNotSupported:消息类型不支持时(主要包含所有小程序卡片、合并转发的消息卡片。很遗憾,UOS版wx……后面忘了)

/txyun

本节定义了 腾讯云API的凭据信息,目前仍为语音转文字等功能的必需。

如需启用,请前往 https://console.cloud.tencent.com/cam/capi ,新建密钥即可。在此过程中可以遵循页面指引,新建子账号并为后者生成API Key,以降低Key泄露后被盗用的服务覆盖面。不过请注意所配置的子账户必须具有如下服务的访问权限:

语音识别ASR。

  • switch:是否启用腾讯云API。

  • secretIdsecretKey:请根据腾讯云网站提示分别填入AK与SK即可。

/upyun

由于sharp的引入,此节用途暂缺,因此暂缓相关文档条目的完善。

  • switch
  • password
  • webFilePathPrefix
  • operatorName
  • urlPrefix
  • urlPathPrefix
  • Title: ctBridgeBot Wiki (Lite)
  • Author: Eddy
  • Created at : 2023-08-01 10:54:00
  • Updated at : 2024-08-10 01:17:02
  • Link: https://blog.eddy.moe/2023/08/01/CTBR_Docs1/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments