# π οΈ YouTube μλν νμ΄νλΌμΈ: HTTP API & OAuth 2.0 μ§μ μ μ΄ κ°μ΄λ
**λ¬Έμ μμ±μΌ:** 2026-03-13
**μμ±μ:** μ‘°μ©ν λΆμ μ€κ³μ & AI μ΄μμ€ν΄νΈ
**λͺ©μ :** Make.com κΈ°λ³Έ YouTube λͺ¨λμ μ¦μ ν ν° λ§λ£(400 Error) λ° κΆν μ€λ₯(403 Error)λ₯Ό μ°ννμ¬, 묡묡νκ³ μμ μ μΌλ‘ λμκ°λ λ°±μλ μ
λ‘λ μμ€ν
ꡬμΆ.
—
## π [To-Do List] μλν μμ€ν
κ΅¬μΆ λ§μ€ν° νλ
– [ ] λ
립λ GCP νλ‘μ νΈ μ μ λ° YouTube Data API v3 νμ±ν
– [ ] GCP OAuth λμ νλ©΄ μΈν
(Testing -> In Production μ ν)
– [ ] Custom OAuth ν΄λΌμ΄μΈνΈ ID/Secret λ°κΈ λ° λ¦¬λλ μ
URI μΌμΉν
– [ ] Make.com HTTP λͺ¨λ (Make an OAuth 2.0 request) μΈν
– [ ] Access Token ν€λ μ£Όμ
λ° Multipart νμ΄λ‘λ μ€κ³
– [ ] νμ΄νλΌμΈ μ€μΌμ€λ§ λ° λͺ¨λν°λ§ μ μ©
—
## π μ€ν κ°λ₯μ± κ²μ¦ (Executability Check)
– **μμ€ν
μꡬμ¬ν νμΈ:** λ³Έ κ°μ΄λλ λ€μμ λΈλλ μ±λμ μ΄μνλ©° μΌμΌ μ
λ‘λ μ ν(Quota)μ μ΄κ³Όνμ§ μλ λ²μ λ΄μμ λ¨μΌ GCP νλ‘μ νΈλ₯Ό νμ©νλ ꡬ쑰λ₯Ό μ μ λ‘ μμ±λμμ΅λλ€.
– λͺ¨λ μ€μ μ Google Cloud Consoleμ κ΄λ¦¬μ κΆνμ΄ μλ μνμμ μ ν¨ν©λλ€.
—
## 1. μΈνλΌ κΈ°λ° λ€μ§κΈ° (GCP νλ‘μ νΈ μΈν
)
λΈλλ°μ€ κ°μ κΈ°λ³Έ λͺ¨λμ κ±·μ΄λ΄κ³ ν΅μ κΆμ μ₯κΈ° μν 첫걸μμ
λλ€. λ¨μ μλ²κ° μλ ‘λ΄ μλ²(GCP)’μ μ격μ μ¦λͺ
ν΄μΌ ν©λλ€.
– **νλ‘μ νΈ κ²©λ¦¬:** κΈ°μ‘΄ νλ‘μ νΈμ μμ§ μκ³ , μλν μ μ© GCP νλ‘μ νΈλ₯Ό μ κ·λ‘ μμ±νκ±°λ μ©λκ° λΆλ¦¬λ κΉ¨λν νλ‘μ νΈλ₯Ό μ¬μ©ν©λλ€.
– **API νμ±ν:** API λ° μλΉμ€ > λΌμ΄λΈλ¬λ¦¬μμ YouTube Data API v3λ₯Ό λ°λμ ‘μ¬μ© μ€μ (Enable)’ ν©λλ€.
—
## 2. λ¬Έμ§κΈ° ν΅κ³ΌνκΈ° (OAuth 2.0 μ€μ λ° μλ¬ ν΄κ²°)
κ°μ₯ λ§μ κ°λ°μκ° μ’μ νλ μΈμ¦ λ¨κ³μ
λλ€. ꡬκΈμ κΉκΉν 보μ μ μ±
(400, 403 μλ¬)μ μ°μνκ² ννΌνλ μ€μ κ°μ
λλ€.
– **403 access_denied μλ¬ (νλΌμ΄λΉ ν΄λ½μ μ μ£Ό):** GCP OAuth λμ νλ©΄μμ κ²μ μνκ° ‘ν
μ€νΈ μ€(Testing)’μΌ λ λ°μν©λλ€.
– **ν΄κ²°μ±
:** μ± κ²μ(Publish App) λ²νΌμ λλ¬ **’νλ‘λμ
(In production)’**μΌλ‘ κ³Όκ°ν μ νν©λλ€. (λ΄λΆ μ¬μ© λͺ©μ μ΄λ―λ‘ κ΅¬κΈ μ± κ²ν λ 무μν©λλ€).
– **400 redirect_uri_mismatch μλ¬ (κΈΈ μμ ν ν°):** Make.comμ΄ μꡬνλ μ½λ°± μ£Όμκ° GCPμ λ±λ‘λμ§ μμ λ°μν©λλ€.
– **ν΄κ²°μ±
:** GCP μ¬μ©μ μΈμ¦ μ 보 > OAuth 2.0 ν΄λΌμ΄μΈνΈ ID μμ νλ©΄μμ μΉμΈλ 리λλ μ
URIμ `https://www.integromat.com/oauth/cb/oauth2` λ₯Ό ν μ¨ νλ νλ¦¬μ§ μκ³ μΆκ°ν©λλ€.
—
## 3. μμ€ν
μ νκ΄ μ°κ²° (API μ§μ νΈμΆ)
ν ν°μ΄λΌλ λΉλ° ν΅νμ¦μ μ»μλ€λ©΄, μλ²μ ν€λ(Header)μ μ΄λ₯Ό μ€μ΄ 보λ΄μΌ ν©λλ€.
### Make.com HTTP λͺ¨λ μΈν
(Make an OAuth 2.0 request)
– **Authorize URI:** `https://accounts.google.com/o/oauth2/v2/auth`
– **Token URI:** `https://oauth2.googleapis.com/token`
– **Scope:** `https://www.googleapis.com/auth/youtube.upload`
– **API Endpoint:** `https://www.googleapis.com/upload/youtube/v3/videos?uploadType=multipart&part=snippet,status` (λ©μλ: POST)
### λμ: Google Apps Script (GAS) μ½λ ꡬν
λ§μ½ Make.comμ λ²μ΄λ μμ μ½λλ‘ μ μ΄ν λ μ¬μ©νλ ν
νλ¦Ώμ
λλ€.
“`javascript
function uploadVideoDirectly() {
var accessToken = “λ°κΈλ°μ_Access_Token”;
var url = “https://www.googleapis.com/youtube/v3/videos?part=snippet,status”;
var headers = {
“Authorization”: “Bearer ” + accessToken, // Bearer λ€ λμ΄μ°κΈ° 1μΉΈ νμ
“Accept”: “application/json”,
“Content-Type”: “application/json”
};
var videoMetadata = {
“snippet”: {
“title”: “μμ€ν
μ΄ λΉμ΄λΈ μμ΅”,
“description”: “λ°±μλ μ½λλ‘ μμ±λ μλν νμ΄νλΌμΈ”,
“categoryId”: “22”
},
“status”: {
“privacyStatus”: “private”
}
};
var options = {
“method”: “post”,
“headers”: headers,
“payload”: JSON.stringify(videoMetadata),
“muteHttpExceptions”: true
};
var response = UrlFetchApp.fetch(url, options);
Logger.log(response.getResponseCode());
}
“`
—
## 4. μμ κ΄λ¦¬μ νμ₯μ± (Quota & Multi-channel)
νλμ GCP Client IDλ‘ μ¬λ¬ λΈλλ κ³μ μ μ°κ²°νλ κ²μ μν€ν
μ²μ μλ²½ν κ°λ₯νλ©° κΆμ₯λ©λλ€. Make.comμμ Connectionλ§ λΆλ¦¬νμ¬ μ°κ²°νλ©΄ λ©λλ€. λ¨, ꡬκΈμ μλΉ μλ API ν λΉλ(Quota)μ μνμ μΌλ‘ κ³μ°ν΄μΌ ν©λλ€.
– **νλ‘μ νΈλΉ μΌμΌ κΈ°λ³Έ ν λΉλ:** 10,000 Units
– **λμμ μ
λ‘λ 1ν μλͺ¨λ:** 1,600 Units
– **ν루 μ΅λ μ
λ‘λ κ°λ₯ μλ:** `β10,000 / 1,600β = 6 videos/day`
**μ λ΅:** μ΄ν© ν루 6κ°λ₯Ό μ΄κ³Όνλ μ λ‘λκ° νμνλ€λ©΄, λ¨μΌ ID μν€ν μ²λ₯Ό λ²λ¦¬κ³ λΈλλ μ±λλ³λ‘ GCP νλ‘μ νΈλ₯Ό 물리μ μΌλ‘ λΆλ¦¬νμ¬ ν λΉλμ νμ₯ν΄μΌ ν©λλ€.