1. 跨IM通知平台能帶給我什麼便利?

身為一個資工系的學生/畢業生,相信你一定也很常會自己撰寫script來自動化處理生活上的事物,像是監控家中NAS的loading或是定期備份自己的資料,處理完成後往往都會透過各種管道送出最後的處理結果,讓您能輕鬆掌握各個排程工作的結果。如果您擁有自己的服務,也常會想要即時得知有新的用戶註冊了。

以往最常使用的方法便是透過email或是簡訊通知,但使用email總感覺即時性不太夠,而且總是需要Google個老半天去找到寄信的範例,而簡訊通知,則是得花自己的錢,而且還得想辦法去找到可以處理各電信業者的機器人程式。

上述兩種方式使用起來都不太方便,加上這兩年各類IM(Line, Facebook Messenger)已經滲透你我的生活,也提供各種平台上的Client(最近連Chrome Extension都推出了!),常言道:簡訊/email通知隨他響,Line/Facebook訊息則不可不看,此服務就是為了這個目的而誕生,提供最簡單的方式讓您可以自動發送通知到自己的Line上,更棒的是我們提供五種常用語言(Python, PHP, Ruby, Node.js, Golang)的範例程式,讓您只需要簡單修改後即可整合進去您現有的專案!

2. 聽起來不錯,那使用上有什麼需要注意的地方嗎?

本服務的使用限制如下:

  1. 目前支援Line以及Facebook Messenger平台
  2. 本服務使用Line官方提供的Bot API,目前該API處於Beta階段,若該API進入正式版本改採收費制度,本服務可能將會取消Line的支援(Facebook不受影響),還請見諒 (fingers crossed)
  3. 單一則訊息長度為250個字(中英混合)
  4. 限制單一IP每秒鐘只能夠送三次request
  5. *** 請注意此token跟DDNS的token不同!不同!不同!(請點選本頁上方"我的token"取得,token最後結尾是一串數字) ***
  6. 傳送圖片最大上限為4 MB

3. 這正是我需要的!我該怎麼使用呢?

您只需要三個步驟即可註冊使用跨IM訊息通知!

  1. 首先將您的csie.io帳號與您想要使用的平台連結
  2. 在您手機/電腦的Line上搜尋Line ID: @wch4173n 並且將它加為好友。您可以在Line中直接掃描下方QR Code加入好友

    請用您的Messenager App掃描下方QR Code,加入好友後即可註冊使用



    或是直接點選右方按鈕開啟聊天視窗即可:
  3. 點擊本頁上方我的專屬token標籤頁,複製您的專屬token: OOO-12344321(注意此token跟DDNS的token不同,請點選本頁上方"我的token"取得,token最後結尾是一串數字!)
  4. 在手機/電腦的Line/Facebook Messenger發送訊息給CsieIoBot,請送出 /add [您的token],例如 /add OOO-12344321,收到CsieIoBot的確認通知即完成註冊!

4. 所以到底該怎麼要CsieIoBot發訊息給我啊啊啊啊?

當您完成註冊後,您只需要送出一個https request即可,純送純文字Line訊息說明如下:

  • HTTP Method: GET/POST
  • API_ENDPOINT = https://csie.io/msgme
  • Parameters:
    • token: 你的專屬token (本頁最上方取得)
    • msg: 你要傳送的字串
    • im: line 或 facebook

curl -G "https://csie.io/msgme?token=abcd-12344321&im=line" --data-urlencode 'msg=哇哈哈~測試一下喔!!'
                          

curl -G "https://csie.io/msgme?token=abcd-12344321&im=fb" --data-urlencode 'msg=哇哈哈~測試一下喔!!'
                          
您應該可以在幾秒內收到CsieIoBot傳送給您的訊息!

若您需要傳送圖片,請使用POST的方式傳送檔案,簡單範例如下(允許只傳圖片不帶msg):

