專案說明
利用AWS Lambda觸發,設定每分鐘透過IG API到指定帳號檢測是否有新貼文/動態,如果有,則抓取其media url,將該圖片/影片發佈到Twitter的Media API後,獲得該media的media id,接著,發佈到Twitter帳號中。
架構圖
流程比較麻煩的點有兩部分,各是ig端以及twitter端
- instagram提供的graph api沒辦法直接取得別人帳號的貼文內容(像是圖片、影片網址),因此需要透過徒法煉鋼方式,模擬登入、拿TOKEN,然後再透過另外的API去取回多媒體網址。
- twitter上傳多媒體檔案需要多個步驟,第一步是要將多媒體檔傳到一個額外的media api server中,取得media id,而在上傳到media api server的過程中又有三步驟要做驗證,在結束前面的程序後,call twitter api發布貼文的指令,並附上前面得到的response: media id。
開發講解
- 登入並取得IG的csrftoken, sessionid, ds_user_id
在這個階段中,必須準備一個實際的IG帳號來做Login行為
登入後取得csrftoken, sessionid, ds_user_id三個資訊以利後續操作
原因是IG的官方API裡,並沒有辦法直接用API讓你存取他人的貼文
官方API只能用來操作/查看自己帳號的內容
這邊特別要提醒的是 要小心不要在同一小時裡面打太多reuqest
instagram api有防範機制 過多請求將會鎖住IP
就會得到response code 429: Too Many Requests
2. 取得限時動態資訊
由”https://i.instagram.com/api/v1/feed/user/{cookies}"這個url做GET
在發REQUEST的時候,header記得放入
{
'User-Agent': 'Instagram 10.3.2 (iPhone7,2; iPhone OS 9_3_3; en_US; en-US; scale=2.00; 750x1334) AppleWebKit/420+'
}
以及剛剛拿到的csrftoken, sessionid, ds_user_id放入cookies中
3. 拆解限時動態資訊(JSON)
由剛剛的HTTP GET得到的response 架構如以下
而主要的內容都在items之中
items中將會有數個element,每個element都代表一個現在這個使用者有的限時動態
舉例如以下
這個帳號目前可供觀看的限時動態有九個,因此上面得到的element也是0~8沒錯
而各item中內的架構如以下,這邊稍微講一些關鍵的attribute就好
- taken_at:指這個限時動態發布的時間(可透過time.localtime轉為datetime型態)
- video_versions:可以用這個屬性推估,如果存在這屬性,表示這則限時動態為影片
- image_versions2:如果該貼文為圖片,圖片的url可以在此找到
這邊先以圖片的限時動態為講解內容
打開image version可以看到兩個element
這邊的兩個element其實都代表一樣的資訊
只是#0是高畫質 #1畫質較差罷了
因此我們都直接拿#0的url即可
程式部分,tm這邊是要用來預留,之後可以給時間limit選擇要留下來的限時動態
(假設Lambda每分鐘call,就判斷此限時貼文是否為前一中所發出的,是則觸發)
4. 登入Twitter API驗證
這邊採用了函式庫Twython
https://twython.readthedocs.io/en/latest/
其實這個函式庫也只是幫你把大部分twitter official的一些步驟寫好
比較簡略 容易開發而已
class Twitter(object):
def __init__(self, CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) -> None:
print(f"initilize and verify twitter object....")
self.twitter = Twython(CONSUMER_KEY, CONSUMER_SECRET,
ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
self.twitter.verify_credentials()
5. 將IG的多媒體檔由Twitter Media Upload API上傳
這邊的步驟跟一些官方教學的步驟比較不同
大部分的教學都是去打開local的圖片文件
但這邊因為我們使用的是url的圖片
所以透過request打get到url圖片
然後再轉用BytesIO接
就可以達到一樣的效果
在影片上傳這部分其實比起圖片複雜許多
Upload happens in 3 stages:
- INIT call with size of media to be uploaded(in bytes). If this is more than 15mb, twitter will return error.
- APPEND calls each with media chunk. This returns a 204(No Content) if chunk is received.
- FINALIZE call to complete media upload. This returns media_id to be used with status update.
https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-upload
基本上他是有三個步驟要做: INIT, APPEND, FINALIZE
有興趣可以自己去看document
但這邊因為我們直接用了函式庫就不用特別自己寫
特別要注意的是twitter.upload_video參數
media_category這邊要用對的型態 才會上傳成功
The category that represents how the media will be used. This field is required when using the media with the Ads APIPossible values: amplify_video, tweet_gif, tweet_image, and tweet_video
6. 由Twitter Media Upload API得到的media id發布至Twitter中