• 解决了crash的问题。前一版的问题是在于用户隐私设置,如果禁止转发消息,则不会在forward信息中带有原始用户的user id,引起异常。 解决办法,就是在收到用户消息后,服务器保存消息id和chatid(user id),然后在回复转发消息时查表即可。(回复时带有reply id,即前面的消息id)。
  • 加入了webhook和pooling两种机制的支持,通过yaml配置即可。
  • yaml示例:

    account:
    mode: "pooling"  或者是 webhook
    token: "aaaaa"   @botfather建立bot时得到的token
    owner: 12345678   需要转发的目地user id
    endpoint: "https://www.foo.bar"   webook的接收消息地址。pooling时随便填。完整的endpoint是 https://www.foo.bar/{token}。 telegram的要求必须是https协议。
    port: 80              服务监听端口,pooling时随便填。代码使用的http,因为前端会用cloudflare等反代,没必要弄https,还要折腾证书,烦一个字。

bot.go
telegram.go

继续接着 上次的事 来弄
完美的做法当然是仔细的通过事务和数据锁等等来解决这个,但,大家都很忙,能有简单但有效的解决办法么?
当然。

  1. 路由处理函数随机延时,比如每次请求 sleep 0-100ms。人类感觉不大出来这个时间,人的神经线传输是0.3秒。但它就可以有效的把并发处理从时间上分散开。当然,我是指不是恶意的,只是因为不小心或者实在太凑巧了并发了。
  2. 路由函数加互斥锁,锁使用用户token或者userid等。其实绝大多数路由函数,特别是写的操作,简单的互斥锁就够了,咱们遇不到真正需要严格并发处理它的这种业务需求。
  3. 忽略掉逻辑上不可能的并发,比如,同一个用户一秒登录10次,那就只处理第一个请求,后面9个通通直接return。这一方面是解决并发,一方面也是防止cc。

有的时候,不想把自己的telegram号给别人,用个机器人来转发就很有必要了
@LivegramBot是实现同样功能的,不过,本着折腾精神,自己写一个。
原理就是,机器人会把收到的消息转发给自己的主号,主号回复的转发消息,提取出来文字/图片/视频后把它发给消息的原始发送者。
偶尔会crash掉,还有待继续debug,找到crash的地方。

**crash原因已发现,如果用户在隐藏模式下,就是禁止group转发时,无法获得原始的转发人id故而出错。明天发修正的源码。

逻辑: tgfwd.go

TG接口: telegram.go

配置文件: bot.yaml

先执行select sn from xxxx where oid=xxxx, 找指定的oid的记录,如果错误,就是记录不存在(数据库挂了?不可能的啦。。),然后既然不存在,那就新增对应oid的一条记录。这是常用的如果有就读出来没有就创建新记录的机制。
逻辑和流程没问题?
笑话,大力出奇迹,板砖也能飞上天!
同时并发一堆这请求,只要力气够大速度够快,大家都可以同时在select还没来得及insert的时候进入if err!=nil,就产生了一堆相同oid的记录。
啥?没这么巧?系统因为这个重复一大堆,现在都还不知道怎么擦这屁股。。。

dl.jpg

适用于最新版,网上的千篇一律的那些老文大多不适用了。

  1. 安装 asar npm install -g asar
  2. 到app.asar目录
  3. asar extract app.asar ./app
  4. mv app.asar app.asar.bak
  5. rm app-update.yml
  6. 修改app/js/background-process.js
  7. 将 const e=await this.api.bulkAccount(); 这一句改成下面:

    var e=await this.api.bulkAccount();
    e.account.pro_mode=true;
    e.account.need_to_update_subscription=false;
    e.account.current_period={
     "from": "2022-01-01T00:00:00",
     "until": "2099-01-01T00:00:00"
    };
    e.account.plan_type="Premium";
    e.account.user_type="Premium";
    e.student=null;
    e.trial=null;
    e.account.authorized_features.show_trial_section=false;
    e.account.authorized_features.show_subscription_section=true;
    e.account.authorized_features.show_github_account_section=false;
    e.account.expired_screen_type=null;
    e.personal_subscription={
     "now": new Date().toISOString().slice(0, -5),
     "status": "SUCCESS",
     "platform": "stripe",
     "current_period": {
         "from": "2022-01-01T00:00:00",
         "until": "2099-01-01T00:00:00"
     },
     "revokable": true,
     "refunded": false,
     "cancelable": true,
     "reactivatable": false,
     "currency": "usd",
     "created_at": "2022-01-01T00:00:00",
     "updated_at": new Date().toISOString().slice(0, -5),
     "valid_until": "2099-01-01T00:00:00",
     "auto_renew": true,
     "price": 12.0,
     "verbose_plan_name": "Termius Pro Monthly",
     "plan_type": "SINGLE",
     "is_expired": false
    };
    e.access_objects=[{
     "period": {
         "start": "2022-01-01T00:00:00",
         "end": "2099-01-01T00:00:00"
     },
     "title": "Pro"
    }]
    
  8. 搞定,pro版了。