群組太多訊息看不完、

退群又怕傷感情怎麼辦?

 

何不做一隻跨平台的訊息轉送機器人

 

以 C++ REST SDK 在 Arch Linux 上實作 Chat Bot 經驗談

Too many chat groups,
Too many unread messages;

I want to leave groups, but somebody' heart broken 😢
How can I do?

Why not create a Cross Platform Instant Messaging Chat Bot?

Based on C++ REST SDK and Arch Linux

Ping Wu (小平)

  • Come from Penghu Islands
  • Archer (Arch Linux User)
  • Cataholic

 

  • Neobards (泥巴娛樂)
    Network Programmer

 

Story

我想退群、

但又怕傷感情

怎麼辦?

我有一個大膽的想法 ...

Line Message to Telegram

  1. Recive Line Message : LINE Message API - Webhook
    https://developers.line.biz/en/docs/messaging-api/receiving-messages
  2. Send Message To Telegram : Telegram Bot API
    https://core.telegram.org/bots/api#sendmessage

 

Telegram Message to Line

  1. Recive Telegram Message : Telegram Bot API - Webhook
    https://core.telegram.org/bots/api#setwebhook
  2. Send Message To Line

CPIM

  • Cross

  • Platform

  • Instant

  • Messaging

Telegram ⇋ Line

Standby Programming

C++ REST SDK ( cpprestsdk )

yay --color=always -Ss cpprestsdk
[ping@x201 ~]$ yay cpprestsdk
2 aur/cpprestsdk-git 2.1.0.r1705.g1e4717e5-1 (+2 0.00) (Orphaned) 
    A Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design
1 aur/cpprestsdk 2.10.13-1 (+7 0.00) (Out-of-date: 2019-08-19) 
    A cross-platform, modern, and asynchronous library that enables developers to access and author connected applications
==> Packages to install (eg: 1 2 3, 1-3 or ^4)
==>

Conan : C++ Package Manager

yay --color=always -Ss conan
[ping@x201 ~]$ yay conan
3 aur/barbarian 1.0.0-1 (+0 0.00) 
    A frontend for the Conan package manager, written in Qt.
2 aur/conan-git 1.23.0.dev.r4185.4ea97afca-1 (+1 0.89) 
    A distributed, open source, C/C++ package manager.
1 aur/conan 1.27.1-1 (+33 1.13) (Installed)
    A distributed, open source, C/C++ package manager.
==> Packages to install (eg: 1 2 3, 1-3 or ^4)
==>

Conan with IDE

  • CLion
  • Visual Studio
  • Visual Studio Code

Conan with CLion

Conan with Visual Studio

Conan with Visual Studio Code (Orphaned)

Other Tips?

# https://wiki.archlinux.org/index.php/GNU#Toolchain
# https://www.archlinux.org/groups/x86_64/base-devel
[ping@x201 ~]$ sudo pacman --needed -S base-devel



[ping@x201 ~]$ gcc --version
gcc (GCC) 10.1.0



# https://wiki.archlinux.org/index.php/LLVM
[ping@x201 ~]$ clang --version
clang version 10.0.0

Other Traps?

Build Failed

CMake Error at cmake-build-debug/conanbuildinfo.cmake:1064 (message):
  Detected a mismatch for the compiler version between your conan profile
  settings and CMake:

  Compiler version specified in your conan profile: 9

  Compiler version detected in CMake: 10.1

  Please check your conan profile settings (conan profile show
  [default|your_profile_name])

  P.S.  You may set CONAN_DISABLE_CHECK_COMPILER CMake variable in order to
  disable this check.
# .conan/profiles/default_bafore

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=9
compiler.libcxx=libstdc++11
build_type=Release
[options]
[build_requires]
[env]

Option​

  1. Rollback to GCC 9
  2. Set compiler.version=10
# .conan/profiles/default_after

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=10
compiler.libcxx=libstdc++11
build_type=Release
[options]
[build_requires]
[env]

小孩子才 Rollback,

大人的我們當然要 Rolling UP TO DATE.

支離滅裂式發言

此處應有圖

 

大人的我們當然是___.png

Build succeed?

Can't compile on GCC 10.1

priv-kweihmann opened this issue on 2020-07-07T08:09:24Z

 

building on gcc 10.1 with a reasonable warning set breaks the build.
Same code on gcc 9.x builds fine

fix format-truncation on 64bit

priv-kweihmann wants to merge 1 commit into microsoft:master on 2020-07-07T11:01:16Z

 