curl -F 'token=abcd-12344321' -F 'msg=Nightly Build成功,看個正妹慶祝一下!' -F 'im=line' -F 'file=@Downloads/beauty.jpg' https://csie.io/msgme
                          

curl -F 'token=abcd-12344321' -F 'msg=Nightly Build成功,看個正妹慶祝一下!' -F 'im=fb' -F 'file=@Downloads/beauty.jpg' https://csie.io/msgme
                          
本服務也提供五種常見語言的呼叫方式,請參考範例頁面!

5. 我該怎麼讀懂CsieIoBot的return code?

  1. OK:- 處理成功
  2. badauth: 認證錯誤
  3. toolongmsg: 訊息長度超過限制
  4. noreg: 您尚未註冊使用跨IM通知平台服務

6. 我手邊還有之前line通知的code需要變更嗎?

舊有的呼叫方式依然可以正常運作,不過建議您可以抽空轉換成新的呼叫方式(把lineme改成msgme跟多一個參數而以,花不了幾分鐘!)

7. 我還是有些問題不太清楚,我該怎麼辦?

請聯絡 lab@csie.io,將會有專人提供解答。

8. 為什麼截圖都是Android的畫面?

因為我沒有錢買iphone Orz

** 致謝 **

感謝Lukas幫忙review文件,icross.cc提供Ruby的範例程式碼,同時也感謝Terces提供Node.js呼叫CsieIoBot範例 (訊息+圖片)的範例程式!!



Email轉發功能

雖然csie.io提供了便利的API讓您可以自行整合至您的應用,但還是不夠完美,最常見的是您沒有權限能夠整合API到現有系統中,只能夠被動的透過email接收警告通知,有了本功能後,這再也不是問題!只需在您的監測系統的email警示欄位中填上您的專屬email,或者設定mail filter將警示類的mail轉寄至您的專屬email,就可以在Line或是Facebook上即時獲得通知!

1. 使用方式

  1. 請先確定您已經註冊跨IM通知平台服務,如果還沒的話,請先送出 /add [您的token],例如 /add OOO-12344321 (請點選上方"我的token"取得token)
  2. 同樣在本頁上方"我的token"中取得您專屬的email(Line與Facebook不同)
  3. 在您的系統中或是自行定義filter,將相關警示信件寄送至專屬email即可

2. 常見問題

  • Q: 我的email中有圖片你們可不可以處理啊?
    A: 沒問題,但僅支援圖片,其他附加檔案會直接略過。
  • Q: 我可以透過這個專屬email收信嗎?
    A: 不可以。
  • Q: 我用工具測了一下,你們這服務竟然有開放open relay?!
    A: 安啦,保證沒有 kerker

3. 有圖有真相

*** 感謝系友Kudo大方提供csie.info使用權!***

宿網用量提醒服務

快速的宿舍網路總是讓人一用上癮,但是每天10.3GB的流量限制實在是讓人時時擔心,尤其是一旦超流就得被斷線,更是讓人生氣又無奈,所以本服務使用跨IM通知平台功能,每三分鐘檢查一次您的宿網使用流量,並在使用流量到達50%、70%、90%以及100%時,自動發出通知至您註冊的平台(Line/Facebook),讓您可以預先做出處置(例如:遠端回去關機或是打電話給室友拔線等等),省去被斷線的痛苦經驗!


1. 使用方式

您只需使用Line或是Facebook Messenger發送註冊IP訊息至CsieIoBot即可註冊您的宿網IP,立刻享有流量提醒的服務!

  1. 請先確定您已經註冊跨IM通知平台服務,如果還沒的話,請先送出 /add [您的token],例如 /add OOO-12344321
  2. 註冊宿網IP: /dormadd 140.123.123.123 (請記得換成您的IP)
  3. 如果以後想要移除宿網IP: /dormdel 140.123.123.123 (請記得換成您的IP)
就這樣,夠簡單吧!kerker~快點加入這個服務吧!

