git SSL certificate problem

今天在某台 centos 的伺服器上遇到這(下面這段)問題,看似 certificate 的問題,去 google 一下會發現超多種解決方式,看似非常複雜但其實有更快的 workaround。

error: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed while accessing http://github.com/xxxxxxxxxxxxx


這問題應該會發生在 git clone 或 npm install 時,某些 package 造成,但其實就是 certificate 出錯,如果是 git 最快速的解決方式
GIT_SSL_NO_VERIFY=true git clone https://github.com/.......

但是如果是 npm 並沒有辦法這樣下,所以要用另外的方式
export GIT_SSL_NO_VERIFY=true
npm install

togetherjs inject to your web

Togetherjs 是一個 Mozilla 所開發的讓網站多人共同協做的工具,只要瀏覽器有支援立馬就可以開始協做。

只要在下面這段 scripts 加入書籤,之後之要按下書籤就立馬可以開始使用



相關連結
Togetherjs
Mozilla
完整 scripts

Youth 蘋果優仕 iphone 舊換新心得

身旁的 iphone4 已經跟了我三年多,雖然目前功能上都還正常,但順暢度上已經越來越差,整體使用上的感覺當然也是一樣,剛好看到「蘋果優仕」有提供舊換新服務,非常的符合我的需求「解決買新機後舊機處理問題」,加上過去對優仕映像還不差,就這樣決定去換了。

優仕在換機上需要提供三個東西:

1. 手機本體
2. 充電器(iphone 的小豆腐)
3. 傳輸線
4. iphone 的包裝盒

集滿四顆龍珠四個就可以準備出發去舊換新,有沒有發現到少了什麼?購入 iphone 除了這四樣外,還有說明書,SIM 卡的針,以及耳機,下圖中最下面第一點「舊機需附盒裝,變壓器,傳輸線,耳機不交換」,這「耳機不交換」的意思就是「你不需要帶舊耳機,但新機在現場拆開把耳機拿走」,也就是你的新手機是不包含耳機的,如果你想要耳機必須再加「NT. 990」,店員會另外再幫你去拿一個新的 EarPods(不是盒中的),連你想要買盒中的耳機都沒辦法,說實在感覺蠻差的,誰知道這耳機是去哪?



經過了這關後店員就會拿出一張表(下圖)開始挑剔了,依照我的 iphone4 16G,可抵價為 3500,出發兌換前可以先看一下下表,如果扣完的錢不是可以接受的範圍那還是省下這功夫白跑一趟,店員也是很忙的,就算店內人數比店員還少,對你的服務態度也不會比滿滿的人好。




最後順利換到但下一個問題出來了,iphone4 的 SIM 卡尺寸與 iphone5s 不同,蘋果優仕是沒提供這項服務的,必須去找手機行或電信公司的門市,如果是中華電信建議直接去神腦,現場換大約 5 分鐘新卡就可以開通使用。

舊換新只能夠使用現金,如果想刷卡建議還是從蘋果官方比較快。

相關連結
蘋果優仕facebook 粉絲頁

Backbone solve IE ajax cache result

一般來說 Backbone 在針對 model 送 ajax 到後端時使用方法如下:


但在 IE 會針對相同的 ajax request 做 cache,所以必須將 ajax 的 cache 設定為 false,在 backbone 必須要這樣設定:


相關連結
http://stackoverflow.com/questions/6178366/backbone-js-fetch-results-cached

Terminal find a program runing on a port

查詢哪些程式跑在某一個 port

sudo lsof -i :80 # checks port 80

git remove remote branch

一般來說想要刪除遠端的 branch 直接使用:

git push REMOTE_NAME BRANCH_NAME
sample: git push origin dev

但是可能你無意中把 branch 名稱與 tag 名稱設定相同,當你想要刪除時 git 會給你錯誤訊息:
error: dst refspec BRANCH_NAME matches more than one
error: failed to push some refs to 'https://github.com/IskenHuang/xxxxxxxxxxxxx.git'

這時候如果你還是想要刪除遠端的 branch 請改下指令:
git push REMOTE_NAME :refs/heads/BRANCH_NAME
sample: git push origin :refs/heads/dev

相關連結
Deleting remote branches

sailsjs router regex

相信很多人都有在 sailsjs 的 config/router.js 中看到下面這段,這問題就是當 controller 與 static directory 衝突時 router 該如何處理,官方其實在下面這段有寫出解決方案,但實際使用上沒辦法正常運作。

// What about the ever-popular "vanity URLs" aka URL slugs?
// (you remember doing this with `mod_rewrite` in PHP)
//
// This is where you want to set up root-relative dynamic routes like:
// http://yourwebsite.com/twinkletoezz993
//
// You still want to allow requests through to the static assets,
// So we need to set up this route to allow URLs through that have a trailing ".":
// (e.g. your javascript, CSS, and image files)
'get /*(^.*)': 'UserController.profile'

如果想要達到相同的效果可以使用另一個方式如下:
'get /[^.?]+?': 'UserController.profile'

但這時可能會遇上另一個問題,原本 sailsjs 的 router 設計為 :controller/:action,所以如果是想要把所有 '/XXXXXXXXX' 都對應到 UserController 的 action,就沒辦法在 controller 的 req 拿到 req.param('action') 取得要對應的 action,因此可以將上方這段修改為:
'get /:action([^.?]+?)': 'UserController.profile'

修改完後只要是連到 '/XXXXXXXXX' 都會被指向 UserController 的 profile action,而 UserController.profile 的 req.param('action') 就會是 XXXXXXXXX 的名稱,如果是連到 '/logo.png' 等連結會被指向 static directory,這邊也建議如果要使用這種方式請把 profile 改為 index,由 index 來做處理,畢竟 profile 這字這樣使用不太恰當。


如果是想要只開放幾個特殊狀況才進行上面這段可以修改為:
'get /:action(profile|page)': 'UserController.profile'

這樣修改後會發現只有 '/profile', '/page' 會指向 UserController 的 profile,而 req.param('action') 也會拿到 profile/ page,其他的如果沒有 static file 就會被導到 404。


-------- update 2013-11-11 -------
其實這段 regex 跟原本的寫出來會略有不同,真正原因是 sails 會對這段 regex 作些調整:
如果你寫 /:action(*) 會被 sails 轉譯為「^\/(?:( YOUR_REGEX ))\/?$」,而「*」會被改為「.*」也就是所有字元都可以,這部份目前看起來是直接將轉譯後的 regex 對應到 expressjs 的 router。
-------- update 2013-11-11 -------


相關連結
sailsjs document - router

search code in git commit history

常常寫到一半看到過去的一段 code,內心的 OS 不禁嘶吼「WTF 怎麼會這樣寫」,這時候就只好回去找是哪一次 commit,但問題來了,每個 file commit 數量這麼多要怎樣找?還好 git 有提供查詢的功能(淚奔~~~)

如果只是要查詢專案目前的 source 可以使用下面這行,REGEX 就是你想查詢的條件,當然還有很多參數可以帶(請參考:http://git-scm.com/docs/git-grep)

git grep REGEX

如果是要收尋整個專案所有過去的 commit 可以使用下面這行,SEARCH_STRING 就是想要搜尋的字串,FILE_PATH 檔案的路徑,如果是想要搜尋整個專案可以使用「.」,詳細參數可參考:http://git-scm.com/docs/git-log
git log -S SEARCH_STRING FILE_PATH

相關連結
http://git-scm.com/

facebook page feeds

由於看到一些 feed 內容還不錯,但是每次從 RSS reader 看完後再手動儲存下來有點累(我習慣儲存在 google form),雖然每次作一次這種複製貼上的過程中可以再多看一眼,但久了還是會累(已經蒐集了700多筆後...)

Facebook 的 page 有提供 rss feed 給其他網站使用,其提供的型態有三種 AOTM, RSS2.0, JSON,使用方式如下:

JSON https://www.facebook.com/feeds/page.php?format=json&id=246748395427671

ATOM https://www.facebook.com/feeds/page.php?format=atom10&id=246748395427671

RSS https://www.facebook.com/feeds/page.php?format=rss20&id=246748395427671


最後面所帶的 id 就是 pageId,如果不知道 pageId 可以到下方連結查詢,只要把 url 中的 'AppStore' 至換成你的 page 名稱
https://developers.facebook.com/tools/explorer/?method=GET&path=AppStore%2Ffeed

查詢結果會顯示 pageId 如下圖


以上已經完成了一大步,順利取得 Feed 來源,接來來就是快快樂樂使用 Google Apps Script 自動儲存到 google form 中 :)

