Messenger chatbot send youtube video 失敗心得

Messenger chatbot send youtube video 失敗心得




因為專題想要開發一個bot可以推播特定的youtube影片給使用者,
然而youtube影片格式無法直接使用messenger bot 的 video api,api只吃類似.mp4格式的網址,
所以若使用者想在messenger看youtube影片,必須得不停的切換messenger and brower視窗,
對使用者體驗來說相當不便
所以運用了神通廣大的google大神,仍然宣告失敗,然而還是學到許多事情,所以記錄下來

youtube api 教學

youtube api還蠻簡單的,輕鬆使用get方法可以拿到頻道資訊 播放清單資訊 影片資訊等等

這是channel的 http request,可以抓取頻道資訊 要將{}改成自己的參數
https://www.googleapis.com/youtube/v3/channelSections?part=contentDetails&channelId={}&key={}

這是playlist的 http request,可以抓取播放清單資訊 要將{}改成自己的參數
https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails,snippet&maxResults=50&playlistId={}&key={}

以下code為對某頻道做search並抓去該頻道播放清單的video_id

import requests import json import sys def main(argv): key = "your api key" cat_channel_id = "UC9egiwuJsQZ0Cy2to5fvSIQ" # cat channel id jsondata = requests.get( "https://www.googleapis.com/youtube/v3/channelSections?part=contentDetails&channelId={}&key={}".format(cat_channel_id, key)) # request channel information data = json.loads(jsondata.text) list_playlist = data['items'] # get playlists count = 0 for playlist in list_playlist: count = count + 1 if 'contentDetails' in playlist and 'playlists' in playlist['contentDetails']: playlist_id = playlist['contentDetails']['playlists'][0] print playlist_id videos_json = requests.get( 'https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails,snippet&maxResults=50&playlistId={}&key={}'.format(playlist_id, key)) # request playlist information videos_data = json.loads(videos_json.text) print videos_data videos = videos_data['items'] for video in videos: if 'contentDetails' in video: video_id = video['contentDetails']['videoId'] print "video_id={}".format(video_id) #print video id print count if __name__ == '__main__': main(sys.argv[1:])

youtube dl in python

再來採用youtube dl 套件,想辦法獲取video的真實url,讓api可以傳送video