2. 注意事項

  1. 為了避免訊息轟炸,您只能選擇發送通知到Line或Facebook Messenger
  2. 切換IM通知比你想像中的簡單,直接在該IM平台送出"/dormadd 你的IP"即可完成切換

3. 我想要跑在自己機器上可以嗎?

我們一向欣賞喜歡自己動手做的使用者,所以我們也提供了獨立執行的版本,您可以直接在系上機器運行,安裝及使用方式請參考這個github頁面

4. 有圖有真相

找美食(彩蛋)

出門在外肚子餓想找好吃的餐廳嗎?在Line或Facebook Messenger中傳送你的位置訊息給CsieIoBot,立即取得周遭10家被食尚玩家或非凡美食大探索所推薦過的店家吧!!


有推薦有真相

各類應用通知範例


Server Loading過重通知範例

本範例簡單展示如何將本服務結合進您的monitor script,當系統附載過高時,會自動送出通知至指定IM(並且包含一張loading圖)通知您!


#!/bin/bash
threshold=4.00 # 設定Loading上限
load=`cat /proc/loadavg | awk '{print $1}'`
overLoad=`echo $load'>'$threshold | bc -l`

if [ $overLoad == "1" ]
then
    curl -F 'token=ccurocks-12344321' -F 'msg=不太妙啊~Server的Loading超過設定上限了,快點看一下Loading圖,然後ssh進去檢查一下吧!' -F 'file=@loading.png' -F 'im=line' https://csie.io/msgme
fi
                          

Sample Output:

Dynamic DNS IP變更通知範例

您也可以結合本服務提供的Dynamic DNS服務,如果您的IP變更了即可收到跨IM通知平台!


#!/bin/bash
oldip=`host kerker.csie.io | grep "has address" | awk '{print $4}'`
curip=`curl http://checkip.amazonaws.com`

if [ $oldip != $curip ]
then
    # 更新DNS Record
    result=`echo url="https://csie.io/update?hn=您的hostname&token=您的token&ip=$curip" | curl -k -K -`
    
    if [ $result == "OK" ]
    then
        # 送出Line通知
        curl -G "https://csie.io/msgme?token=ccurocks-12344321&im=line" --data-urlencode "msg=偵測到IP改變,新的IP為:$curip"
    else
        curl -G "https://csie.io/msgme?token=ccurocks-12344321&im=line" --data-urlencode "msg=注意注意!偵測到IP改變,但是DDNS更新失敗!"
    fi
fi
                          

Sample Output:

Rsync備份通知範例

您也可以結合您的rsync備份script以及本服務,可以即時得知備份是否成功!


#!/bin/bash
rsync -r -z -c /home/神秘的D槽 root@1.2.3.4:/home/神秘神秘
if [ "$?" -eq "0" ]
then
  echo "Done"
  curl -G "https://csie.io/msgme?token=ccurocks-12344321&im=line" --data-urlencode "msg=rsync備份完成!所有的寶貴檔案都遠端備份完成了!"
else
  echo "Error while running rsync"
  curl -G "https://csie.io/msgme?token=ccurocks-12344321&im=line" --data-urlencode "msg=rsync注意注意!rsync備份發生錯誤,請記得檢查!"
fi
                          

Sample Output:

Synology通知設定

Synology提供了詳細的警示,可以透過Email或簡訊來發送通知,但今天開始您也可以透過本服務將所有的通知發送至Line或Facebook Messenger,減低資料損毀的機率,而且一切免費!


1. 使用方式

  1. 登入你心愛的Synology,打開控制台後點選通知設定



  2. 點選簡訊分頁,勾選啟動簡訊通知後,點選新增簡訊服務供應商



  3. 輸入供應商名稱並且在測試網址中輸入(如果要發送到Facebook請把im從line改成fb):
    https://csie.io/msgme?a=1&b=2&im=line&token=4&msg=Hello+world



  4. 接著按照下列圖示選擇後點選套用



  5. 最後填寫所有的必要資訊,點選套用後點選寄送測試簡訊



  6. 檢查你的Line或Facebook Messenger是否有成功收到訊息