Fixes Issue#1461

我已經盡力了,GCC 這塊編譯器不要我沒關係

 

via 深夜情緒大爆發的 C++ 初心者

「夜深人靜的時候,你還有我」 - LLVM (設計對白)

# .conan/profiles/clang

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=clang
compiler.version=10
compiler.libcxx=libstdc++11
build_type=Debug

[options]

[build_requires]

[env]
CC=/usr/bin/clang
CXX=/usr/bin/clang++
CMake Error at cmake-build-debug/conanbuildinfo.cmake:1240 (message):
  Incorrect 'clang', is not the one detected by CMake: 'GNU'

Build succeed?

/home/ping/.conan/data/boost/1.72.0/_/_/package/f2d0294e070a9bf6922db8b0c4adcbd7074c0680/include/boost/asio/async_result.hpp:70:20: error: concept cannot have associated constraints

/home/ping/.conan/data/boost/1.72.0/_/_/package/f2d0294e070a9bf6922db8b0c4adcbd7074c0680/include/boost/asio/async_result.hpp:492:20: error: concept cannot have associated constraints

8 warnings and 2 errors generated.
make[2]: *** [CMakeFiles/main.dir/build.make:63: CMakeFiles/main.dir/main.cpp.o] Error 1
make[2]: Leaving directory '/home/ping/ProjectPath/cmake-build-debug'
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/main.dir/all] Error 2
make[1]: Leaving directory '/home/ping/ProjectPath/cmake-build-debug'
make: *** [Makefile:84: all] Error 2

Orz ...

# conanfile.txt

[requires]
cpprestsdk/2.10.16
# cpprestsdk/2.10.15 build failed.

boost/1.73.0
# cpprestsdk/2.10.16 require boost/1.72.0 but build failed.

[generators]
cmake

Finally ... Build Succeed.

WARN: cpprestsdk/2.10.16: requirement boost/1.72.0 overridden by your conanfile to boost/1.73.0 
WARN: websocketpp/0.8.2: requirement boost/1.72.0 overridden by cpprestsdk/2.10.16 to boost/1.73.0

\ Let's Programming /

Standby Webhook

Dynamic DNS (DDNS)

# /etc/ddclient/ddclient.conf

daemon=300                # check every 300 seconds
syslog=yes                # log update msgs to syslog
mail=root                 # mail all msgs to root
mail-failure=root         # mail failed update msgs to root
pid=/var/run/ddclient.pid # record PID in file
ssl=yes                   # use ssl-support

protocol=noip                                                                                                                                  
use=web, web=checkip.dyndns.com                                                                                                                
server=dynupdate.no-ip.com                                                                                                                     
login=YourNoIpAccount                                                                                                                                 
password=YourNoIpPassword                                                                                                                  
YourNoIpDomain
# /usr/lib/systemd/system/ddclient.service

[Unit]
Description=Dynamic DNS Update Client
After=network.target

[Service]
Type=forking
PIDFile=/run/ddclient.pid
ExecStart=/usr/bin/ddclient

[Install]
WantedBy=multi-user.target

C++ REST SDK

void web::http::experimental::listener::http_listener_config::set_ssl_context_callback ( const std::function< void(boost::asio::ssl::context &)> &  ssl_context_callback )

Nginx

[ping@x201 ~]$ netstat -lnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN     
tcp        0      0   0.0.0.0:8443          0.0.0.0:*               LISTEN     
tcp6       0      0       ::1:8080               :::*               LISTEN     
tcp6       0      0       :: :8443               :::*               LISTEN     
// From Telegram

{
  "message": {
    "chat": {
      "all_members_are_administrators": true,
      "id": -123456789,
      "title": "Telegram Bot API 測試",
      "type": "group"
    },
    "date": 1596098895,
    "from": {
      "first_name": "Ping Wu (小平) 🐈",
      "id": 12345678,
      "is_bot": false,
      "language_code": "zh-hans",
      "last_name": "誠心所願",
      "username": "PingNote"
    },
    "message_id": 123,
    "text": "Arch Linux Taiwan @ COSCUP 2020"
  },
  "update_id": 123456789
}
// From Line

{
  "destination": "0123456789ABCDEFabcdef",
  "events": [
    {
      "message": {
        "id": "1234567890",
        "text": "Arch Linux & Archers",
        "type": "text"
      },
      "mode": "active",
      "replyToken": "0123456789abcdef",
      "source": {
        "groupId": "0123456789ABCDEFabcdef",
        "type": "group",
        "userId": "0123456789ABCDEFabcdef"
      },
      "timestamp": 1596099033060,
      "type": "message"
    }
  ]
}

