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. 聽起來不錯,那使用上有什麼需要注意的地方嗎?
本服務的使用限制如下:
- 目前支援Line以及Facebook Messenger平台
- 本服務使用Line官方提供的Bot API,目前該API處於Beta階段,若該API進入正式版本改採收費制度,本服務可能將會取消Line的支援(Facebook不受影響),還請見諒 (fingers crossed)
- 單一則訊息長度為250個字(中英混合)
- 限制單一IP每秒鐘只能夠送三次request
- *** 請注意此token跟DDNS的token不同!不同!不同!(請點選本頁上方"我的token"取得,token最後結尾是一串數字) ***
- 傳送圖片最大上限為4 MB
3. 這正是我需要的!我該怎麼使用呢?
您只需要三個步驟即可註冊使用跨IM訊息通知!
- 首先將您的csie.io帳號與您想要使用的平台連結
- 點擊本頁上方我的專屬token標籤頁,複製您的專屬token: OOO-12344321(注意此token跟DDNS的token不同,請點選本頁上方"我的token"取得,token最後結尾是一串數字!)
- 在手機/電腦的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=哇哈哈~測試一下喔!!'
若您需要傳送圖片,請使用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?
- OK:- 處理成功
- badauth: 認證錯誤
- toolongmsg: 訊息長度超過限制
- 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. 使用方式
- 請先確定您已經註冊跨IM通知平台服務,如果還沒的話,請先送出 /add [您的token],例如 /add OOO-12344321 (請點選上方"我的token"取得token)
- 同樣在本頁上方"我的token"中取得您專屬的email(Line與Facebook不同)
- 在您的系統中或是自行定義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,立刻享有流量提醒的服務!- 請先確定您已經註冊跨IM通知平台服務,如果還沒的話,請先送出 /add [您的token],例如 /add OOO-12344321
- 註冊宿網IP: /dormadd 140.123.123.123 (請記得換成您的IP)
- 如果以後想要移除宿網IP: /dormdel 140.123.123.123 (請記得換成您的IP)
2. 注意事項
- 為了避免訊息轟炸,您只能選擇發送通知到Line或Facebook Messenger
- 切換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. 使用方式
- 登入你心愛的Synology,打開控制台後點選通知設定
- 點選簡訊分頁,勾選啟動簡訊通知後,點選新增簡訊服務供應商
- 輸入供應商名稱並且在測試網址中輸入(如果要發送到Facebook請把im從line改成fb):
https://csie.io/msgme?a=1&b=2&im=line&token=4&msg=Hello+world - 接著按照下列圖示選擇後點選套用
- 最後填寫所有的必要資訊,點選套用後點選寄送測試簡訊
- 檢查你的Line或Facebook Messenger是否有成功收到訊息
3. 有圖有真相
QNAP通知設定
QNAP提供了詳細的警示,可以透過Email或簡訊來發送通知,但今天開始您也可以透過本服務將所有的通知發送至Line或Facebook Messenger,減低資料損毀的機率,而且一切免費!
1. 使用方式
- 登入你心愛的QNAP,打開控制台後點選通知設定
- 點選SMS分頁,點選SMS 服務提供者後,選擇新增SMS 提供者
輸入SMS 服務提供者,
在URL 樣式文字欄位輸入(如果要發送到Facebook請把im從line改成fb):
https://csie.io/msgme?token=KER-123123&msg=@@Text@@&im=line&a=@@PhoneNumber@@ - 勾選啟用SMS 伺服器 SSL 連線,不需填入帳號密碼
- 勾選當系統事件發生時,傳送SMS通知至下列電話號碼,隨便選個順眼的國家後,然後填個電話號碼後,點選全部套用,最後點選寄送測試訊息看看是否運作正常!
- 檢查你的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))
}