相關連結
facebook developer
Google Apps Script

SlideNote new feature transition and themes

SlideNote 過去只有一個樣板,我認為字型就像是投影片的靈魂,沒有好的字型看起來就是有點缺陷,所以新增了 8 個字型與配色,以及 7 種過場動畫。

Screenshot


字型、配色:Default, Beige, Moon, Night, Serif, Simple, Sky, Solarized


Transition:Cube, Page, Concave, Linear, Fade, None


相關連結
SlideNote

http response \ufeff

前幾天遇上從 server api 拿到的 response 會在第一個字元收到 \ufeff,jquery 的 ajax 會直接 fail,但直接看 response 會發現 status code 一樣是200,json 的內容也是正常,但 ajax 就是會變成 fail。

目前查詢到的資料來看,這是 utf8(BOM) 的問題, IDE 的編碼在儲存時如果編碼為 BOM 會在第一個字元插入\ufeff,而\ufeff這字元是個特殊的空白字元,一般的 IDE 會自動把這濾掉,所以你將 response 貼上 IDE 想要檢查問題出在哪一般也看不到,建議使用 vim 來看,會清楚的看到這字元,或者 chrome 的 inspect 也會發現如下圖的紅點:


其實這問題看起來真的跟使用的語言無關,似乎與 IDE 關係比較大,從 google 搜尋看起來就是跟網路相關的語言都容易碰上(如下圖)


Nodejs 的 V8 會自動將這字元濾掉,除非你連續寫了兩個\ufeff,不然不會發生,其他語言可能就要注意一下,在發生這問題請不要懷疑自己寫的 code,應該先去查 IDE 的編碼,而這問題也不會是前端的問題,由 server side 處理更為恰當。

grunt-contrib-connect fake api with yeoman

依照現在 F2E 正夯的狀況,很多 front-end 都會希望不需要等 backend 先寫完 api 才可以接資料,或者要等 backend 先開出假的 api 後才能動工,最好的方法就是先確定好資料結構後雙方就可以開工,也可以減少 api 寫完後才發現沒辦法接好的問題。 yeoman 是個相當好用的前端開發輔助工具,尤其 liveboard 大量增加 f5/ctrl + R 的壽命,如果能再結合假資料 api 拿來測試那就再完美不過了。

立馬下載
git clone https://gist.github.com/7210042.git

使用方式 (好讀版
Step1. 下載 redirect.js 到專案根目錄.
Step2. 編輯 Gruntfile.js
var redirect = require('./redirect');

...
...


connect: {
options: {
port: 9000,
// change this to '0.0.0.0' to access the server from outside
hostname: '0.0.0.0'
},
livereload: {
options: {
middleware: function(connect) {
return [
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, 'app'),
redirect('api')
];
}
}
}
},

Step3. redirect 有三個參數. rootDir 是假 api 根目錄. indexFile 是預設連結的檔案. headers 是 http response 的 header,範例:
/app
...

/api
/user
index.json
list.json
...

/Gruntfile.js
...

Step4. run "grunt server"
當讀取 url "/user" 會自動導到根目錄的 "/api/user/index.json"
當讀取 url "/user/list.json" 會自動導到根目錄的 "/api/user/list.json"


相關連結
https://gist.github.com/IskenHuang/7210042
yeoman

SlideNote - markdown makes slides

Markdown 是個很棒的編輯文件方式,尤其在程式文件嵌入原始碼也是非常方便,甚至坊間也很多專門做 Markdown 的編輯器,但是每次整理完文件如果需要再做出一份簡報同時就會造成很大的困擾:

1. markdown 要怎樣 copy/paste 到 keynote/powerpoint 上?
2. 基於理由一,乾脆放棄,開始問:「能不能直接用 markdown 來簡報?」

所以認為最根本的問題是「怎樣直接拿 markdown 做簡報」,方法很多,直接轉換為 ppt(powerpoint)/key(keynote) 檔、讓 markdown preview 為 slide show、直接線上轉換為 slide,這些想法都非常棒,但為了最快速解決「怎樣直接拿 markdown 做簡報」的問題做了現在的「SlideNote

SlideNote 主要的目標:
1. 用 Markdown 直接產出 Slide
2. 完全使用 Markdown 語法
3. 線上編輯,線上產出

截圖 slide show


截圖 編輯 markdown 文件


截圖 首頁



因為快,所以很多東西都還不完整,歡迎隨時來亂玩它,有問題或建議首頁左下角有 feedback 可以馬上回報給我:)

相關連結
SlideNote

nodejs hosting service - openshift

nodejsgithub wiki 上可以找到一個頁面為 Node hosting 上面有相當多的服務可以選擇使用,著要是測試用機器,所以幾個重點條件就是:

1. deploy 後立馬可以使用
2. 可以跑 nodejs 並且支援 0.8+ 的版本
3. 使用 Git 做版本控管
4. 免費(超重要)

基於以上條件目前使用過兩個服務:
1. heroku
2. openshift

這次先來介紹 openshift,oepnshift 是頂頂大名的 redhat 提供的服務,這次使用的是 openshift online,產品定位為 Public Paas,有支援語言:Nodejs 0.6+, 0.10+, JAVA, PHP, Python, Ruby, Perl, GO (註1),或是可以直接在上面架設 Jenkins, Drupal, Wordpress 可直接開啟不需要自行 deploy。 openshift 官方還有寫了一套 Command-line client 工具來對 deploy 上去的 app 坐操作,關閉、啟動、重起、目前的 log 等,詳細可至官方查詢

當然最重要的 openshift 符合我們所有的條件,並且免費的 Gear(instance) 可以開三台,如官網價錢
Size MemMemory Storage Recommended for Cost
Small 512 MB
1-6GB
1GB
expandable

PHP, Perl, Python, Ruby, Node.js, MySQL $0.04/hour
after the first 3
Medium 1GB
1-6GB
1GB
expandable

Java, MongoDB, PostgreSQL $0.10/hour
Medium (with JBoss EAP 6)
Java EE6 Full Profile
1GB
1-6GB
1GB
expandable

JBoss EAP $0.13/hour




這麼佛心看到只能馬上跪下說聲「謝主龍恩」不然也不知道該怎麼辦,目前使用上除了 deploy 速度很慢(相較起 heroku),web 介面非常醜並且不人性化,常常找不到資料,官方文件看不太懂以外,其實還蠻不錯的,畢竟是要免費的測試機還是別太苛求。

目前就一點特別需要注意,deploy 上去後 port 與 root url 設定上與一般不太相同,必須修改如下:
port 必須設定為「process.env.OPENSHIFT_NODEJS_PORT」
root url 必須設定為「process.env.OPENSHIFT_NODEJS_IP」

sails 為例,local.js 必須修改如下


註1. 除了nodejs 外其他語言支援版本可至官方開發者中心查詢

相關連結
nodejs
github wiki
Node hosting
heroku
openshift
openshift developer center
openshift Command-line client
openshift pricing
sailsjs

node-hipchat

Hipchat 是一套相當好用的 Log system,還可以與 Github, Bitbucket, jenkins......等服務整合,團隊中打屁的同時還可以看到系統狀況,因為 Hipchat 官方給 nodejs 的不知道在寫啥鬼,所以就自己寫了一個簡單的版本

使用起來相當簡單,詳細可以參考如下,完成後就會看到你的 room 中噴出兩筆 log

var hipchat = require('./lib/hipchat');