import youtube_dl ydl = youtube_dl.YoutubeDL({'outtmpl': '%(id)s%(ext)s'}) with ydl: result = ydl.extract_info( 'http://www.youtube.com/watch?v=ET0rV79uFDQ', download=False # We just want to extract the info ) if 'entries' in result: # Can be a playlist or a list of videos video = result['entries'][0] else: # Just a video video = result print(video) video_url = video['url'] print(video_url)

很好,我拿到網址了,

https://r6—sn-u5oxu-uooe.googlevideo.com/videoplayback?ratebypass=yes&itag=22&requiressl=yes&expire=1495442327&mime=video%2Fmp4&key=yt6&sparams=dur%2Cei%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&ip=140.116.1.136&lmt=1492925516230696&dur=527.046&mt=1495420642&mv=m&ms=au&source=youtube&signature=DAD0CEE5063DE3B61E892B6A23EC6BAD16E124F0.C78C5E8FA97EA53668EBB9604976BD939829FAF9&initcwndbps=4775000&mm=31&mn=sn-u5oxu-uooe&id=o-AKRm_kSrfIkSvTcaOtsXmUPBRhb-JW2xHJPhQFHF3YDA&upn=zv89kP3EApo&ipbits=0&ei=Nk8iWfzoPJGb4AKty5ioBA&pl=19

但是這個網址fb仍然不吃… :cry:

結論:失敗,待解決

目前仍然想不到在messenger內直接看youtube影片的方法

目前最好的方式是採用general template,圖片用youtube api 抓到的縮圖

下方建button來讓使用者點擊進入youtu
be

  •  
張書維 張書維 Author

telegram chatbot on heroku 建構 telegram 聊天機器人

Telegram chatbot on heroku 建構 telegram 聊天機器人

學校期末專題要寫telegram的聊天機器人(一堆專題 :cry: )

摸了一下telegram並記錄下來

申請上比messenger簡單許多,只要跟bot father 講講話就申請完了

chatbot需要放在server上跑,而我選擇heroku

以下範例code deploy在heroku上 可以echo使用者的回應

範例code

bot.py

記得填上自己的token 跟 server的url

import telebot import os from flask import Flask, request bot = telebot.TeleBot('your access token') server = Flask(__name__) @bot.message_handler(commands=['start']) def start(message): bot.reply_to(message, 'Hello, ' + message.from_user.first_name) @bot.message_handler(func=lambda message: True, content_types=['text']) def echo_message(message): bot.send_message(message.from_user.id, message.text) @server.route("/", methods=['POST']) def getMessage(): bot.process_new_updates([telebot.types.Update.de_json(request.stream.read().decode("utf-8"))]) return "!", 200 @server.route("/") def webhook(): bot.remove_webhook() bot.set_webhook(url="your heroku application url") return "!", 200 server.run(host="0.0.0.0", port=os.environ.get('PORT', 5000)) server = Flask(__name__)

requirements.txt

pyTelegramBotAPI==2.1.5 requests==2.7.0 telebot==0.0.3 logger==1.4 flask==0.11

Procfile

web: python bot.py

將這三個檔案deploy到heroku上即可

  •  
  •  
張書維 張書維 Author

imgur-api-簡易申請流程-教學-python

Imgur API 簡易申請流程 教學 python

簡介

imgur 個api蠻friendly的,因為專題需要一個圖床放圖片,所以就去摸了一下imgur 的一些簡單的操作,並記錄下來

申請

申請的流程相當簡單

申請完後會得到一組 Clinet ID 與 Client Serect
如果有去翻文件看過的話,會發現有些函式還需要access token 跟refresh token

疑~阿這兩個要哪裡來

這就是比較麻煩的OAUth的認證,因為當初不懂這是在幹嗎的,用了超級久才用出來,用出來後系統就會寄這兩個token給你

1.pip install imgurpython
2.從imgur 的 github上抓範例code下來 https://github.com/Imgur/imgurpython/tree/master/examples
3.修改auth.ini的 client id 與secret為自己的資料
4.run auth.py 並依照指示操作
5.get token

範例程式

這個程式可以將照片網址的照片上傳到imgur的圖床,ㄅ,,當然也可以改成用別種方式上傳(檔案等等 要換別的函式),填上個人資訊就可以自動化輕鬆上傳圖片至圖床了

# -*- coding: utf-8 -*- """ Created on Tue May 02 22:16:19 2017 @author: vic """ from imgurpython import ImgurClient def upload_photo(image_url): client_id = 'your id' client_secret = 'your serect' access_token = 'your token' refresh_token = 'your token' client = ImgurClient(client_id, client_secret, access_token, refresh_token) album = None # You can also enter an album ID here config = { 'album': album, } print("Uploading image... ") image = client.upload_from_url(image_url, config=config, anon=False) print("Done") return image['link']
張書維 張書維 Author

解決 No JSON object could be decoded 的方法教學

解決 No JSON object could be decoded 的方法教學

我嘗試將網路上的開放資料傳到DB上
然而在json.load時一直跳No JSON object could be decoded 的bug
編碼已經是utf8,仍然跳bug

為此研究一番,紀錄一下自己的解決方法

系統:windows

對沒錯,這問題就是出在windows
在windows中,json就算存成utf8編碼,仍然會有問題,
因為windows預設是有BOM的utf8編碼
但這會被python判斷錯誤
因此必須調整成無BOM的編碼
可以在notepad裡面修改編碼
這樣或許就能解決 No JSON object could be decoded 的問題

  •  
張書維 張書維 Author

Compiler Ch5 LL Parser 編譯系統 學習筆記

Compiler Ch5 LL Parser

First L: 由左到右處理input

Second L: 執行left derivation

LL(K): K代表向前探查K個token

LL(1)

由左到右處理字串,再對句型執行最左推導語法樹,只需向前查看(偷偷看)1個token,就可以推導出來的文法,即是LL(1),當 parser 遇到多種可能的推導方式時,偷偷的看 Predict Set ,找出對應Token ,持續parse直到$

如何計算 Predict Set (所有可能的下一個token)

如果 A -> ABCD


ANS = First(ABCD) #找出第一個terminal


if (ABCD -> λ):     #如果會derive 出 lumbda
    ANS = ANS 聯集 Follow(A)     #那就要再從follow找terminal
    
return(ANS)     #回傳答案

Lumbda 不算是 Terminal , 所以不能算在Set裡

如何確認 Grammer 是 LL(1)

如果 S -> A | B

要符合 LL(1) 的 grammer 有以下條件

  1. First(A) 跟 First(B) 交集為空
  2. 兩者至多一個可 derive lumbda
  3. if B -> lumbda , First(A) 跟 Follow(S) 交集為空
  4. if A -> lumbda , First(B) 跟 Follow(S) 交集為空

Example

Rule:

S -> A C $
C -> c | λ
A -> a B C d | B Q
B -> b B | λ
Q -> q | λ

建表

Rule Number A X1X2…Xn First(X1X2…Xn) Derive empty Follow Ans
1 S AC$ abqc$ N abqc$
2 C c c N c
3 C λ Y d$ d$
4 A aBCd a N a
5 A BQ bq Y c$ bqc$
6 B bB b N b
7 B λ Y cd$ cqd$
8 Q q q N q
9 Q λ Y cd$ c$

檢查條件

檢查4種條件,若都符合即是LL(1)

Recursive-Descient Parser with LL(1)

這種parser搭配LL(1),大致結構就是LL方式判斷,依照rule去match terminal,若是nonterminal,則call它的rule繼續match,遞迴下去求得解答或是判斷出syntax error

  •  
張書維 張書維 Author

Database Ch3 ER Model 資料庫系統導論 學習筆記

Database Ch3 ER Model

E:entity
R:relationship

ER model 是 database 設計的一種流程

範例:

ER model 常用符號:

Entity: 用來詮釋Mini World的一些物件,大部分是名詞,例如在公司中,有員工 部門 專案 這些entity

Relationship: 用來表示Entity間的關係,就像是離散數學中的relation概念差不多。

Attribute: Entity 或 relationship 的 屬性,例如員工這個Entity有名子 性別 等等屬性

Entity type & key attribute

Entity type:有相同基本類型的entity,可分類成entity type 例如員工type , Project type

Key attribute:在Entity type中,每個entity的這個attribute都不同,則為key attribute,像是身分證號碼

每個entity不一定只有一個key attribute

Relationship & Relation type

一樣同樣type 的 relation 會分到一個relation type

參與這個relation的entity數 = degree

Binary relation -> degree = 2
Ternary relation-> degree = 3
n-ary relation -> degree = n

Relationship 可以relate相同的entity type中的entity
例如 上司關係(員工A,員工B) 員工A是員工B的上司,兩個員工都是屬於員工type

Structural Constraints and Roles

Cardinality Ratio:代表不同個體之間在參與某一個關係時,個體間的實例相互參與之數量比

常見有 1:1 1:N M:N

Participation Constraint:是指某個體中的所有實例,是否一定需要依靠參與某關係,並和另一個體產生關聯而存在。

全部參與 (Total Participation)
部份參與 (Partial Participation)

Min Max Notation:

用來定義relation的參與entity數的最小與最大值
Default: Min=0,Max=1

Weak Entity

弱實體就是必須依靠其他實體才能存在。如果弱實體所依靠的實體消失了, 則該弱實體也就變得沒有意義了。

參考資料

  1. 李強老師ppt
  2. http://sjchen.im.nuu.edu.tw/Database/99/Ch03.pdf
  3. http://spaces.isu.edu.tw/upload/19225/0/news/postfile_308.pdf
  4. http://www.mysql.tw/2013/03/entity-relationship-model.html
  •  
張書維 張書維 Author

Database Ch2 DBMS概念與架構 資料庫系統導論 學習筆記

Database Ch2 DBMS概念與架構

Data Model

Data Model: 一組用來描述資料庫結構的概念

Data Model Operation: 依據資料模型指定存取及更新資料庫的動作。在資料模型上的運算可能包含「基本運算」和「使用者定義的運算」

Data Model 的分類:

  1. Conceptional(high-level):容易讓使用者理解
  2. Physical(low level):表現資料實際在電腦的儲存方式
  3. Implementation(record-oriented):介於以上兩者之間

Schema

Database Schema: 資料庫的綱要,包括資料庫的描述與一些限制
Database Instance: 資料庫實例,在某個特殊時間點的資料庫狀態(內容)

schema 很少更改,但 instance 則是每次更新都更改

Three schema architecture

Internal schema: 描述實際的資料庫儲存結構。通常是使用實體(physical model)資料模型

Conceptional schema: 是用來為某一組使用者描述整個資料庫的結構與限制。通常是使用某種概念 (conceptual) 或實作
(implementation)資料模型

External schema: 是用來描述各個不同的使用者檢視表 (view)。它通常使用與概念層相同的資料模型

DBMS必須將External schema的需求轉換成 Conceptional schema的需求,然後再轉換成Internal schema的需求,以便處理實體資料庫

Data Independence

Logical Data Independence: 代表修改Conceptional 時,不必修改 External

Physical Data Independence: 代表修改 Internal時,不必修改 Conceptional

DBMS Language

Data Defination Language(DDL): 是一種能讓DBA與資料庫設計師用來定義Conceptional schema,某些DDL也會定義 Internal (用storage definition language,SDL)與 External (用view definition language,VDL)

Data Maniputation Language(DML): 用來指定資料庫的擷取與修改

DML Command(Data sublangage):

可以嵌入在一般的程式語言裡(主機語言,host
language),如COBOL、C或組合語言,或者是直接執行獨立的(stand-alone)DML命令(也就是查詢語言,query language)

Type of DML

Procedural DML:低階或程序化的,一次一筆記錄;它們是指定如何擷取資料,並且具有如迴圈這類的程式結構

Non-procedural DML:高階或非程序化的,它們是集合導向的(set-oriented),而且是指定要什麼資料,而不是如何擷取,如SQL。也稱作宣告式(declarative)語言

DBMS 分類

依照Data Model分類:
傳統的:Relational, Network, Hierarchical
新興的:Object-oriented, Semantic, Entity-Relationship, other

  •  
張書維 張書維 Author

Database Ch1 資料庫系統導論 第一章 學習筆記

Database Ch1

基本概念

  1. Database:Data的集合(Collaction)
  2. Mini-world:微小世界,用來詮釋真實世界一部分
  3. DBS:資料庫系統
  4. DBMS:資料庫管理系統
  5. DB:資料庫

DBS包含DB跟DBMS

DBMS的目錄(catalog) 中儲存有資料庫的描述,這些描述資料稱為詮釋資料 (metadata)。因此DBMS軟體能與不同的資料庫一起工作

資料庫的使用者

Worker on the scene(檯面上的人):

  1. Database adminstrators(DBAs): 負責授權存取資料庫、協調及監督資料庫的使用、取得軟硬體資源、控制它的使用和監督運作的效能
  2. Database Designer: 負責定義資料庫的內容、結構、限制,以及函數和交易。他們必須與終端使用者溝通以了解他們的需求
  3. 終端使用者:他們會查詢和使用資料來製作報表,其中一部分人可以修改資料庫的內容

Worker behinh the scene:

  1. DBMS designers and implementers: 負責資料庫管理系統的開發
  2. Tool developer: 開發DBMS的tools
  3. Operators and maintenance personel:管理database的硬體環境與軟體環境

參考資料

  1. 李強老師ppt
  2. 台大kkchen ppt http://www.lis.ntu.edu.tw/~khchen/course/db/db2007/DBCh01Intro.pdf
  •  
張書維 張書維 Author

Web Crawler In Perl 網路爬蟲

Web Crawler In Perl 網路爬蟲

因為學校功課的關係,在很短的時間內摸perl的網路爬蟲,用api寫完後才發現老師要我們自己寫parser(乾 早知道不翹課),所以在用RE寫第二遍( :cry: )之後一陣子應該都用不到了,所以紀錄下來給未來可能用到的自己或是其他人看

Readme

本程式會去爬台南市的三個影城的電影時刻表
並且把資料抓下來解析,因為作業要求所以略過一些資訊(是否3dMax之類的),只抓電影名稱跟時間,很簡單的小程式
抓html -> parse 出我要的資訊 -> 輸出

Sample code Using Regular Expression

use LWP::Simple; use LWP::UserAgent; use HTTP::Request; use HTTP::Response; use HTML::LinkExtor; use Encode; $browser = LWP::UserAgent->new(); $browser->timeout(10); &crawler('http://www.atmovies.com.tw/showtime/t06607/a06/'); &crawler('http://www.atmovies.com.tw/showtime/t06608/a06/'); &crawler('http://www.atmovies.com.tw/showtime/t06609/a06/'); sub crawler{ (my $URL) =@_; my $request = HTTP::Request->new(GET => $URL); my $response = $browser->request($request); if ($response->is_error()) {printf "%s\n", $response->status_line;} $contents = $response->content(); $data = $contents; while($data =~ m!<ul id="theaterShowtimeTable">(.*?)<ul>(.*?)</ul>(.*?)</ul>!gs) { $item=$1; $otherparse=$3; $item =~ m!<a href=(.*)>(.*?)</a>!; $title=$2; print "$title\n"; while($otherparse =~m!(\d)(\d):(\d)(\d)!gs) { print "$1$2:$3$4\n"; } } }

sample code using TreeBuilder

use HTML::TreeBuilder; binmode(STDIN, ':encoding(utf8)'); binmode(STDOUT, ':encoding(utf8)'); binmode(STDERR, ':encoding(utf8)'); $URL = 'http://www.atmovies.com.tw/showtime/t06607/a06/'; my $tree = HTML::TreeBuilder->new_from_url($URL); my @items = $tree->look_down('id', 'theaterShowtimeTable' )or die("no items: $!\n"); for my $item (@items) { my @movies = $item->look_down( '_tag', 'li' ) or die("no movies$!\n"); $count=0; for my $movie (@movies) { if($count!=1&&$count!=2&&$count!=3) { if($movie->attr('class') ne "theaterElse" && $movie->attr('class') ne "filmVersion") { print $movie->as_text, "\n"; } } $count++; } }
  •  
  •  
張書維 張書維 Author

First & Follow set

Compiler Ch4-Grammer

First and follow

是兩個很重要的Function,用來建構top-down 跟 bottom-up Parser

假設rule是以下這些
S -> ABc
A -> a | B
B -> b | λ


1.First(T)

定義:

將 T (可以是terminal 或 nonterminal) 展開時,可能遇到的第一個 terminal symbol 所成的集合
所以

First(A) = { a , b , λ }

First(B) = { b , λ }

2.Follow(T)

定義:

接在T( nonterminal ) 後所有可能的第一個terminal
在開始算Follow之前,先把$(input right end marker)放到Start symbol後
所以

Follow(B) = { c , $}

Follow(A) = First(B) + Follow(B) = { b , c }

在算Follow(A)時,即是在找接在A之後的第一個terminal有哪些,
而 S->ABc 因此去尋找B的First set,即是在找A後的第一個terminal,
會發現 First(B) 有 λ,因此當B->λ時,A後的第一個Terminal在Follow(B)內,以此類推。


  •  
張書維 張書維 Author

在 Messenger平台寫聊天機器人Chatbot on Heroku

因為大學專題需要,開始試著寫Chatbot,以下就是慢慢紀錄的開發歷程

1.在facebook Developer 創App 與創粉專

2.寫 code

3.把App deploy 到各大雲端平台

4.設定回呼網址為雲端平台上的app,設定Token

5.測試是否能對話


一開始的流程很簡單就可以爬文爬到,比較麻煩的是編輯 page 的回呼網址,

必須先把app放到雲端平台(Heroku  Azure  等等) ,然後 Copy App 的網址,這裡的驗證才會過關

我是採用Heroku    https://www.heroku.com/ ,它有很方便的功能,可以與Github做連接,只要與Chatbot的專案做Connenct,就可以與Github同步,Heroku 的免費流量應該足以讓小專案生存,但Heroku的server 在沒人呼叫它超過30分,會休眠就是了。

如果不想讓Heroku休眠,可以嘗試使用 Uptime Robot
它可以在固定時間內發送訊息給伺服器,讓伺服器不休眠,而且服務是免費的,
不過會不會讓Heroku流量爆掉就難說了...

  •  
張書維 張書維 Author

總網頁瀏覽量

Popular Posts