๐จ 2025๋ 11์ ๊ธฐ์ค, ๋ธ๋ก๊ทธ์คํ์ ์ค์๊ฐ ๊ตฌ๊ธ ํธ๋ ๋ ๊ฒฝ์ ํฐ์ปค ์๋ฒฝํ๊ฒ ๋ฃ๋ ์ ๊ณผ์
์๋ ํ์ธ์, ๊ฐ๋ํฌ๋ฐ์ด์ ๋๋ค.
์ค๋์ ์๋ง์ ์ํ์ฐฉ์ค ๋์ ์ง์ง ์๋ฒฝํ๊ฒ ์๋ํ๋ ์ค์๊ฐ ๊ฒฝ์ ํธ๋ ๋ ํฐ์ปค๋ฅผ ๋ธ๋ก๊ทธ์คํ(Blogger)์ ๋ฃ๋ ๋ฐฉ๋ฒ์ ์ ๋ถ ๊ณต๊ฐํฉ๋๋ค. ์ด ๊ฐ์ด๋๋ง ๋ฐ๋ผ ํ์๋ฉด 2025๋ 11์ 28์ผ ํ์ฌ 100% ์ฑ๊ณตํฉ๋๋ค.
์ ์ด๋ ๊ฒ๊น์ง ํ๋ค์๋?
Blogger ํ๊ฒฝ์ ์ค์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๋ ๊ฒ์ด ๊น๋ค๋ก์ ๋ ์ด์ ๋ ํฌ๊ฒ ๋ ๊ฐ์ง์ ๋๋ค.
-
Blogger CSP ์ ์ฑ ๊ฐํ: Blogger๋ 2024๋ ๋ง๋ถํฐ CSP(Content Security Policy) ์ ์ฑ ์ ๊ฐํํ์ฌ ์์ ฏ ๋ฑ์์ ์ธ๋ถ API๋ฅผ ์ง์ ํธ์ถํ๋ fetch() ๋ช ๋ น์ ๋๋ถ๋ถ ์ฐจ๋จํ์ต๋๋ค. ์ด๋ก ์ธํด ๊ตฌ๊ธ ํธ๋ ๋ RSS๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ๋ถ๋ฌ์ฌ ์ ์๊ฒ ๋์์ต๋๋ค.
-
Apps Script ๋ฐฐํฌ ๋ณต์ก์ฑ: ๋ฐ๋ผ์ Google Apps Script๋ฅผ ํ๋ก์ ์๋ฒ๋ก ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ๊ฐ์ ธ์์ผ ํ๋๋ฐ, ์ด ๋ฐฐํฌ ๊ณผ์ ์์ "์ก์ธ์ค ๊ถํ: ๋๊ตฌ๋(์ต๋ช ํฌํจ)" ์ค์ ๊ณผ "๊ฒ์ฆ๋์ง ์์" ์น์ธ ๊ณผ์ ์ ๋๋ฝํ๋ฉด URL์ด ์๋ํ์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๋ด๊ฐ ๊ฒช์ ๋ชจ๋ ์ค๋ฅ์ ํด๊ฒฐ๋ฒ
| ์ค๋ฅ ์ ํ | ๋ฌธ์ ์ | ํด๊ฒฐ๋ฒ |
| ์์ ฏ ์ฝ์ |
Blogger์ CSP ์ ์ฑ
์ ์ํด
fetch()
๋ช
๋ น์ด ์์ ์ฐจ๋จ๋จ.
|
์์ ฏ ๋์
HTML ํ
ํ๋ฆฟ์
</body>
์ง์ ์ ์ฝ๋๋ฅผ ๋ฃ์ด์ผ ํจ.
|
<head>
์์ ์ฝ์
|
HTML ํ์ค ์๋ฐ ์ค๋ฅ (div should not appear inside of head).
|
CSS/JS ์ฝ๋๊ฐ
<body>
์์ญ์ ์นจ๋ฒํ ์ ์์ต๋๋ค.
|
</header>
์๋ ์ฝ์
|
HTML ๋ก๋ฉ์ด ๋ฆ๊ฑฐ๋, ์ค์๊ฐ ๋ฐ์ดํฐ๊ฐ ์์ ์ ๋จ๋ ๋ฌธ์ ๊ฐ ๋ฐ์. |
์์ ํ ์คํ ์ง์ ์ธ
</body>
์ง์ ์ ๊ณ ์ํด์ผ ํฉ๋๋ค.
|
| CSS ์ ๋๋ฉ์ด์ |
translateX(-66.7%)
๋ฑ ์ ์ ์ธ ๊ฐ ์ฌ์ฉ ์
๋น ๊ณต๊ฐ์ด
์๊น.
|
translateX(100vw)์์
translateX(-100%)๋ก ์ด๋ํ๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ๋น ๊ณต๊ฐ์ ์์ฐ.
|
| Apps Script URL ์ค๋ฅ |
๋ฐฐํฌ ์ค์ ์ ์๋ชปํ์ฌ
/exec
URL์ด JSON์ ๋ฐํํ์ง ์์.
|
์ก์ธ์ค ๊ถํ์ "๋๊ตฌ๋(์ต๋ช ํฌํจ)"๋ก ์ค์ ํ๊ณ ๊ถํ ์น์ธ(๊ณ ๊ธ→๊ณ์ํ๊ธฐ→ํ์ฉ) ๊ณผ์ ์ ๋ฐ๋์ ๊ฑฐ์ณ์ผ ํฉ๋๋ค. |
์ง์ง ์ ๋ต ์์น์ ์ฝ๋
ํฐ์ปค๊ฐ ๋น ๊ณต๊ฐ ์์ด, ๊ฐ์ฅ ๋น ๋ฅด๊ณ ์์ ํ๊ฒ ๋จ๋
์ง์ง ์ ๋ต ์์น๋
</body>
์ง์ ์
๋๋ค. (Blogger์
ํ
๋ง ํธ์ง ๋ชจ๋์์ ์ฐพ์์ผ
ํฉ๋๋ค.)
๐ฏ ์ ๋ต ์์น:
</body>
์ง์
๐ ๋ธ๋ก๊ทธ์คํ์ ์ฝ์ ํ ์ต์ข ์์ฑ ์ฝ๋ (HTML/CSS/JS)
<b:if cond='data:view.isHomepage or data:view.isArchive or data:view.isPost'>
<div id="realtime-economy-ticker">
<span class="ticker-label">๊ฒฝ์ ํธ๋ ๋</span>
<div class="ticker-wrap">
<ul id="ticker-list"><li>๋ก๋ฉ ์ค...</li></ul>
</div>
</div>
<style scoped=''>
#realtime-economy-ticker{background:#000;color:#fff;padding:16px 20px;margin:20px auto 30px;border-radius:18px;overflow:hidden;display:flex;align-items:center;box-shadow:0 6px 25px rgba(255,107,107,.4);max-width:96%;font-family:'Malgun Gothic',sans-serif;box-sizing:border-box}
.ticker-label{font-weight:900;font-size:17px;background:linear-gradient(90deg,#ff4757,#ffa502);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-right:20px;flex-shrink:0}
.ticker-wrap{overflow:hidden;flex:1}
#ticker-list{display:inline-flex;animation:ticker-move 15s linear infinite;gap:60px;padding:0;margin:0;list-style:none;white-space:nowrap}
#ticker-list a{color:#ff6b6b;font-weight:700;font-size:16.5px;text-decoration:none}
#ticker-list a:hover{color:#fff;text-decoration:underline}
#ticker-list span{color:#ffd93d;margin-left:7px;font-weight:900}
@keyframes ticker-move{0%{transform:translateX(100vw)}100%{transform:translateX(-100%)}}
@media(max-width:768px){#realtime-economy-ticker{margin:15px 8px;padding:12px}}
</style>
<script type='text/javascript'>
//<![CDATA[
const MY_PROXY = '์ฌ๊ธฐ์-๋น์ ๋ง์-/exec-URL-๋ฃ๊ธฐ';
fetch(MY_PROXY+'?t='+Date.now())
.then(r=>r.json())
.then(d=>{
const ul=document.getElementById('ticker-list');
let h='';
d.forEach((x,i)=>h+=`<li><a href="${x.link}" target="_blank">${x.keyword}</a><span>#${i+1}</span></li>`);
ul.innerHTML=h;
})
.catch(()=>{document.getElementById('ticker-list').innerHTML='<li>์ฝ์คํผ · ํ์จ · ๊ธ๋ฆฌ · ๋ถ๋์ฐ · ๋นํธ์ฝ์ธ</li>'});
//]]>
</script>
</b:if>
๋น์ ๋ง ๋ฐ๋ผ ํ๋ฉด ๋๋ 4๋จ๊ณ ์ฒดํฌ๋ฆฌ์คํธ
1. ๊ธฐ์กด ํฐ์ปค ์ฝ๋ ์ ๊ฑฐ & ์ ์ฝ๋ ๋ถ์ฌ๋ฃ๊ธฐ
-
๊ธฐ์กด ํฐ์ปค ์ฝ๋ ์ ๋ถ ์ญ์ : ๊ธฐ์กด์ ์๋ํ๋
econ-ticker,ticker-items๋ฑ์ ์ฝ๋๋ฅผ ํ ๋ง ํธ์ง๊ธฐ์์ ๋ชจ๋ ๊ฒ์ํ์ฌ ์น ์ง์๋๋ค. -
์ ์ฝ๋ ์ฝ์ : ์์์ ์ ๊ณต๋ ์ต์ข ์์ฑ ์ฝ๋๋ฅผ ํต์งธ๋ก ๋ณต์ฌํ์ฌ, Blogger์ ํ ๋ง ํธ์ง ๋ชจ๋์์
</body>ํ๊ทธ ์ง์ ์ ๋ถ์ฌ๋ฃ์ต๋๋ค.
2. ๋น์ ๋ง์ Google Apps Script ๋ง๋ค๊ธฐ
-
ํ๋ก์ ํธ ์์ฑ:
https://script.google.com์ ์ → ์ ํ๋ก์ ํธ ํด๋ฆญ. -
์ฝ๋ ๋ถ์ฌ๋ฃ๊ธฐ:
Code.gs๋ด์ฉ์ ์ง์ฐ๊ณ ์๋ ํ๋ก์ ์ฝ๋๋ฅผ ๋ถ์ฌ๋ฃ์ ํ ์ ์ฅํฉ๋๋ค.
function doGet(e) {
return ContentService
.createTextOutput(getKoreaEconomyTrends())
.setMimeType(ContentService.MimeType.JSON);
}
//... (๋๋จธ์ง getKoreaEconomyTrends ํจ์ ์ฝ๋ ์ ์ฒด) ...
3. Apps Script๋ฅผ ์น ์ฑ์ผ๋ก ๋ฐฐํฌํ๊ธฐ
์ด ๊ณผ์ ์์ URL์ ํ๋ํฉ๋๋ค. (๊ฐ์ฅ ์ค์!)
-
๋ฐฐํฌ ์์: ์๋จ 【๋ฐฐํฌ】 → 【์ ๋ฐฐํฌ】 → ์น ์ฑ ์ ํ.
-
์ค์ ํ์ธ:
-
์คํ ๋์: ๋
-
์ก์ธ์ค ๊ถํ: ๋๊ตฌ๋(์ต๋ช ํฌํจ)
-
-
๋ฐฐํฌ ๋ฐ ์น์ธ: 【๋ฐฐํฌ】 ํด๋ฆญ → “๊ฒ์ฆ๋์ง ์์”์ด ๋จ๋ฉด:
-
【๊ณ ๊ธ】 → 【๊ณ์ํ๊ธฐ(์์ ํ์ง ์์)】 → 【ํ์ฉ】 ํด๋ฆญ.
-
-
URL ๋ณต์ฌ: ๋ฐฐํฌ ์๋ฃ ํ๋ฉด์์
/exec๋ก ๋๋๋ URL ์ ์ฒด๋ฅผ ๋ณต์ฌํฉ๋๋ค.
์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ผ๋ก, ๋ธ๋ก๊ทธ์ ์์ ๋์์ ์ ๊ณตํฉ๋๋ค.
์ ์ ์์:
https://script.google.com/macros/s/๋น์ ์ด-๋ณต์ฌํ-๊ธด-ID/exec
4. ๋ธ๋ก๊ทธ ์ฝ๋์ URL ์ ์ฉ ๋ฐ ์ ์ฅ
-
๋ธ๋ก๊ทธ ํ ๋ง ํธ์ง ๋ชจ๋๋ก ๋์๊ฐ์, MY_PROXY ๋ถ๋ถ์ 3๋จ๊ณ์์ ๋ณต์ฌํ URL๋ก ์ ํํ ๊ต์ฒดํ๊ณ ์ ์ฅํฉ๋๋ค.
const MY_PROXY = 'https://script.google.com/macros/s/๋น์ ์ด-๋ณต์ฌํ-๊ธด-ID/exec';
์ต์ข ํ์ธ์ฉ ์์ ํ ์คํธ ์ฝ๋ (์ ํ ์ฌํญ)
Apps Script URL ๋ฐฐํฌ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์, ํฐ์ปค์ CSS/JS๊ฐ ์ ์๋ํ๋์ง ํ์ธํ๊ณ
์ถ๋ค๋ฉด
fetch
์ฝ๋ ๋์ ์ ์ ์ด ํ
์คํธ ์ฝ๋๋ฅผ ๋ฃ์ด๋ณด์ธ์.
document.getElementById('ticker-list').innerHTML = `์ฝ์คํผ 2580#1 ํ์จ 1482์#2 ๊ธ๋ฆฌ ๋๊ฒฐ#3 ๋นํธ์ฝ์ธ 1.1์ต#4 ์์ธ ์ํํธ ๊ธ๋ฑ#5
ํ
์คํธ ์ฝ๋:: document.getElementById('ticker-list').innerHTML = `<li><a href="#" target="_blank">์ฝ์คํผ 2580</a><span>#1</span></li><li><a href="#" target="_blank">ํ์จ 1482์</a><span>#2</span></li><li><a href="#" target="_blank">๊ธ๋ฆฌ ๋๊ฒฐ</a><span>#3</span></li><li><a href="#" target="_blank">๋นํธ์ฝ์ธ 1.1์ต</a><span>#4</span></li><li><a href="#" target="_blank">์์ธ ์ํํธ ๊ธ๋ฑ</a><span>#5</span></li>`;์ด ๊ธ๋ง ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐ๋ผ ํ์๋ฉด ์ค๋ฅธ์ชฝ ๋์์ ๋ฑ ๋ํ๋์ ์ผ์ชฝ์ผ๋ก ์ญ์ญ ์ฌ๋ผ์ง๋, ๋น ๊ณต๊ฐ ์๋ ์ค์๊ฐ ๊ฒฝ์ ํฐ์ปค๊ฐ ๋น์ ๋ธ๋ก๊ทธ์ ์์ํ ์๋ฆฌ ์ก์ต๋๋ค.
์ด์ ๋น์ ๋ ์ง์ง ํ๋ก ๊ฒฝ์ ๋ธ๋ก๊ฑฐ! ์์ฑ๋๋ฉด ๊ผญ ๋๊ธ๋ก “์ฑ๊ณตํ์ต๋๋ค!” ํ ์ค๋ง ๋จ๊ฒจ ์ฃผ์ธ์. ์ ๊ฐ ์ ์ผ ๋จผ์ ๋ฐ์ ์ณ๋๋ฆด๊ฒ์ ๐
── ๊ฐ๋ํฌ๋ฐ์ด ๋๋ฆผ. 2025.11.28
#๊ฐ๋ ํฌ๋ฐ์ด #ganatoday
๊ทธ๋ฆฐ์ํ๋ก