// log warn
hipchat.logger('Hello hipchat logger - warn', 'warn');

// log error
hipchat.logger('Hello hipchat logger - error', 'error');

這麼好用的東西當然要立馬 clone
git clone git@github.com:IskenHuang/node-hipchat.git


相關連結
Hipchat
IskenHuang/node-hipchat

gitst embed one file

Gist 是個放置少量的 code 或 blog 很好用的東西,但有時候可能是一個 Gist 內放了很多的檔案,這時如果複製貼上「<script src="https://gist.github.com/IskenHuang/b5bb5bc9b56a15452d6e.js"></script>」就會發生一次把所有的檔案都嵌入,但這中間可能需要嵌入一寫字來說明每個檔案間的關係就變很麻煩。

這時候只需要複製原本的連結再加上「?file=FILE_NAME」就可以只貼上一個檔案,範例如下:

<script src="https://gist.github.com/IskenHuang/b5bb5bc9b56a15452d6e.js?file=structure.md"></script>

切記,檔案名稱大小寫必須與 Gist 上面相同,不然無法正常使用

想關連結
Gist

sailsjs differentiate api and view controller

Sails 是一套我相當喜歡的 Node.js web framework,底層仍然是使用 Express.js,另外整合了很多常用的 web 套件:grunt, socket.io, RESTful API, ......等。

由於 sails 的架構與 codeigniter 相當類似,Controller 對應到 View,並且對應到 route,在 config 中有個 controller.js 還可以對所有的 controller 做設定,如自動產生 restful api 等,以及這次的重點「prefix」,prefix 設定後在 route 上就會自動改變如下

使用 prefix 前
http://localhost/CONTROLLER_NAME/ACTION_NAME

使用 prefix 後( prefix 設定為 '/api/')
http://localhost/api/CONTROLLER_NAME/ACTION_NAME

如果只是要做 api server 相信這會是個很棒的設計,還可以作為 api 的版本區分(例如「/api/v1/」),但要做「網站」在 view 與 api 之間就必須做些區分,以下的作法就是將 view 與 api 切開,view 統一由 ViewController 控制,其他的 api 交由一般的 controller 控制,從 route 看起來如下
// ViewController
// Get user or user's view
http://localhost/user

// UserController
// Get user '1' api
http://localhost/api/user/1

資料夾目錄如下


接下來開始實作把 api 與 view 切開
首先是設定好 api 的 prefix,修改 「/config/controllers.js」


再來是設定 route 把 view 改為 '/',修改「/config/routes.js」
routes.js


最後是產生 ViewController,在 terminal 輸入
sails generate controller view

並修改 「/api/controllers/ViewController.js」



ps. 或許也可以直接做 single page design,但某些狀況下透過 controller 可以從 server side 將其他訊息一併回給前端

完整的 code 可至 Gist 查看

相關連結
Sails
Node.js
grunt
socket.io
Express.js
codeigniter

iOS restore and upgrade

相信很多人都有升級 iOS7,並且在 beta 測試時就搶先使用幫助 apple 來 debug,這種就甘心的情操實在很偉大,但是使用了 beta 版本後卻沒辦法升級為正式版實在是很嘔的事,當然你可以再去開發者頁面下載最新的 build 來重刷,或者可以直接靠 itunes 來進行升級,以下就介紹如何使用 itunes 直接升級,只需要幾個步驟:

step1. 準備一條線連接電腦,一隻安裝了 beta 或舊版本的手機
step2. 把手機關機,把線接上手機,並且不要連接著電腦
step3. 持續按著 home 鍵(直到說要放開前請持續按著)
step4. 把線接回電腦,等到看到 itunes logo 再把home 鍵放開
step5. 按照 itunes 的步驟完成

Inside salon #2 千萬下載等級遊戲開發商 Orange Nose Studio 創業與中國經驗分享 - 重點整理

我是個不太常在手機上玩遊戲的人,大多會玩遊戲就是為了打發時間,而 Orange Nose studio 出的遊戲完全是主打我這族群,無腦的遊戲有助於紓壓(無誤)。

這邊來重點整理一下這次所聽到 Leon 所談的重點,省略前面自家的火力展示,以下未依照演講時順序,未必完全與演講用字相同,僅以當時筆記為主

  • 成功的原因
    • 找到對的TA (不玩遊戲的人)
    • 找到對的市場,市場一定要夠大,並且具發展性
    • 30 秒測試
      • 用 30 秒對一個沒用過的使用者測試,30 秒如果沒辦法提起興趣那這個人就不是你的 TA或你設計根本有問題
      • 測試時什麼都不要說,在旁安靜的觀察使用者
      • 偷偷跑去手機店把要測試的 App 安裝到展示機上,然後躲在旁邊觀察,最好還可以先把 App 打開後再去旁邊觀察,確保使用者一定是看到這 App(先前我自己在寫 Android 也想過這方法 XD,這也許是個 business model)
    • 免費
    • 同時間在多個平台( ios, android )上架,所以類似 cocos2d 這類的 framework 會是你的好夥伴
    • 病毒式成長
      • 前期還是需要打廣告增加曝光量,但前期購買下載量 CP 值不高
      • 廣告再多還是比不上病毒行銷的擴散速度
      • marketing 再怎樣強還是比不上產品好
      • app + market = viral
    • 好的評分( rating )
      • 如果評分低於 4 顆星那肯定是產品出問題了,有 1顆星出現那肯定是會有 crash 或無法正常進行遊戲
  • 做一個好的遊戲
    • 選一個屬於你的市場
      • 不一定要做的特別快,但一定要想清楚
      • 維持在高的評分( rating )
      • 別只能跟電腦玩,加入社群元素可以發展更快
        • e.g. race cars vs race with friends
          • race cars - 那市場限定在熱愛賽車的人
          • race with friends - 市場肯定比 race cars 大,重點是妹也會玩
      • 最好是免費的
        • 免費市場肯定比付費市場大
        • 免費第一名下載量大約等於付費的 10 倍
      • 跨平台 ( ios, android )
    • 了解你的市場
      • 觀察同一個市場上其他優秀 App 怎麼做
      • 觀察這些優秀 Apps 的留言,看到其實哪邊還可以再改進,使用者喜好
      • 觀察市場的大小
      • 詢問自己,是否適合這市場
    • First love in 30s
      • 使用前 30 秒幾乎是掌握會不會再使用下去的關鍵(很多使用者下載後是不會開啟 App 或不了解馬上刪除)
      • Icon, title 就是吸引用戶的第一步,不好看的 icon 下載機會大幅降低
      • 如果 30s 測試無法成功通過那就表示這 App 有問題
      • 通過 30s 測試後詢問使用者
        • 了解 or 疑惑
        • 是否對某個片段有映像 or 失望
        • 是否喜歡
      • 如果可能一定要做使用者測試
    • 做出產品
      • 計畫 milestone 和 上市時間
      • 除了做使用者測試外也要做市場測試
        • 市場測試可以利用國家為範圍,香港是個很好的測試環境,測試結果幾乎會與全球差不多
      • 找出最好的付費點,做 App 是要賺錢的
        • 大多要依靠 經驗、測試,然後微調
    • 賣出你的產品
      • 可以考慮 itunes 最為你的第一個平台
      • 找出最划算的下載 預算
        • 投遞不同方式、種類的廣告,多嘗試幾個不同的通路
        • 想要大量下載基本上還是要靠錢
        • 目前(CPI) 單價越來越高(2~3+ 美金/每個下載)
      • 確保排名在前面
        • itunes 的規則前兩三個月才又改過,要靠長期觀察
          • 使用率
          • 下載量
          • 刪除率
          • 好的品質(raking)
        • Google 會依照多少人砍了你的 App
        • 各家 store 都會營造出榜單是活的感覺(常常跳動)
        • 不一定要衝上第一,前幾名一樣很有用
      • 從小的市場開始,早期測試早期修正
      • 考量長期的拓展模式
      • 考慮內至廣告模式賺錢
        • 不同國家使用不同家廣告,找出最自己最有利的
        • 最好設計成可線上切換廣告模式,多測試幾家不會錯
        • 影片廣告 ( e.g. vungle )
      • 3rd 網站廣告購買
      • android 可以考慮跟 Tapjoy 合作
      • 跟發行商合作 Chillingo
  • 中國市場
    • 市場大小
      • 250m 智慧型手機
      • 超高成場率
      • 中國市場 幾乎等同於 全球(中國以外國家)市場
    • 中國境內大約有 200 個以上的 android apps store
    • 中國使用社群
    • 手機出場 bundle app 也是常見的行銷方法
    • 收費
      • 管道
        • 電信商
          • 抽 30%
          • 提供小額付費
          • 一定要包自家的SDK(每一家都不同)
          • 還可能會被電信商要求改介面(不改不能上架)
        • 在地出版商
          • 抽 40 ~ 60%(也有抽到 90%)
          •  360, 91, baidu, ....等
          • 很可能會要求簽首發(eg. 一個月內只能在某個 store 賣)
          • 一定要包自家的SDK(每一家都不同)
        • 代理出版
          • 抽 50%
          • 你中國的窗口
          • 會幫你想辦法打擊盜版
            • Leon 提到當地盜版商甚至會把你的 App 盜版後要求正版下架,除非你花 XXX 元來買通
          • 會幫你進行手機測試,中國很多沒牌的手機
          • 會幫你通過審核
            • 一般審核約 1~2 個月,透過合作出版商大約 1 週
        • 在中國沒有設立公司妹辦法透過電信商收費
        • 一般來說大概僅剩下 12% 實際收益
      • 在地化
        • 一定要用中國用語
        • 但不一定要翻譯的很完整,因為太完整可能會被當做中國本土產品
      • 收費模式
        • 中國 IAP 模式收費為 2, 4, 6 元(人民幣)
        • 6 元(人民幣)已經是最貴
        • 以 causal game 來說中國會玩的人收入大多不高,2 元(人民幣)是非常願意付費
        • 不要讓使用者玩太久,玩太久就不付錢,所以有些 App 甚至是限定時間,超過 5 分鐘就需要付費
        • 中國 App 不能放廣告
      • 中國在地遊戲 vs 全球遊戲比例大約為 6 : 4
      • 在地出版商合作
        • 營收拆帳 + MG(保證金,超過XXX量後再跟你算)
        • 360 不給 MG
        • 有 MG 比較有保障,多少就是靠談判
        • MG 越高,因為電信商想賺回來,所以會更努力賣
        • 貨比三家不吃虧
      • 進入中國市場需要擁有的特殊技能
        • 整合各家 SDK (各家都有自己的)
          • 如果放心的話可以直接給 source code,對方會幫忙整
          • 如果是好遊戲,其他平台版本對方都可以幫忙做
        • 翻譯成中國用語
      • 如何進入
        • 找到一個好的管道
        • 整合當地的付費方式
        • GOOD LUCK