3. 有圖有真相

QNAP通知設定

QNAP提供了詳細的警示,可以透過Email或簡訊來發送通知,但今天開始您也可以透過本服務將所有的通知發送至Line或Facebook Messenger,減低資料損毀的機率,而且一切免費!


1. 使用方式

  1. 登入你心愛的QNAP,打開控制台後點選通知設定



  2. 點選SMS分頁,點選SMS 服務提供者後,選擇新增SMS 提供者
    輸入SMS 服務提供者
    URL 樣式文字欄位輸入(如果要發送到Facebook請把im從line改成fb):
    https://csie.io/msgme?token=KER-123123&msg=@@Text@@&im=line&a=@@PhoneNumber@@



  3. 勾選啟用SMS 伺服器 SSL 連線,不需填入帳號密碼



  4. 勾選當系統事件發生時,傳送SMS通知至下列電話號碼,隨便選個順眼的國家後,然後填個電話號碼後,點選全部套用,最後點選寄送測試訊息看看是否運作正常!



  5. 檢查你的Line或Facebook Messenger是否有成功收到訊息

3. 有圖有真相




*** 感謝系友Puzi提供QNAP設備協助測試!***

Python呼叫CsieIoBot範例 (純文字)


# coding=utf-8
import requests

msg = u"Python也可以輕鬆送Line通知!"
im = "line" # or "fb" for Facebook Messenger
req_url = "https://csie.io/msgme?token=%s&msg=%s&im=%s" % (LINE_TOKEN, msg, im)

r = requests.get(req_url)
if r.text == "OK":
    print "Line通知成功送出!"
else:
    print "Line通知無法送出 Orz srO"
      

Python呼叫CsieIoBot範例 (訊息+圖片)


# coding=utf-8
import requests

# msg可留空,純粹丟圖
# or "fb" for Facebook Messenger
param = {'token': 'ccurocks-12344321','msg': "Traffic is Money! 目前流量如下圖", 'im': 'line'}
files = {'file': open('mrtg.png','rb')}
req_url = 'https://csie.io/msgme'

r = requests.post(req_url, files=files, data=param)
if r.text == "OK":
    print "Line通知成功送出!"
else:
    print "Line通知無法送出 Orz srO"
      

PHP呼叫CsieIoBot範例


<?php
    $msg = "PHP老而彌堅,呼叫CsieIoBot是ok的!";
    $im = "line"; // or "fb" for Facebook Messenger
    $req_url = "https://csie.io/msgme?token=ccurocks-12344321&msg=" . $msg . "&im=" . $im;

    $result = file_get_contents($req_url);
    if ($result == "OK")
        echo "Line通知成功送出!";
    else
        echo "Line通知無法送出 Orz srO";
?>
      

PHP呼叫CsieIoBot範例 (訊息+圖片)


<?php
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, "https://csie.io/msgme");
    curl_setopt($ch, CURLOPT_POST, true);
    $post = array(
        "file" => "@/home/ccu/snoopy.jpg",
        "token" => "ccurocks-12344321",
        "msg" => "PHP老而彌堅,呼叫CsieIoBot是ok的!",
        "im" => "line"  // or "fb" for Facebook Messenger
    );
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    $result = curl_exec($ch);
    if ($result == "OK")
        echo "Line通知成功送出!";
    else
        echo "Line通知無法送出 Orz srO";
?>
      

Ruby呼叫CsieIoBot範例


require 'rest-client'
require 'open-uri'

token = 'ccurocks-12344321'
msg = URI::encode("許蓋功")
im = 'line' # or "fb" for Facebook Messenger
req_url = "https://csie.io/msgme?token=#{token}&msg=#{msg}&im=#{im}"

