Line 有提供 profile API 可以取得使用者名稱,實務情況常見於使用者加入好友當下觸發,把 userID 和 displayName 紀錄進好友資訊
profile API
https://api.line.me/v2/bot/profile/{userId}
Response呼叫成功 status code 會回傳 200 並回傳下列 json
{
"displayName": "LINE taro",
"userId": "U4af4980629...",
"language": "en",
"pictureUrl": "https://profile.line-scdn.net/ch/v2/p/uf9da5ee2b...",
"statusMessage": "Hello, LINE!"
}
其中 pictureUrl 和 statusMessage 要使用者有設定才會有該資訊
Error Response
呼叫後的 status code 有 400 和 404
- 400:不是有效的 userID
- 404 則有下列四種可能
- userID 不存在
- 使用者沒有同意授權可以取得 profile 資訊
- 該使用者沒有加 LineBot 為好友
- 該使用者封鎖 LineBot
// 400 json
{
"message": "The value for the 'userId' parameter is invalid"
}
// 404 json
{
"message": "Not found"
}
Google Apps Script .gs Code
function doPost(e) {
try {
let contents = JSON.parse(e.postData.contents);
let event = contents.events[0];
let userID = event.source.userId
// 加 LineBot 為好友
if (event.type === 'follow') {
let profile = getProfile(userID);
let displayName = profile.displayName;
WriteLog([new Date(), '加入好友', userID, displayName])
return;
}
// 發送文字訊息
if (
event.type === "message" &&
event.message &&
event.message.type === "text") {
let text = contents.events[0].message.text;
WriteLog([new Date(), "文字訊息", userID, text]);
return;
}
WriteLog([new Date(), "無對應事件"]);
} catch (e) {
WriteLog([new Date(), "錯誤訊息:", e.toString()]);
}
}
function getProfile(userId) {
// 從 PropertiesService 取出 LineChannelAccessToken
let lineChannelAccessToken = getProperties("LineChannelAccessToken");
let url = `https://api.line.me/v2/bot/profile/${userId}`;
let options = {
'method': 'GET',
'headers': {
'Authorization': 'Bearer ' + lineChannelAccessToken,
'Content-Type': 'application/json'
},
'muteHttpExceptions': true
};
try {
let response = UrlFetchApp.fetch(url, options);
let responseCode = response.getResponseCode();
let responseText = response.getContentText();
if (responseCode === 200) {
return JSON.parse(responseText);
} else {
WriteLog([new Date() , `Get Profile API 呼叫失敗。Code: ${responseCode}, Response: ${responseText}`]);
return null;
}
} catch (e) {
WriteLog([new date() , `執行 UrlFetchApp 發生錯誤: ${e.toString()}`])
return null;
}
}
function WriteLog(logData) {
if (!logData || !Array.isArray(logData)) {
Logger.log("WriteLog 錯誤:傳入的參數不是有效的陣列。");
return;
}
try {
// 從 PropertiesService 取出 SheetID 和 SheetName
let sheetID = getProperties("SheetID");
let sheetName = getProperties("SheetName");
let ss = SpreadsheetApp.openById(sheetID);
let sheet = ss.getSheetByName(sheetName)
if (!sheet) {
Logger.log(`WriteLog 錯誤:找不到名稱為 ${SHEET_NAME} 的工作表。`);
return false;
}
sheet.appendRow(logData);
Logger.log(`成功寫入 Log: ${logData.join(', ')}`);
} catch (e) {
Logger.log("WriteLog 寫入失敗: " + e.toString());
}
}
function getProperties(key) {
let scriptProperties = PropertiesService.getScriptProperties();
let properties = scriptProperties.getProperties();
return properties[key];
}
UrlFetchApp.fetch muteHttpExceptions 參數
預設值為 false,以該範例為例來說明就是當 status code 為 400 或 404 時,GAS 會停止運行,設定為 true 會回傳 status code 來表示
設定為 false,回傳 400 時 GAS 停止運行,是停止運行而不是拋出 exception,try catch 是無法阻止停止運行的,如下圖
設定為 true 可以判斷 status code 並把錯誤訊息顯示出來,當然也可以寫進 Log 內



沒有留言:
張貼留言