相關連結
Orange Nose studio
http://registrano.com/events/isalon2
ios
android
cocos2d
itunes
Google play
vungle
freeappaday.com
AppGratis.com
Chillingo
360
91
baidu
安卓
中國移動
中國聯通
新浪微博
騰訊微博
人人

sublime ascii plugin

自從看到這張圖(圖一)馬上笑了出來,想到之前在 LiveAll 以及做 Trend Micro yeoman generator 的時候也一樣畫了很多 ASCII 圖片,但從來沒想到這些 ASCII 的圖片可以在 Sublime 的 minimap 變得如此方便!


這邊來介紹幾個 Sublime 目前的幾個 畫 ASCII 的 plugin

ASCII-Decorator
ASCII-Decorator 提供了很簡易但又實用的功能,也是最接近這次我們所需要的功能,其中預設字體為 slant ,雖然與看到的圖片中不太相同,但這其實可以換字型的!在 package settings 中可以設定你想要的字體,字體列表中可以來慢慢的找到你想要的字型,選取字型後按下 super+shift+K or alt+shift+K 就可以把字轉換



ASCIIPresentation
ASCIIPresentationASCII-Decorator其實很類似,但功能上又更多了點,可以加上顏色,還可以畫出些視窗的外框等功能



ASCII-Cowpletions
最後介紹這個算是這次的意外發現,內建了相當多種的牛可以快速的畫出,還提供了下拉選單來選取XD,可參照下圖



相關連結
Sublime Text
Sublime Text - plugin
LiveAll
Trend Micro yeoman generator
ASCII-Decorator
ASCII-Decorator 字體列表
ASCIIPresentation
ASCII-Cowpletions

圖一:https://pbs.twimg.com/media/BURbS2pCcAAaG7z.png:large#.png

水、電、瓦斯 電子帳單

相信很多人家裡的水、電、瓦斯等帳單都是使用紙本,由於紙本實在是不好管理加上電子化公文等理由,其實水、電、瓦斯帳單不但可以直接銀行、信用卡扣款,還可以線上申請把原本的紙本帳單轉為電子郵件,當然如果想要保留原本的紙本帳當寄送(同時有電子帳單 + 紙本帳單)也是可以。

也因為這次想要申請電子帳單的緣故讓我了解到,原來我家的自來水並不是台灣自來水公司,而是台北自來水事業處,這兩個要怎樣分呢?
首先先看一下你家水費帳單上左上部分有個紅色區塊分別寫著「大區、小區、戶號、檢」這四個欄位,如果有的話那你家的自來水是屬於台北自來水事業處
如果沒有就表示你家自來水來自台灣自來水公司,而台灣自來水公司使用為「站所(2碼)、編號(8碼)、檢算號(1碼)」
當然更快的方式就是看你家是不是在台北市Orz...



*重點
如果要申請電子帳單各家都需要各家自己的「編碼 (id)」這些「編碼 (id)」在帳單上都有,申請前先準備好之前的帳單可以減少很多不必要浪費的時間



相關連結
台灣電力公司
台灣電力公司 電子帳單申請
大台北瓦斯
大台北瓦斯 電子帳單申請
台灣自來水公司
台灣自來水公司 電子帳單申請
台北自來水事業處 電子帳單申請

Facebook like button document.domain issue

今天遇到了一個 facebook like button 的問題,錯誤訊息如下

Blocked a frame with origin "https://www.facebook.com" from accessing a frame with origin "https://platform.twitter.com". The frame requesting access set "document.domain" to "facebook.com", the frame being accessed set it to "twitter.com". Both must set "document.domain" to the same value to allow access. l5vDWYcNnY2.js:41
2
Blocked a frame with origin "https://www.facebook.com" from accessing a frame with origin "https://apis.google.com". The frame requesting access set "document.domain" to "facebook.com", but the frame being accessed did not. Both must set "document.domain" to the same value to allow access. l5vDWYcNnY2.js:41
2
Blocked a frame with origin "https://www.facebook.com" from accessing a frame with origin "https://accounts.google.com". The frame requesting access set "document.domain" to "facebook.com", but the frame being accessed did not. Both must set "document.domain" to the same value to allow access. l5vDWYcNnY2.js:41

以及跳出(下圖) popup 然後怎麼點 "Post to facebook" 都沒辦法順利送出(成功送出 popup 會關閉)




當下看到這錯誤訊息只想到兩個可能性
1. https
2. 可能跟其他家( twitter, google+ )按鈕衝突

twitter, google+ 都可以正常的運作,唯獨 facebook 在按下 like 後跳出的 popup dialog 無法順利送出,經過 Google 大神的協助後發現案情並不單純,like button 是使用 facebook 所提供的 html5 版本,內容沒做任何修改,理論上 facebook 發生這種問題的機率肯定比我低,經過許久的查詢發現了 Facebook Debugger,顯示內容如下

其中中間那段為:There was an error in fetching the object at URL 'http://***************************/', or one of the the URLs specified via a redirect or the 'og:url' property including one of http://*********************.