Standby

Send Messages

https://api.telegram.org/botYourBotToken/sendMessage
https://notify-api.line.me/api/notify

Content-Type  = application/x-www-form-urlencoded
Authorization = Bearer <access_token>

How to get Line Notify Access Token ?

Option:

  1. OAuth2​
  2. Generate access token (For developers)

Results

Receive (POST): /HIDDEN/FromLine                                                                                                              
Body: {"destination":"HIDDEN","events":[{"message":{"contentProvider":{"type":"line"},"id":"HIDDEN","type":"
image"},"mode":"active","replyToken":"HIDDEN","source":{"groupId":"HIDDEN","type":"group",
"userId":"HIDDEN"},"timestamp":1596107403013,"type":"message"}]}                                                    
        headers["accept"]="*/*"                                                                                                                
        headers["Connection"]="close"
        headers["Content-Length"]="371"
        headers["Content-Type"]="application/json; charset=utf-8"
        headers["Host"]="HIDDEN"
        headers["user-agent"]="LineBotWebhook/1.0"
        headers["X-Forwarded-For"]="HIDDEN"
        headers["X-Line-Signature"]="HIDDEN"
        headers["X-Real-IP"]="HIDDEN"
sendToTelegram(200):
        headers["Access-Control-Allow-Methods"]="GET, POST, OPTIONS"
        headers["Access-Control-Allow-Origin"]="*"
        headers["Access-Control-Expose-Headers"]="Content-Length,Content-Type,Date,Server,Connection"
        headers["Connection"]="keep-alive"
        headers["Content-Length"]="731"
        headers["Content-Type"]="application/json"
        headers["Date"]="Thu, 30 Jul 2020 11:10:05 GMT"
        headers["Server"]="nginx/1.16.1"
        headers["Strict-Transport-Security"]="max-age=31536000; includeSubDomains; preload"
Receive (POST): /HIDDEN/FromTelegram
Body: {"message":{"chat":{"all_members_are_administrators":true,"id":HIDDEN,"title":"群組名稱","type":"group"},"date":1596107443,"from":{"first_name":"名字","id":HIDDEN,"is_bot":false,"language_code":"zh-hans","last_name":"姓氏","username":"HIDDEN"},"message_id":HIDDEN,"sticker":{"emoji":"🎮","file_id":"HIDDEN","file_size":25818,"file_unique_id":"HIDDEN","height":512,"is_animated":false,"set_name":"HIDDEN","thumb":{"file_id":"HIDDEN","file_size":6204,"file_unique_id":"HIDDEN","height":128,"width":128},"width":512}},"update_id":HIDDEN}
        headers["Accept-Encoding"]="gzip, deflate"
        headers["Connection"]="close"
        headers["Content-Length"]="801"
        headers["Content-Type"]="application/json"
        headers["Host"]="localhost:8080"
        headers["X-Forwarded-For"]="HIDDEN"
        headers["X-Real-IP"]="HIDDEN"
sendToLine(200):
        headers["Connection"]="keep-alive"
        headers["Content-Type"]="application/json;charset=UTF-8"
        headers["Date"]="Thu, 30 Jul 2020 11:10:44 GMT"
        headers["Keep-Alive"]="timeout=3"
        headers["Server"]="nginx"
        headers["Transfer-Encoding"]="chunked"
        headers["X-RateLimit-ImageLimit"]="50"
        headers["X-RateLimit-ImageRemaining"]="50"
        headers["X-RateLimit-Limit"]="1000"
        headers["X-RateLimit-Remaining"]="996"
        headers["X-RateLimit-Reset"]="1596109844"

附加好處

  • Line 訊息馬上就有兩個(機器)人已讀
  • Line 訊息都備份到 Telegram 了,再也不怕換手機

Thanks

 

Q&A

 

工商宣傳

群組太多訊息看不完、退群又怕傷感情怎麼辦?何不做一隻跨平台的訊息轉送機器人:以 C++ REST SDK 在 Arch Linux 上實作 Chat Bot 經驗談

By Ping Wu (小平)

群組太多訊息看不完、退群又怕傷感情怎麼辦?何不做一隻跨平台的訊息轉送機器人:以 C++ REST SDK 在 Arch Linux 上實作 Chat Bot 經驗談

  • 895