Lambda + EventBridge で関数の定期実行を実現した際の画面

📝 AWS Lambda で cron みたいに定期実行する

コンテナをホットスタンバイさせるために EC2 でインスタンス起動して cron で ping 飛ばしていたのですが、コスト的に勿体ないなーと思っていました。しかし、「AWS Lambda 使えばいいじゃん」という指摘を受け、確かにってなったので cron で定期実行していた ping 処理を AWS Lambda + EventBridge で置き換えました。 実は Heroku Scheduler とか使って同様のことをしていた時期もあったのですが、10 分毎しか実行できない制約があったりして使い勝手が悪かったので、後々も使っていけそうな知見な気がしたのでメモがてら記事で残しておくことにしました。 まず、AWS Console から Lambda サービスを選択して関数を新たに作成します。 1. AWS Lambda のトップ画面から関数作成のための画面に遷移する 2. 必要な情報を入力して Lambda の関数を作成する 関数が作成でき次第、ping 処理を書いていきます。http リクエストを行うためのライブラリとして Node.js の標準モジュール(https) を利用します。 Lambda 関数作成直後の index.js は下記のような記述になっていると思います。 // index.js exports.handler = async (event) => { // TODO implement const response = { statusCode: 200, body: JSON.stringify("Hello from Lambda!"), }; return response; }; こちらを Node.js の標準モジュール(https) を利用する形で下記のように書き換えます。 ...

1月 4, 2021 · 1 分 · Me

📝 React で highlight.js を適用する方法

Zenn.badge を作成する時に React に highlight.js を組み込もうとしたのですが、若干躓いてしまったので対処法についてメモっておきます。 React は既にプロジェクトにインストール済みと仮定します。 # 一応 React をインストールするためのコマンドは ↓ npm i --save react react-dom まずは highlight.js を NPM or Yarn でインストールします。 # NPM で highlight.js をインストールする npm i --save highlight.js yarn add highlight.js その後、React ソースコードに highlight.js を組み込みます。 ソースコードの全体像は下記のとおりです。 import Head from 'next/head' import styles from '../styles/Home.module.css' import React, { useState, useEffect } from 'react'; /** highlight.js を import する */ import hljs from 'highlight.js/lib/core'; /** シンタックスハイライトしたい言語のみ import として登録する 今回は html をハイライトしたかったので xml を import した デザインは highlight.js/styles/~ を変更することで調整可能 https://highlightjs.org/ のトップページから各種デザインについては確認可能 (コード右下にある style の右側リンククリックで各種デザインのプレビューが可能) */ import xml from 'highlight.js/lib/languages/xml'; import 'highlight.js/styles/github.css'; hljs.registerLanguage('xml', xml); let inputChecker = null; export default function Home() { const [user, setUser] = useState('nikaera'); const [previewUser, setPreviewUser] = useState('nikaera'); const [badgeCode, setBadgeCode] = useState('nikaera'); const [style, setStyle] = useState('plastic') /** useEffect のタイミングで hightlight.js の初期化を行う。 called プロパティを false にすることで highlight.js で、 コードが変更された場合でも常にシンタックスハイライトすることが可能 */ useEffect(() => { hljs.initHighlighting(); hljs.initHighlighting.called = false; }); useEffect(() => { /** シンタックスハイライトしたいコード input フォームへの入力内容に応じて動的に変わる */ setBadgeCode(` <!-- Like のバッジ --> <a href="https://zenn.dev/${user}"> <img src="https://zenn-badge.herokuapp.com/s/${user}/likes?style=${style}" alt="${user} likes" /> </a> <!-- Articles のバッジ --> <a href="https://zenn.dev/${user}/articles"> <img src="https://zenn-badge.herokuapp.com/s/${user}/articles?style=${style}" alt="${user} articles" /> </a> <!-- Followers のバッジ --> <a href="https://zenn.dev/${user}/followers"> <img src="https://zenn-badge.herokuapp.com/s/${user}/followers?style=${style}" alt="${user} followers" /> </a> <!-- Books のバッジ --> <a href="https://zenn.dev/${user}/books"> <img src="https://zenn-badge.herokuapp.com/s/${user}/books?style=${style}" alt="${user} books" /> </a> <!-- Scraps のバッジ --> <a href="https://zenn.dev/${user}/scraps"> <img src="https://zenn-badge.herokuapp.com/s/${user}/scraps?style=${style}" alt="${user} scraps" /> </a>`); }, [user, style]); const handleChange = (event) => { if (inputChecker) clearTimeout(inputChecker); inputChecker = setTimeout(() => { clearTimeout(inputChecker); inputChecker = null; setPreviewUser(event.target.value); }, 1 * 1000); // 1 seconds setUser(event.target.value); }; const handleSelect = (event) => { setStyle(event.target.value); } return ( <div className={styles.container}> <Head> <title>Zenn.badge</title> <link rel="icon" href="zenn.svg" type="image/svg+xml" /> <meta name="description" content="GitHub Profile に載せるための Zenn の各種スコアバッジを作成するためのウェブサービス" /> <meta name="keywords" content="Zenn, GitHub, GitHub Profile, Shields.io" /> <meta name="author" content="nikaera" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta property="og:url" content="https://zenn-badge.vercel.app/" /> <meta property="og:type" content="website" /> <meta property="og:title" content="Zenn.badge" /> <meta property="og:description" content="GitHub Profile に載せるための Zenn の各種スコアバッジを作成するためのウェブサービス" /> <meta property="og:site_name" content="Zenn.badge" /> <meta property="og:image" content="https://zenn-badge.vercel.app/ogp_image.png" /> </Head> <main className={styles.main}> <h1 className={styles.title}> Welcome to <a href="https://zenn-badge.nikaera.vercel.app/">Zenn.badge!</a> </h1> <p className={styles.description}> <a href="https://zenn.dev/" target="_blank" rel="noopener noreferrer">Zenn</a> のスコアを GitHub 風のバッジに変換するサービスです。 </p> <div> <h3>注意事項 &rarr;</h3> <p>下記の事項にご留意ください。</p> <ul> <li>12時間ほどデータがキャッシュされます</li> <li>100%の動作を保証するものではありません</li> <li>APIの利用数制限などにより、表示されない事があります</li> <li>GitHub Profile にご利用ください</li> </ul> <h3>アカウント名を入力してください &rarr;</h3> <input type="text" value={user} onChange={handleChange} /> <select name="style" value={style} onChange={handleSelect}> <option value="plastic">plastic</option> <option value="flat">flat</option> <option value="flat-square">flat-square</option> <option value="for-the-badge">for-the-badge</option> <option value="social">social</option> </select> { /* pre -> code タグ内に highlight.js で シンタックスハイライトしたい内容を出力する */ } <pre style={{ width: '80vw' }}> <code className="xml"> {badgeCode} </code> </pre> <h3>プレビュー &rarr;</h3> <h4>Likes 👍</h4> <a href={`https://zenn.dev/${previewUser}`}> <img src={`https://zenn-badge.herokuapp.com/s/${previewUser}/likes?style=${style}`} alt={`${previewUser} likes`} /> </a> <h4>Articles 📝</h4> <a href={`https://zenn.dev/${previewUser}/articles`}> <img src={`https://zenn-badge.herokuapp.com/s/${previewUser}/articles?style=${style}`} alt={`${previewUser} articles`} /> </a> <h4>Followers 👱</h4> <a href={`https://zenn.dev/${previewUser}/followers`}> <img src={`https://zenn-badge.herokuapp.com/s/${previewUser}/followers?style=${style}`} alt={`${previewUser} followers`} /> </a> <h4>Books 📚</h4> <a href={`https://zenn.dev/${previewUser}/books`}> <img src={`https://zenn-badge.herokuapp.com/s/${previewUser}/books?style=${style}`} alt={`${previewUser} books`} /> </a> <h4>Scraps 🗑️</h4> <a href={`https://zenn.dev/${previewUser}/scraps`}> <img src={`https://zenn-badge.herokuapp.com/s/${previewUser}/scraps?style=${style}`} alt={`${previewUser} scraps`} /> </a> <h3>問い合わせ &rarr;</h3> <div> 下記 GitHub の Issue で <a className={styles.link} href="https://github.com/nikaera">nikaera</a> にメンションを付けてご連絡ください。 <ul> <li><a className={styles.link} href="https://github.com/nikaera/zenn-badge">Zenn.badge</a></li> </ul> </div> </div> </main> <footer className={styles.footer}> 制作者:&nbsp;<a className={styles.link} href="https://zenn.dev/nikaera" target="_blank" rel="noopener noreferrer">nikaera</a> </footer> </div> ) }

