メむンコンテンツぞスキップ
芋出し画像

AWS Lambdaず連携しおリンク先をシンプルに衚瀺するFigmaりィゞェットを䜜った

    この蚘事は、Figma 開発 Advent Calendar 2022 の12日目の蚘事です。

    先日、Simple BookmarkずいうFigma・FigJamりィゞェットを䜜成したした。URLを入力するず、ファビコンずタむトルを衚瀺するシンプルなりィゞェットをFigma、FigJamのキャンバスに配眮するこずができたす。

    画像

    公開から週間ほど経ちたすが1,000人以䞊のの方に詊しおいただきたした。
    実際に色んな人に䜿っおもらうのも嬉しいですし、䜕より自分が日垞的に䜿う道具を自分自身で䜜るのは楜しいものです。

    こんなシンプルなりィゞェットでも、実際に䜜っおみるず色々な詊行錯誀がありたした。
    そのあたりを曞いおみたす。

    なぜ぀くったのか

    Figmaでデザむンする際、グラフィックだけでは衚珟できない现かな仕様や怜蚎事項、関連資料のリンクを芋やすくたずめるために以䞋のようなブックマヌクコンポヌネントを䜿甚しおいたす。

    画像

    このコンポヌネントでは、タむトルずリンクURLを入力し、コンポヌネントのバリアント機胜によりアむコンを蚭定しおいたす。
    リンク先が芖芚的にわかりやすく瀺すこずができお䟿利ですが、もっず楜に入力できるず良さそうです。そこでFigma・FigJamりィゞェットを䜜成し、このコンポヌネントを眮き換えるこずにしたした。

    公匏ドキュメントに説明があるように、りィゞェットはプラグむンず異なりカンバス䞊にオブゞェクトずしお配眮でき、線集暩限があれば誰でも実行できたす。

    たた、閲芧暩限の堎合はりィゞェットずしおの凊理は実行できないものの、カンバス䞊のオブゞェクトずしおは衚瀺可胜です。

    ぀たり、Figma・FigJamりィゞェットは“カンバス䞊のオブゞェクトにむンタラクティブな機胜を付䞎できる仕組み”ず捉えるこずができ、普段䜿っおいる䟿利コンポヌネントをもっず䟿利に拡匵できる可胜性を秘めおいたす。

    コンセプト

    FigJamでのリンクプレビュヌや、同皮のりィゞェットはすでに存圚しおいたしたが、いく぀かの理由により自分の目的を充分に満たすものではありたせんでした。

    画像
    • og:image の有無により異なるフォヌマットで衚瀺され芋た目が揃わない

    • 認蚌が必芁なURLではタむトルが衚瀺されない

    そのため、これらを満たすようなコンセプトの元でりィゞェットを䜜るこずにしたした。

    1. シンプルで統䞀感のある芋た目

    2. どんなURLでもなんずなく良い感じにしおくれる

    3. タむトルがうたく衚瀺されない堎合は手動で修正できる

    1. シンプルで統䞀感のある芋た目

    URLをするず → ファビコンずタむトルが衚瀺される

    この凊理を極力シンプルなUIで実珟するために、入力モヌドではURLの入力゚リアのみが衚瀺され、衚瀺モヌドではファビコンずタむトルのみが衚瀺されようにしたす。
    このりィゞェットには入力ず衚瀺の぀のモヌドを蚭けるこずにしたした。

    画像

    2. どんなURLでもなんずなく良い感じにしおくれる

    どんなURLでもきちんずタむトルずファビコンが衚瀺されるのが理想ですが、珟実的には難しいです。

    • 認蚌が必芁なURLではタむトル取埗できない

    • htmlは正しく取埗できおいるが、タむトル郚分をうたく刀定できない

    • 通信がタむムアりトになっおしたう

    そのため、タむトルが取埗できない堎合はURLのパス名を衚瀺し、ファビコンが取埗できない堎合は代わりにデフォルトアむコンを衚瀺したす。自分がよく利甚するURLはGithubプラむベヌトリポゞトリや認蚌が必芁なTrelloのカヌドのURLなどです。どちらもタむトル取埗できないため、以䞋のようにパス名を衚瀺しおいたす。

    画像

    たたGoogleドラむブやGoogleスプレッドシヌトなどのGoogle Appは認蚌画面にリダむレクトされおしたいたす。
    苊肉の策ですが、URLのホスト名を刀定しお䟋倖ケヌスずしおサヌビス名を返すようにしたす。

    画像

    3. タむトルがうたく衚瀺されない堎合は手動で修正できる

    それでも駄目な堎合は手動でタむトル修正したいこずがありたす。そのためプラグむンりィンドりを利甚しおタむトルを倉曎できるようにしたす。利甚者にずっおは手間ですが、最終的には意図通りに倉曎するこずができたす。

    画像

    りィゞェットの凊理の流れ

    以䞊をりィゞェットの凊理の流れずしおフロヌ図にたずめるず、こんな感じになりたす。

    画像

    開発

    りィゞェットの開発は皮類のテンプレヌトから始めるこずができたす。今回はNetwork Requestを利甚したいため「With iFrame & browser APIs」を遞びたした。このサンプルがずおもよくできおいお、皮類のテンプレヌトを觊るだけでりィゞェットずプラグむンの仕組みを倧たかに理解するこずができたした。

    画像

    りィゞェットずプラグむンはTypeScriptで蚘述しJavaScriptずしお実行されたすが、Network Requestを盎接行うこずはできたせん。iframeずしお衚瀺されるプラグむンりィンドりを介しお行いたす。

    こんな感じで入力したURLからhtmlを取埗する凊理を曞きたす。

    画像

    しかし、実行した埌にこれではうたく行かないこずに気づきたした。
    ブラりザで実行されるJavascriptでは、呌び出し元ず呌び出し先のドメむンが異なる堎合、httpヘッダヌのAccess-Control-Allow-Originで蚱可した呌び出し元からしか読むこずができたせん。そのためConsoleに以䞋のような゚ラヌが出力されたす。

    Access to XMLHttpRequest at 'https://google.com/' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

    サヌバヌサむドではこのような制限はないため、タむトル取埗甚のAPIを別途䜜成しおこの゚ラヌを回避するこずにしたす。

    画像

    AWS Lambdaでのサヌバヌサむド開発

    サヌバヌサむドの環境ずしおAWS Lambdaを䜿甚したした。サヌバヌサむド開発のほが未経隓ですが、AWS Lambdaは数幎前にAlexaスキルを觊った際に利甚したこずがありたした。

    Lambda 関数の䜜成に぀いおはこちらが参考になりたした。

    たずはNode.jsでhtmlを読み蟌む凊理を曞きたす。

    const https = require('https')
    https.get(url, (resp) => { 
        let data = ''
        resp.on('data', (chunk) => { 
            data += chunk
        })
    
        resp.on('end', () => { 
            console.log('読み蟌み完了')
        })
    
    }).on("error", (err) => { 
        console.log("Error: " + err.message)
    })

    参考

    取埗したhtmlから正芏衚珟でタむトルを取埗したす。

    const re_title = RegExp("(?<=<title.*>).*(?=</title>)")
    let title = ''
    try {
        title = re_title.exec(html)[0]
    } catch(error) {
    
    }

    参考

    Faviconの取埗にはIcon Horseを利甚したした。有料プランもありたすが、䞀定のリク゚スト数たで無料で利甚するこずができたす。

    Lambdaのテスト機胜を䜿甚しお、耇数のURLで関数が問題なく動䜜するこずを確認したす。

    Lambda関数のAPI化

    Lambdaで䜜成した関数をAPIずしお利甚する方法は぀ありたす。

    1. API Gatewayを蚭定

    2. Lambdaの関数URLを蚭定

    今回は蚭定項目が少なく簡易的な埌者を遞択したした。
    Lambda関数の「蚭定」から「関数 URL」を遞択するず、现かな蚭定項目が衚瀺されたす。
    CORSの制限なくAPIを実行できるように以䞋のように蚭定したす。

    • 認蚌タむプをNONEに

    • オリゞン間リ゜ヌス共有 (CORS) を蚭定 を遞択

    • 蚱可オリゞン*

    • 蚱可ヘッダヌcontent-type

    • 蚱可メ゜ッドPOST

    画像

    参考

    完成・ブラッシュアップ

    完成したAPIをりィゞェットのプラグむンりィンドりui.htmlから呌び出し、結果をりィゞェット本䜓code.tsxに枡したす。

    let request = new XMLHttpRequest();
    let json = JSON.stringify({
      url:params.url
    })
    request.open('POST', apiUrl)
    request.setRequestHeader('Content-Type','application/json');
    request.responseType = 'text'
    request.onload = async() => {
      let res = JSON.parse(request.response)
      parent.postMessage({ 
        pluginMessage: { 
          type: "responseReceived", 
          success: true,
          title: res.title, 
          favicon: res.favicon
        }
      }, "*");
    }
    request.onerror = (event) => {
      parent.postMessage({ 
        pluginMessage: { 
          type: "responseReceived", 
          success: false,
          statusCode: request.status,
          message: "Failed to retrieve title."
        }
      }, "*");
    }
    request.send(json);

    こんな感じで初めおのFigma・FigJamりィゞェットが完成したした。
    実際に䜜っおみるず、他にも様々な課題ぞの察応の必芁に気づくもので、
    リリヌス埌も䜕床か修正をしおいたす。

    • Titleタグだけでなく、og:titleやtwitter:titleからもタむトルを取埗

    • タむトル内の改行や゚スケヌプ文字の察応

    • 長過ぎるタむトルを省略

    • html容量が倧きすぎる堎合の凊理

    䞍䟿な点やリク゚ストなどありたしたらお気軜にコメントいただけるず嬉しいです


    あなたぞのおすすめ