response = RestClient.get req_url

if response.to_str == "OK"
  puts "Line 通知成功送出!"
else
  puts "Line 通知無法送出 Orz srO"
  puts "response.code = #{response.code}  , response.to_str = #{response.to_str}"
end
    

Ruby呼叫CsieIoBot範例 (訊息+圖片)


require 'rest-client'
require 'open-uri'

response = RestClient.post('https://csie.io/msgme',
                           'file' => File.new('snoopy.jpg'),
                           'token' => 'ccurocks-12344321',
                           'msg' => URI::encode("許蓋功"),
                           'im' => 'line' # or "fb" for Facebook Messenger
                        )

if response.to_str == "OK"
  puts "Line 通知成功送出!"
else
  puts "Line 通知無法送出 Orz srO"
  puts "response.code = #{response.code}  , response.to_str = #{response.to_str}"
    

Node.js呼叫CsieIoBot範例


var https = require('https');

var options = {
  host: 'csie.io',
  port: 443,
  path: '/msgme?token=ccurocks-12344321&msg=這年頭用Node.js才夠潮啊!!&im=line'
};

https.get(options, function(resp){
  resp.on('data', function(chunk){
    if(chunk == "OK")
        console.log("Line notification sent!");
    else
        console.log("Unable to send Line notification!");
  });
}).on("error", function(e){
  console.log("Got error: " + e.message);
});
    

Node.js呼叫CsieIoBot範例 (訊息+圖片)


var request = require('request');
var fs = require( 'fs');

var formData = {
        msg: 'node.js rocks',
        token: 'ccucs-12345678',
        file: fs.createReadStream( __dirname + "/domo_kun.jpg"),
        im: 'line'
};

request.post({
        url: 'https://csie.io/msgme',
        formData: formData},
        function (err, res, body) {
                if( err)
                        return console.error( 'upload fail :X(', err ,')');
                // noticed: it might get 'badauth' as response
                console.log('upload success! response :', body);
        }
);
    

Golang呼叫CsieIoBot範例


package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
    _ "crypto/sha512"
    "os"
    )

func main() {
    response, err := http.Get("https://csie.io/msgme?token=ccurocks-12344321&msg=用Go送更是潮到出水!&im=line")
    if err != nil {
        fmt.Printf("%s", err)
        os.Exit(1)
    } else {
        defer response.Body.Close()
        contents, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Printf("%s", err)
            os.Exit(1)
        }
        if string(contents) == "OK" {
            fmt.Printf("Line notification sent!\n")
        } else {
            fmt.Printf("Unable to send Line notification\n")
        }
    }
}
    

Golang呼叫CsieIoBot範例 (訊息+圖片)


package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	_ "crypto/sha512"
)

func main() {
	client := &http.Client{}

	request_url := "https://csie.io/msgme"
	form := url.Values{
		"token": {"ccurocks-12344321"},
		"msg": {"用Go送更是潮到出水!"},
		"im": {"line"},
	}

	body := &bytes.Buffer{}
	file_name := "snoopy.jpg"
	body_writer := multipart.NewWriter(body)

	for field_name, field_value := range form {
		body_writer.WriteField(field_name, field_value[0])
	}

	file_writer, err := body_writer.CreateFormFile("file", file_name)
	if err != nil {
		panic(err)
	}
	f, err := os.Open(file_name)
	if err != nil {
		panic(err)
	}
	_, err = io.Copy(file_writer, f)
	if err != nil {
		panic(err)
	}
	f.Close()
	body_writer.Close()

	content_type := body_writer.FormDataContentType()

	req, err := http.NewRequest("POST", request_url, body)
	req.Header.Set("Content-Type", content_type)

	rsp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	body_byte, err := ioutil.ReadAll(rsp.Body)
	if err != nil {
		panic(err)
	}
	rsp.Body.Close()
	fmt.Println(string(body_byte))
}