/**
 * Line API class
 */
class LineAPI {
  /**
   * Get access token from Line
   * @return {string} access token
   */
  function getAccessToken() {
    var clientId = 'YOUR_CLIENT_ID';
    var clientSecret = 'YOUR_CLIENT_SECRET';
    var redirectUri = 'YOUR_REDIRECT_URI';
    var scope = 'profile openid email';
    var authUrl = 'https://access.line.me/oauth2/v2.1/authorize';
    var tokenUrl = 'https://api.line.me/oauth2/v2.1/token';
    
    var authCode = getAuthCode_(authUrl, clientId, redirectUri, scope);
    var tokenResponse = getToken_(tokenUrl, clientId, clientSecret, authCode);
    var accessToken = tokenResponse.access_token;
    return accessToken;
  }
  
  /**
   * Get user profile from Line
   * @param {string} accessToken
   * @return {object} user profile
   */
  function getUserProfile(accessToken) {
    var apiUrl = 'https://api.line.me/v2/profile';
    var headers = {
      'Authorization': 'Bearer ' + accessToken
    };
    var options = {
      'method': 'GET',
      'headers': headers
    };
    var response = UrlFetchApp.fetch(apiUrl, options);
    var userProfile = JSON.parse(response.getContentText());
    return userProfile;
  }
  
  /**
   * Get auth code from Line
   * @param {string} authUrl
   * @param {string} clientId
   * @param {string} redirectUri
   * @param {string} scope
   * @return {string} auth code
   */
  function getAuthCode_(authUrl, clientId, redirectUri, scope) {
    var authUrlParams = {
      'response_type': 'code',
      'client_id': clientId,
      'redirect_uri': redirectUri,
      'scope': scope
    };
    var authUrlWithParams = authUrl + '?' + encodeURI(serializeParams_(authUrlParams));
    var authCode = promptUser_(authUrlWithParams);
    return authCode;
  }
  
  /**
   * Get token from Line
   * @param {string} tokenUrl
   * @param {string} clientId
   * @param {string} clientSecret
   * @param {string} authCode
   * @return {object} token response
   */
  function getToken_(tokenUrl, clientId, clientSecret, authCode) {
    var tokenUrlParams = {
      'grant_type': 'authorization_code',
      'code': authCode,
      'redirect_uri': 'YOUR_REDIRECT_URI',
      'client_id': clientId,
      'client_secret': clientSecret
    };
    var options = {
      'method': 'POST',
      'headers': {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      'payload': serializeParams_(tokenUrlParams)
    };
    var response = UrlFetchApp.fetch(tokenUrl, options);
    var tokenResponse = JSON.parse(response.getContentText());
    return tokenResponse;
  }
  
  /**
   * Serialize parameters to URL query string
   * @param {object} params
   * @return {string} serialized parameters
   */
  function serializeParams_(params) {
    var paramsArray = [];
    for (var key in params) {
      paramsArray.push(key + '=' + encodeURIComponent(params[key]));
    }
    return paramsArray.join('&');
  }
  
  /**
   * Prompt user to authorize
   * @param {string} authUrl
   * @return {string} auth code
   */
  function promptUser_(authUrl) {
    var authCode = prompt('Please authorize and enter the auth code:', authUrl);
    return authCode;
  }
}