Debugger 很清楚的寫出 og:url 連結是不是有錯?請再確認,因為 og:url 要連的頁面不但 redirect 到另一個頁面,並且由 https 變為 http ,facebook 認為是有問題(就甘心)

結論(廢話結束...)
需要使用 Like button 時可在產生 Like button 的頁面先行測試看是否可以正常使用(把 URL 先帶入試試看),如果不行請先到 Facebook Debugger 查看問題點在哪


相關連結
Facebook Debugger
Facebook like button

Facebook and google+ share title description thumbnail link display

先前寫過一篇社群分享按鈕總整,整理了各大社群分享的連結,但分享後長什麼樣子也是與分享後的成效有相當的關係,這邊來介紹一下 Facebook, Google+ 的分享內容。

可以設定的如簡單幾項,更多細節可以參考官網文件,或參考下方圖片(圖一)

<meta property="fb:app_id" content="FACEBOOK_APP_ID" />
<meta property="og:type" content="SHARE_METADATA" />
<meta property="og:url" content="SHARE_URL" />
<meta property="og:title" content="SHARE_TITLE" />
<meta property="og:description" content="SHARE_DESCRIPTION"/>
<meta property="og:image" content="IMAGE_URL" />
<meta property="og:site_name" content="SITE_NAME"/>

如果不知道或是沒有的請隨手把他刪掉,這時候如果有疑問 "都沒設定那會show出什麼" ,這時候只好說《侏羅紀公園》(Jurassic Park)中的經典台詞:「生命總會找到出路。」(Life will find the way.),可以使用官方提供的工具來檢查分享後的樣子,以及哪些部分需要調整。


Google 大神更是提供了簡單的網頁工具提供你快速產生 Web Snippet,可參考下方圖片(圖二)

<body itemscope itemtype="http://schema.org/Product">
<h1 itemprop="name">Shiny Trinket</h1>
<img itemprop="image" src="{image-url}" />
<p itemprop="description">Shiny trinkets are shiny.</p>
</body>

Google 提供了幾種不同的方式,如果你不依照上方的設定方式,優先會去查找 Open Graph "og:title, og:image, og:description" 的參數,如果還是都沒定則會以 page title 以及 meta description 來設定。

相關連結
社群分享按鈕總整
Facebook Using Self-Hosted Objects
Facebook Debugger
Google+ Snippet
圖一 - http://kb.mailchimp.com/article/how-can-i-choose-the-image-thumbnail-that-shows-up-on-facebook
圖二 - https://developers.google.com/+/web/snippet/

Insert CSS style into html head in build process

網頁速度慢除目前看起來最大問題就是 http request 數量太多,因為每次的 request 都需要一定的時間,如果能夠壓縮在同一個 request 是最棒的狀況,前面幾篇有把 Javascript 用 uglify 把檔案壓成一支,以及把小的圖片轉換為 data uri 隨著 html/css 一同載入,這次要做的是把 CSS 直接以 <style> tag 直接塞入 html 的 head 中,讓 CSS 的隨著 html 一起載入,請小心使用

這次的 script 一樣是由 coffeeScript 寫成,以及使用 cheerio 來作 dom select


立馬下載使用



相關連結
image in csshtml from url to uri
html script tags combined a js flie
uglify
coffeeScript
cheerio

image in css/html from url to uri

上次寫了一個單獨一個檔案轉換為 data uri ,但在網站圖片尚未完全確定前這樣做事相當花費時間而且難以驗證檔案,所以再寫了一個 script 夾帶再出 build 流程中,方便的把圖片轉換為 data uri,當然 data uri 沒辦法適用所有的圖片,所以 script 中的 minSize 就是設定要轉換的圖片尺寸上限,單位為 pixel (大約計算出檔案大小),由於 html parse 重寫一次比較麻煩,所以使用了 cheerio 方便做 dom selector

由於許久沒寫 coffeeScript 決定用這 script 快速複習一下



相關連結
cheerio
nodejs image to Data uri
coffeeScript

html script tags combined a js flie

最近每天都在做網頁效能優化,過去 javascript 可能因為很多 plugin 增加了很多 request 次數,或許可以使用 parallel 方式來加速,但始終沒解決浪費頻寬問題,使用 uglify 可以方變得解決需要壓多個 javascript ,但如果網站有一堆頁面都要這樣做一次,每次出 build 都要做一次是非常累人的事,因此寫了一個 script 來處理這個累人的問題。之後再找時間來處理些 error handle 以及,包成一個完整的 module

使用方法很簡單,下載檔案後要先設定好幾個重要的路徑

// javascript 資料夾路徑(相對路徑,相對於 uglify.js這檔案)
JSRootUrl = __dirname + '/js/',

// html 資料夾路徑(相對路徑,相對於 uglify.js這檔案)
viewRoot = __dirname+ '/../application/views',

// 要略過的檔案名稱( html 資料夾)
skipFiles = ['.DS_Store', 'mail'],

// 壓縮完的檔案名稱後需要加上哪些文字,例如 main.min.js
suffix = '.min',

// 要壓縮哪些 scripts 設定( html 資料夾的 tag 名稱)
jsTagRegex = /\\<\/script\>/ig,
設定完後只要下簡單的一行,就會進行兩件事 1. 把 html files 符合 "jsTagRegex" 這規則的 javascript 拿掉,取代為 <script src="XXXXX.min.js"></scrips> 2. 把 html 頁面中會需要用到的 javascript 壓成一支
node uglify


相關連結
uglify

Quick launch nodejs expressjs web server

Expressjs 是一套 nodejs 上非常熱門的 web framework ,提供了相當彈性的功能,豐富的社群支持,是個很棒的 nodejs web framework 選擇,但身為前端工程師常常需求只是 "想要建立一個單純的 web server ",這需求達成方法有很多, apache, nginx 等都可以達到想要的功能,但如果是同時間需要多開幾台 servser 模擬,或好多個專案在不同資料夾中透過 apache, nginx 設定可能不是這麼快速(好吧...應該是我手殘)

立馬下載