12月 23, 2020 · 3 分 · Me

📝 Hugo で外部リンクを target="_blank" で開く方法

Hugo で設定した外部リンクを開くときは別ウィンドウで開けるようにしたかったので、Hugo のテーマファイルをオーバーライドして対応しました。外部リンクが設定されているときのみ a タグに target="_blank" rel="noopener noreferrer" が追加されるようにしました。 テンプレートファイルは GO の HTML テンプレートで書かれているので、その書式にしたがって a タグの属性を書き換えることで、外部リンクの場合は target="_blank" rel="noopener noreferrer" を追加します。 下記は hugo-PaperMod で、メインメニューの a タグに target="_blank" rel="noopener noreferrer" を追加するときのサンプルになります。 <ul class="menu" id="menu" onscroll="menu_on_scroll()"> <!-- `.Site.Menues.main` の要素数 (メニュー数) ループします --> {{- range .Site.Menus.main }} <!-- 要素内の .URL にアクセスすることで設定されているリンクにアクセスする。 設定されている URL のプレフィクスが https:// or http:// であれば、 絶対リンクが設定されているはずなため、外部リンクが設定されているとみなす。 --> {{- $is_abs_url := or (strings.HasPrefix .URL "https://") (strings.HasPrefix .URL "http://") }} <!-- もし外部リンクが設定されていれば、そのまま .URL の内容を出力する。 そうでなければ、内部リンクを language プレフィクスを付与した形で出力する。 --> {{- $menu_item_url := (cond $is_abs_url .URL (printf "%s/" .URL) ) | absLangURL }} <li> <!-- 外部リンクが設定されていたら ($is_abs_url が true なら) a タグに target="_blank" rel="noopener noreferrer" を設定する --> <a href="{{ $menu_item_url }}" {{- if $is_abs_url }} target="_blank" rel="noopener noreferrer" {{- end}}> <span {{- if eq $menu_item_url $page_url }} class="active" {{- end }}> {{ .Name }} </span> </a> </li> {{- end -}} </ul>

12月 17, 2020 · 1 分 · Me