使用方法
Step1. 安裝 nodejs & npm (download: http://nodejs.org/download/)

Step2. 安裝 expressjs (http://expressjs.com/) 在 global
$ sudo npm install express -g

Step3. 立馬開始使用
$ node app

預設的 PORT 為 3000,根目錄路徑為 與 app.js 相同路徑,如果還要再多開一個呢?請多開一個 terminal ,然後再下一次" $ node app ",這時候應該會遇到錯誤訊息告訴你 server 已經開啟,所以提供了另一個功能,可以自訂 PORT 以及根目錄

開啟在 web server 在 8000 PORT 根目錄為 web1
$ node app 8000 ../web1

開啟在 web server 在 9000 PORT 根目錄為 web2
$ node app ../web2 9000


* PORT, 根目錄兩個參數前後順序可以自訂




相關連結
Expressjs
apache
nginx

nodejs image to Data uri

前端為了減少 request 數量可以說是用盡各種方式, Javascript 壓成一支, css 壓成一支,圖片用 image sprite 壓成一張大圖,用盡各種方式把 request 數量減少,讓使用者體驗變得更好。

對於圖片來說 image sprite 是一種很好的方法,但是總會問一下自已「能不能更好?」於是找到了 Data uri 的方式,把圖片轉換為字串,跟著 html, css 一起載入, HTML 的img tag 的 src ,或者 CSS 的 backbround-image 一並載入。產生 Data uri 有些線上工具可以使用,但基於懶人精神 懶得按滑鼠、懶得選取檔案、懶得連上網路(那你做 web 幹嘛!?) 所以就寫了一個簡單的工具,目的當然很簡單,不用上網( local 可以解決),不用使用滑鼠( command line 就可以執行),產生完自動幫我複製到剪貼簿(立馬可使用 ctrl + v)

根據 Caniuse 表示 Data uri 在 IE8+, firefox 2.0+, chrome 4.0+, safari 3.1+, opera 9.0+, 以及所有的 mobile browser 都有支援,所以網站如果是支援 IE8 以上的網頁應該是可以安心服用。

Gist - https://gist.github.com/IskenHuang/6434813

使用方法很簡單在下載後的檔案同目錄下輸入

node img YOUR_IMAGE_PATH

馬上就產出 data uri 並且複製到剪貼簿中,立馬享有 ctrl + v 快速產出的快感( Mac only ),產生出來的字串包含了 data:image/png;base64, 所以直接貼入 HTML img 的 src="PASTE_HERE" ,或 CSS background-image 的 url( PASTE_HERE ) 中。

source


相關連結
Caniuse - datauri
Gist - https://gist.github.com/IskenHuang/6434813

SUNYORY烏龍茶 + CC Lemon

由於看到 把檸檬水倒入烏龍茶後我震驚了! 覺得蠻神奇的,基於實驗精神決定自己來嘗試看看


首先確認是「SUNYORY烏龍茶」以及「CC Lemon」,雖然CC Lemon不是與影片中相同瓶子,但同一家的產品應該是可以確認的。


先將烏龍茶打開並倒入杯中


最後就是見證奇蹟的時刻



真的很神奇,因為一點反應都沒有!?兩種混合後喝起來有種「檸檬烏龍茶」的感覺(廢話),說實在不太對味,還是一句老話「認真就輸了」


題外話,為了做這實驗才了解到瓶裝飲料原來這麼貴,我是在住家附近的全家所購買,SUNYORY烏龍茶要價「39」CC Lemon要價「29」新台幣,而且購買後才發現原來兩家都同為SUNYORY公司旗下產品,不禁讓人有種炒作的感覺。


相關連結
SUNYORY烏龍茶
CC Lemon

[MAC software] 網路限速(port)

以前在PC上有很方便的Netlimiter可以來限速,尤其在宿網中更是扮演重要角色,如今已經不再需要住宿舍,但需要模擬網路不好的狀況,這方法很多,可以從router下手,現在很多router都有支援qos,也可以從軟體下手,其中軟體端可以限制的又更廣,可以針對不同的process、application、port等。

這邊介紹一套輕量的MAC版網路限速「entonnoir」,功能稍微陽春,僅可以限制PORT,但已足夠限制一般的上網行為,只要限制http(80), https(443)應該大多站都可以"享受"到限速的感覺。

entonnoir 立馬下載

開啟後就只會看到這簡單介面,按下「+」「-」就可以新增/刪除需要限制的PORT,下方可以限制上傳下載的速度,完成後按下右上角的"Throttling",當顯示為綠燈時就開啟了限速,再按一下就會回到紅燈(關閉)



相關連結
Netlimiter
entonnoir

jquery.min.map not found error 404

這陣子遇到一個問題,因為 "jquery.min.map" 找不到這檔案而造成https 變為驚嘆號三角形,變成驚嘆號三角形當然有很多可能,例如在https下使用了非https文件(讀取了任何檔案)。

後來上網查了一下看到這篇"jquery.min.map 404(not found)"其實說明的很完整,需要解決這問題簡單來說有幾個方式

1. 別用jquery(誤 jquery表示:「怪我囉」)
2. 加上jquery.min.map檔

追根究柢問題還是為什麼會load這個.map檔,可以參考Introduction to JavaScript Source Maps,如果用最簡單一句話來形容就是debug方便,讓browser報錯同時清楚的告訴你是哪一行出了問題,jquery官方也說明了為何使用.map檔

如果有中文閱讀比較習慣的也有一位熱心的人士寫了一篇中文介紹Javascript source map 功能詳解

相關連結
jquery.min.map 404(not found)
Introduction to JavaScript Source Maps
jquery New! Source Maps
Javascript source map 功能詳解

Social share button i18n

先前有一篇提到Social share button的建立方式,但在某些狀況下這個分享按鈕是需要在地化的,讓不同語言更融入(增加點擊的機會),這邊介紹Facebook, Google+, twitter這三個做i18n的方式

Facebook
Facebook有分為兩種方式分別為「XFBML」、「iFrame」



XFBML
'//connect.facebook.net/en_US/all.js';

iframe
src="http://www.facebook.com/plugins/like.php?locale=fr_FR&..."

特別注意
1. en_US的大小寫方式,Facebook是使用前兩碼小寫,後兩碼大寫,中間使用 _ (underline)隔開
2. 範例中設定為中文zh_TW


Google
Google+必須在window加入一個參數,在載入按鈕前



window.___gcfg = {
lang: 'zh-TW'
};

特別注意
1. en-US的大小寫方式,Google+是使用前兩碼小寫,後兩碼大寫,中間使用 - (dash)隔開
2. 範例中設定為中文zh-TW


Twitter



<a href="http://iskens.blogspot.com/" class="twitter-share-button" data-via="IskenHuang" data-lang="zh-tw">推文</a>

特別注意
1. en-US的大小寫方式,Twitter和Google+一樣是使用前兩碼小寫,後兩碼大寫,中間使用 - (dash)隔開
2. 範例中設定為中文zh-TW



相關連結
Facebook like button - https://developers.facebook.com/docs/reference/plugins/like/
Google+ +1 button - https://developers.google.com/+/web/+1button/
Twitter button - https://twitter.com/about/resources/buttons#tweet

Gravatars profile image

如果有使用 Gravatars 這服務來管理頭像( Ex. Github, NPM, Wordpress, balabala...),請記得你所申請的服務 Email 一定要與 Gravatars 的相同,不然大頭照無法順利的連結起來,如果有不止一個 email 請記得在申請的同時把當前要申請的 email 設定為 Primary ( Make Primary )


Reference: Gravatars - https://en.gravatar.com/

ubuntu git clone error: server certificate verification failed

ubnutu git clone error message

Cloning into 'trend-branding-styleguide'...
error: server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none while accessing https://gitlab.tw.trendnet.org/randy_lien/trend-branding-styleguide.git/info/refs
fatal: HTTP request failed

input below in the shell
$ export GIT_SSL_NO_VERIFY=1

Reference: https://blog.breadncup.com/2011/06/09/skip-git-ssl-verification/

bower can't fetch components(very very slow)

這最主要原因就是bower server只接受"https://"不接受"git://"來的protocol,解決方式就是修改git設定

git config --global url."https://".insteadOf git://

相關連結
bower github wiki - https://github.com/bower/bower/wiki/FAQ#how-can-i-use-bower-with-only-https-urls-and-not-git

bower error status code of git: 128

這其實是bower要更新到local cache中發生衝突,最主要的目的就是要把cache清掉,解決辦法可分為兩種


1. 用bower的功能直接將cache清掉
bower cache-clean

2. 手動將整個bower所有的cache清掉(MAC 路徑)
rm -rf ~/.bower


但如果是下載當中一直卡住請參考下連結
http://iskens.blogspot.tw/2013/06/bower-cant-fetch-componentsvery-very.html

相關連結
https://github.com/bower/bower/issues/50

grunt-contrib-imagemin spawn EMFILE

如果grunt跑imagemin跑出下面這問題
Warning: spawn EMFILE Use --force to continue

請在terminal輸入
sudo ulimit -n 4096


相關連結
https://github.com/aheckmann/gm/issues/42

iPhone todo(GTD) app review

時間管理非常重要,如果管理的很好的人自然是不需要,但是依靠點工具可以把這複雜的事情變得更簡單。就以我來說大多的固定事件、全都記錄在Google calendar,不但可以同步在各個的電腦(PC, MAC, Linux)、行動裝置(iPhone, iPad, Android, Windows8),並且可以設定提醒(Email, SMS, 推播)在指定的時間,但還是有些小問題,例如:已經辦完的事情不會消失,所以看到很多All Day's event,如果有個事情可能是在未來的某一天但詳細的時間地點都還不不確定......等的問題就以Google calendar來說還是不太方便達成,因此Google有推出了Google Task來解決此問題,Google Task非常的棒,整合在Google calendar中,但是只能在Google calendar中使用,離開了Google calendar就沒辦法如同Web整合的這麼好,也因此的讓我歸類出幾個todo app重點需求:
1. 需要可以整合Calendar 或支援 iCal
2. 多平台支援,至少要可以在iPhone, 電腦上編輯
3. 支援離線作業
4. 資料同步
5. 提醒(Email, SMS, 推播)
6. 把todo依照日期、即將到來、未來的某天分類
7. Tag/資料夾 分類
8. UI 要好用

因此開始找到了幾款iPhone App,以下僅列出幾個覺得比較ok的,有些太糟糕的就不列了
1. Any.do - http://www.any.do/
2. Wunderlist - https://www.wunderlist.com/
3. Orchestra Todo - http://www.orchestra.com
4. Google Task - https://mail.google.com/mail/help/tasks/
5. Todoist - http://todoist.com/
6. Asana - http://asana.com/

以下就依照我使用的感覺來做些評比
1. Any.do
優點:
1.UI很漂亮, iPhone版本很棒
2.支援iPhone, Android, Chrome extensions
3.支援語音輸入
4.支援子任務(subtask)

缺點:
1. 資料同步常常出錯,而且很慢
2. App只要不開啟等待同步完,即使在Chrome上設定好Alert也不會叫
3. Calendar只支援在手機 App內觀看


2. Wunderlist
優點:
1. Apple Store大力推薦
2. 支援超多平台(iPhone, iPad, Android, MacOS, Windows, Web)
3. GUI很漂亮
4. 支援子任務(subtask)
5. 支援筆記(note)
6. 可分享task

缺點:
1. 使用上常常會卡住(也許是還不習慣)
2. 非即時同步
3. folder分類有點亂(如果是只有自己使用時All, Inbox 常常會搞混)
4. 無法簡單的把task往後推個幾天,一定要給一個確定日期,但是設定日期方式是UIPickerView,無法直覺的想到是星期幾


Orchestra Todo
優點:
1. 同步速度超快
2. 可以分享task
3. 誤) 這家公司還推出了MailBox

缺點:
1. UI是特別針對會需要多人共享task而設計,而非個人
2. 不知道是不是公司資源都移到MailBox,感覺被冷落


Todoist
優點:
1. 看起來很強大
2. 支援很多平台
3. 付費用戶有支援ical

缺點:
1. 太強大了,UI設計上是個很大的挑戰,還是無法掌握設計者想法


Asana
優點:
1. 介面很清爽
2. 針對團隊協作開發設計
3. 支援iCal

缺點:
1. 資料同步常常錯誤,尤其在mobile app上網路斷斷續續




整體來說
"只使用iPhone"推薦使用"Any.do"
"使用iPhone, iPad, 桌上電腦"推薦使用"Wunderlist", "Any.do"
"團隊多人共同分享task"推薦使用"Asana"


Google Apps Script - GMail Inline Image

最近剛好有需求要做Mail Parser,主要是需要把Mail附件拿來做些處理,Google Apps Script其實在這部份已經做的很棒,詳細可以查詢GmailApp,其中Inbox對於Gmail來說就像是個郵件盒,每個郵件盒中有很多的郵件(GmailMessage),每封郵件內可能還會夾帶著附件(GmailAttachment),相同一系列的郵件(就是一直Re: Fwd:)這些郵件會變為一個郵件串(GmailThread),你可以針對每一個郵件串(GmailThread)貼上標籤(GmailLabel)來分類,這就是在Google Apps Script中所分的幾個大分類。

  • GmailApp:Gmail
  • Inbox:Gmail 的Inbox
  • GmailThread:郵件串
  • GmailLabel:郵件串的標籤
  • GmailMessage:郵件
  • GmailAttachment:郵件附件

對於基本的GMail該有的功能幾乎是都有了,但對於Inline Image似乎沒有辦法取得,既不在Mail body也不在attachment中,但這圖片確實可以出現在Gmail中,從Mail Body只會取得一個連結,但這連結必須要Google login session才可以拿到,在Google apple script沒辦法直接用curl來login,所以開始了找尋新的一條路...最後發現在RawContent中其實有夾帶著Inline Image,是用base64 encode的binary,重點就是要把這些Parse出來decode轉成blob,就可以自由的使用,但在parse過程中遇到很多問題,現在的Mail server種類很多,Mail client更是多...每一個上傳過來的多少都有點落差,在這邊判斷這東西實在很麻煩,所以目前採用了一種方式解決,把所有收到的Email 再轉寄到另一個Gmail,這樣就可以保證收到的Mail全部都是Google 格式,也因此parse只要寫一種(GMail)即可。

如果有興趣使用可以直接Import,project key「MexeYVcutPEfH4PE_lTdUTQ1vcfzwSFZI

使用方式 sample
//只要使用下面這行就會回傳inline image的Array(blob array)
Mail.getGmailInlineAttachments(gmailMessage)


相關連結
source code - https://script.google.com/d/1S9W3czqvmbE20rXUMrZogPz3ij54CudfU7ugIVAKmTU0-U9Nw2k4xNFH/edit
Google Apps Script Gmail - https://developers.google.com/apps-script/service_gmail

Google Apps Script - SpreadSheet Library

前一篇有講過Google Apps Script - SpreadSheet,在使用Google 提供的Library還是感覺有些常用的東西沒有,所以就自己寫了個Library把幾個常用的整理起來。加入Library的使用方式如下:

Project Key「MDu1zmJTs8tZwFGuAKerzvA1vcfzwSFZI

Step1. Resource >> Manage libraries



Step2. 輸入Project Key「MDu1zmJTs8tZwFGuAKerzvA1vcfzwSFZI
成功Input後可以選擇所需要的版本、觀看文件,以及此Library在自己的Project中代表的變數名稱



Step3. Save

完成後就可以直接來使用,開始呼叫任何一個function前記得要先呼叫「initWithSpreadsheetId」,先把Id設定好後所有的function才可以使用,Library列表如下
  • initWithSpreadsheetId:設定要存取哪一個SpreadSheet
  • getSheets:取得SpreadSheet內所有的Sheet
  • getSheet:取得SpreadSheet內取得指定的的Sheet
  • getColumn:取得Sheet內一整欄的資料
  • getColumnIndex:取得Sheet內第一欄的文字位置
  • getRow:取得Sheet內一整行的資料
  • getAllRows:取得Sheet內所有的資料

Project Key「MDu1zmJTs8tZwFGuAKerzvA1vcfzwSFZI

相關連結
Google Apps Script - https://developers.google.com/apps-script/
Google Apps Script SpreadSheet - https://developers.google.com/apps-script/class_spreadsheetapp

terminal new alias name

自定義Terminal的內容,可使用以下方式

新增一個Alias
alias YOUR_NEW_ALIASNAME='YOUR_COMMAND'

移除alias
unalias YOUR_NEW_ALIASNAME


Google Apps Script - Spreadsheets

Google Doc是個相當棒的協作服務,尤其最吸引我的一點就是不需要再擔心一份檔案寄來寄去,最後只能靠檔名加註是幾月記號的版本,而且不需要多浪費不必要的重複檔案,配合上Hangouts還可以同時視訊、語音,確實有效解決了需要面對面開會的問題,單然還是有些不能取代的部份,至少可以減少不必要的資源浪費。

Spreadsheets就像是Excel,函數的數量並沒有像Excel完整,但足以應付基本應用。不論是Excel, Numbers, Spreadsheets還是會有無法完成些特定的需求,如同資料庫可以依照想要的需求下指令,但這問題有解了,Google 有提供給Spreadsheets API,但需要client認證,若不想寫client認證,也有另外的選擇「Google Apps Script」。

Google Apps Script,就以官方的簡單一段話「Google Apps Script 是個Javascript的雲端腳本語言,提供了Google自家產品、第三方服務簡單的來自動執行任務」並提供了四大要點(註一):
  • 自動化的完成重複流程
  • 把Google產品與第三方服務連結
  • 建立自己的函數(也就是Spreadsheets自定函數,如同Excel自定函數)
  • 建立豐富的圖形化介面、菜單

其中第二點我認為是這服務最吸引我的點,在API中有提供HTTP Response以及UiApp
簡單來說可以把Spreadsheets當做MySQL,Google Drive當做硬碟,HTTP Response用來跟其他3-party Service用web service溝通,UiApp可以當做Web Server來更新資訊,簡直就是把過去常聽到的LAMP直接轉換為雲端的版本,直接交由Google來作系統(噫!?Chrome OS ?)

使用方式
Step1. 隨意打開一個Spreadsheets,從MENU中找出Tools


其中有兩個比較重要的如下:
  • Script gallery...
  • Script manager...

Script gallery

可藉由上方直接搜尋,找到喜歡的後就直接點下"install"


按下install後會跳出一個請求,要求權限,確認後就完成安裝



Script manager

Script manager可以幫你確認目前文件中所有使用上的Script,在這邊可以進行所有的Script新增、編輯,或者執行其中一個function,列表中右邊的script就是script的project name,而function就是project內可執行的function



如果不想直接修改從Script Gallery找來的Script,也可透過New來新增自己的project & function


其中有幾個內定的function
  • onInstall:建立文件時執行
  • onOpen:開啟文件時執行
  • onEdit:編輯文件時執行(編輯完每一個Cell)
此畫面也為Script的開發、Debug頁面(下一篇再詳細介紹此開發方式)


結論

  • 優點
    • 有寫過Javascript的人應搭配著官方文件就可以快速上手
    • 可以同時結合Google服務(Calendar, Gmail, Google Apps, ...)做出有趣的應用
    • 提供了oauth的function方便第三方的帳號認證
    • 強大的HTTP Response以及UiApp,與其他服務串接不成問題
  • 缺點
    • 目前的開發、Debug環境還是沒很友善
    • 官方文件在很多地方有點怪,例如很容易查不到些關鍵的function、在需要搭配做clientLogin時找不到對應的文件(例如call哪個service name,或者應該說文件版本太多XD)
    • 目前文件僅有英文版
    • 與3-party連接時效能上不是很優(登入 -> 塞一筆資訊到表格中,這兩個動作大約需要3~5秒)
    • 表格容量有限


註一:此為本人簡單的翻譯,詳細請參照:https://developers.google.com/apps-script/

相關連結
Google Apps Script - https://developers.google.com/apps-script/

iOS Mobile AD & AdMob SDK

相信Banner廣告在已經是無所不在的出現於網站中,也因為廣告的投遞不夠精準、太醜、看不順眼等因素產生了瀏覽器的plugin「AdBlock」,但是iOS上就沒有這種plugin(Android:AdBlock Plus),所以該如何塞入適當的廣告增加CTR(Click-through rate),CPM(cost per 1000 impressions)就是個相當直接關係廣告收入的重點,畢竟推撥廣告的不是自己。

先從幾點來說明廣告的生態、呈現方式
  • 行動廣告環境生態
  • 行動廣告平台提供商
  • 行動廣告呈現方式
  • AdMob SDK

行動廣告環境生態
  • 廣告主/代理商
    • 透過平台(下段說明)投遞廣告
  • 開發者
    • 開發APP/ Mobile web 插入廣告
    • 點擊廣告後的活動網頁/ mobile web
  • 消費者
    • 接受行動廣告平台推撥來的廣告
    • 點廣告給平台/開發者賺錢


行動廣告平台提供
目前最熱門就是AdMob,而admob背後推送的平台就是AdWhirl目前AdWhirlopen source,所以有興趣的人也可以自行來架設廣告平台,目前台灣幾個較大的行動廣告平台(Vpon, KuAd)也都是使用AdWhirl為基礎。

除了AdMob外還有幾個較大的平台如InMobiiAD、......等的平台,其中較為特別的是iAD,他不只扮演了廣告平台的角色,還提供了iAd Producer讓開發者/廣告主快速的製作出活動網頁的工具。


行動廣告呈現方式
  • Banner
    • Phone
      • 320*50
      • 300x250
      • 468x60
      • 728x90
      • 320*50
    • Pad
      • 320*50
      • 360x50
      • 480x32
      • 533x32, range of sizes from 480x32 to 682x32
      • 768x90
      • 1024x90
      • 800x90
      • 1280x90
      • 600x90
      • 1024x50
  • 全螢幕
    • 影片
    • 網頁
    • 地圖
  • 行動平台SDK
    • 陀螺儀
    • 電子羅盤
    • 加速度感應器
    • 定位服務
    • 相機
    • 震動
    • 加速度感應器
    • 3G/Wifi 網路
    • 多點觸碰/手勢操作
    • 播放聲音/影片
    • 藍牙
    • 地圖

其中可以控制行動平台SDK為比較厲害的作法,結合幾個不同的感應器可組成各種不同的動作完成廣告內容,例如相機+電子羅盤+定位服務可組成常見的LBS AR,地圖+定位服務+網路即可組成如Groupon Now這種有趣的活動。


AdMob SDK
這邊簡單介紹AdMob SDK使用方式,基本上大多在Google 官方已經有詳細介紹,SDK也是隨時都可以下載,唯獨讓我不了解的就是官方的教學當中居然少了兩個Framework,以致於按照官方教學Build仍然會出錯,兩個Framework分別為:
  • AudioToolBox.framework
  • StoreKit.framework

這兩個Framework都可以在iOS內建的Framework找到,加入後Build就不會出問題。


相關連結
AdMob - http://www.google.com/ads/admob/
AdWhirl - https://www.adwhirl.com/
Vpon - http://www.vpon.com/zh-tw/index.html
KuAD - http://www.kusogi.com/
InMobi - http://www.inmobi.com/
iAD - http://advertising.apple.com/
iAD Producer - https://developer.apple.com/iad/iadproducer/

Paypal - Buy Now Buttons

前陣子剛好需要串金流,原本考慮台灣著名的紅藍綠(紅陽藍新綠界),但後來考量到後續可能會需要跨國、發票、稅務等問題,最後還是選擇 PayPal。

Paypal是個相當強大的金流服務系統,開放的API,相當完整的文件,以及眾多的 3-party或官方的SDK,只是還是一句老話,好的系統是演化來的,也因此很容易造成歷史包袱(誤)。

如果有去查過 Paypal的相關 source可能會常常看到 IPN(Instant Payment Notification),以及 PDT(Payment Data Transfer),兩種各有不同的需求,但我們所需要的就只是「線上信用卡付費」,只有一種商品一種售價,收費方式也不僅限於信用卡,另提供轉帳服務,在這種狀況下如果要花時間下去串完整的金流C/P值有點低,還好PayPal有提供更簡單的方式「Buy Now Buttons」。

產生Buy Now Buttons簡單來說有三種方式,以下會再針對這三種方式特別來說明


Paypal網站產生
(※可能會因為Paypal網站改版而UI位置調整)
step 1.註冊Paypal(註冊流程不再多加敘述,只是記得別選"個人")


step 2.點選「個人檔案」


step 3.點選「更新」


step 4.「建立新按鈕」


step 5.建立按鈕詳細訊息(以下為三步驟同時展開,其中比較重要部分已圈選起來)


step 6.複製HTML貼到網站中或Email給會員,右邊為此HTML貼上後顯示效果



URL 產生
使用URL產生上方Button的功能,也就是直接連至付費頁面,Sample如下
https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=herschelgomez@xyzzyu.com&item_name=Hot Sauce-12+oz.+Bottle&item_number=12345&amount=5%2e95¤cy_code=USD

較為重要如下,可依照個人需求而改變
  • business=herschelgomez@xyzzyu.com -> 需要匯入的Paypal帳戶名稱
  • item_name=Hot Sauce-12+oz.+Bottle -> 商品名稱
  • item_number=12345 -> 商品編號
  • amount=5%2e95 -> 售價
  • currency_code=USD -> 貨幣代號


HTML 產生
使用HTML自行產生付費按鈕,其中"YOUR_"開頭的部份就是需要填入的內容



相關連結
Paypal官方網站 - http://www.paypal.com
Paypal Developer - https://www.x.com/developers/paypal