Twitterのポストスケジューラを構築します.


今日はTwitterのポストスケジューラアプリケーションを構築する予定です.それをTwittlerと呼びましょう.

工具


開始する前に、確認してください
  • お使いのコンピュータ上のノードとNPM.両方ともダウンロードできますnodejs.org .
  • コードエディター.私はvscode好む.あなたはそれをダウンロードできますcode.visualstudio.com .
  • Twittler高レベルアーキテクチャ


    ここでどのように我々のアプリケーションが動作する簡単な概要です.

    クライアント部分:
  • ユーザーはつぶやきを書いて、彼らがそれをスケジュールしたいときに時間を選択し、送信をクリックします.
  • つぶやきは、データベースに入り、そこに格納されます.
  • サーバー部分:
  • NODEJSは、その分を送信する必要があるすべてのつぶやきを取得するデータベースを毎分呼び出します.
  • 次に、nodejs Twitterでこれらのつぶやきを投稿します.
  • Twittler技術スタック


    Twittlerをビルドするには、次のように使います.
  • NODEJS (サーバ上で)
  • ReactJS (クライアントについて)
  • 動物相
  • しかし、我々がコードを掘る前に、まず、Twitter上で投稿を開始するためにTwitter APIへのアクセスを得るためにTwitterの開発者アカウントを作成する必要があります.

    開発者アカウント


    以下はTwitter開発者アカウントの作成方法です.
  • 移動する

  • ボタンをクリックします


  • Twitter APIへのアクセスを取得する理由を選択します


  • すべての次の手順を完了すると、質問に答え、あなたのアプリケーションを提出します.

  • Twitterのチームがあなたのアプリケーションのレビューを終了するまで待機し、APIへのアクセスを提供します

  • Twitterチームがあなたのアプリケーションを承認した後、新しいプロジェクトを作成して作成します.


  • それから、ベアラートークンをコピーして保存します.我々はTwitterのAPIにアクセスする必要があります.

  • さあ、データベースを設定しましょう.

    動物相


    データベースについては、我々は動物を使用します.これは、データの正確性を犠牲にすることなく、アプリケーションのデータにユビキタス、低遅延アクセスを与えるServerlessデータベースです.
  • あなたの動物相口座でログインしてくださいhere .

  • 「データベースを作成」をクリックします


  • 名前と地域を選択


  • 「新しいコレクション」をクリックします


  • コレクション名を選択し、「保存」をクリックします

  • 我々はちょうど“Twittler”と呼ばれる新しいデータベースを作成し、我々のコレクション“つぶやき”私たちのつぶやきを格納するつもりです.
    何をするかcollection ” 動物相のための平均?
    コレクションはドキュメントと呼ばれるデータレコードの集合です.我々のケースでは、1セットのつぶやき.リレーショナルデータベースに精通している場合、コレクションはそれらのテーブルに類似しています.
    今、我々はAPIキーを生成し、我々のサーバーは、それからのつぶやきを取得するデータベースにアクセスできるように我々のアプリケーションにそれらを置く必要があります.次のようにします.

  • “セキュリティ”タブに移動し、“新しいキーをクリックしてください.”


  • キー名を入力し、[保存]をクリックします


  • 私たちのAPIキーが生成されました.

  • キーをどこかに保存します.我々は、後で我々のアプリケーションから動物にアクセスする必要があります.
  • そして最後にすべきことはindex .
    Indexes ファウナでは、私たちが彼らの他の属性によって文書を取り出すのを許しますReference . ドキュメントを見つけるパフォーマンスを向上させるルックアップテーブルとして機能します.あなたが興味を持っているものを見つけるためにあらゆる文書を読む代わりに、それらのドキュメントを見つけるためにインデックスを照会してください.我々は特定の日付範囲からすべてのつぶやきを得るためにインデックスを使用します.
    「index」タブに移動します.

    と新しいインデックスを作成します

    「保存」ボタンをクリックし、クライアントのコードを開始しましょう.

    クライアント


    クライアントアプリケーションを作成するには、我々はreactjsを使用し、我々はすぐにそれを使用してインストールすることができますcreate-react-app .
    端末を開き、次のコマンドを使用してCREATERANTアプリをインストールします.
    npx create-react-app twittler
    
    その後、作成したフォルダに移動し、プロジェクトを初期化します
    cd twittler && npm i
    
    では、クライアントからデータベースへのアクセスを得るためにアプリケーションで使用するFAONAパッケージをインストールしましょう.
    npm i fauna
    
    また、我々は動物相のセキュリティタブで作成した動物の秘密鍵を追加する必要があります.これを行うには.env.local プロジェクトのルートフォルダのファイルを開き、ファウナの秘密キーを入れます.
    // .env.local
    
    REACT_APP_FAUNADB_SECRET=your-secret-key
    
    我々が加える必要がある最後のものはTailwindCSS . これは、ユーティリティのCSSフレームワークを迅速に設計し、任意のCSSを書くことなく、我々のアプリケーションを構築するためです.それを行うには、パブリック/インデックスに移動します.HTMLとTarwindCSSのcssファイルへのリンクを追加します.
    // public/index.html
    
    <html lang="en">
     <head>
       <meta charset="utf-8" />
       <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
       <meta name="viewport" content="width=device-width, initial-scale=1" />
       <meta name="theme-color" content="#000000" />
       <meta
         name="description"
         content="Web site created using create-react-app"
       />
       <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
       <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    
       <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
       <title>Twittler</title>
     </head>
     <body>
       <noscript>You need to enable JavaScript to run this app.</noscript>
       <div id="root"></div>
     </body>
    </html>
    
    これはTailWindCSSをアプリケーションに追加するのに最適な方法ではありませんが、NPMで「正しく」インストールするときに必要な追加のインストール手順を削除します.現実世界のアプリケーションではinstall Tailwind using npm .
    すべてが設定されている今、いくつかのコードを書く時間.UIの作成から始めましょう.

    src/appを開きます.JSとこのコードを追加します
    // src/App.js
    
    import React, {useCallback, useState} from 'react'
    import Fauna from 'Fauna'
    
    const currentDate = new Date().toISOString().substr(0, 10)
    
    const FaunaClient = new Fauna.Client({
     secret: process.env.REACT_APP_FAUNADB_SECRET,
    })
    const q = Fauna.query
    
    function App() {
     const [tweet, setTweet] = useState('')
     const [date, setDate] = useState(currentDate)
     const [time, setTime] = useState(
       new Date().getHours() + ':' + new Date().getMinutes()
     )
    
     const sendTweet = useCallback(
       async (event) => {
         event.preventDefault()
    
         console.log(new Date(`${date} ${time}`).getTime())
         console.log(new Date(`${date} ${time}`))
    
         try {
           FaunaClient.query(
             q.Create(q.Collection('tweets'), {
               data: {
                 tweet,
                 date: new Date(`${date} ${time}`).getTime(),
               },
             })
           )
    
           setTweet('')
         } catch (error) {
           console.log(error)
         }
       },
       [date, time, tweet]
     )
    
     return (
       <form
         onSubmit={sendTweet}
         className="flex flex-col max-w-lg m-auto min-h-screen justify-center"
       >
         <h2 className="mb-6 text-center text-3xl font-extrabold text-gray-900">
           Your Tweet
         </h2>
         <textarea
           required
           maxLength="280"
           rows="5"
           className="mb-6 focus:ring-indigo-500 focus:border-indigo-500 border-2 w-full p-4 sm:text-sm border-gray-300 rounded-md"
           placeholder="I don't understand pineapple pizza"
           value={tweet}
           onChange={(event) => setTweet(event.target.value)}
         />
         <div className="flex items-center mb-8">
           <input
             required
             type="date"
             min={currentDate}
             value={date}
             onChange={(event) => setDate(event.target.value)}
             className="focus:ring-indigo-500 focus:border-indigo-500 border-2 w-full p-4 sm:text-sm border-gray-300 rounded-md mx-4"
           />
           <input
             required
             type="time"
             value={time}
             onChange={(event) => setTime(event.target.value)}
             className="focus:ring-indigo-500 focus:border-indigo-500 border-2 w-full p-4 sm:text-sm border-gray-300 rounded-md mx-4"
           />
         </div>
         <button
           type="submit"
           className="flex justify-center py-4 px-4 border border-transparent font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
         >
           Schedule Tweet
         </button>
       </form>
     )
    }
    
    export default App
    
    
    ここで何が起こっているのか?
    使用Fauna.Client , 我々は、ファウナAPIにアクセスするためのパラメータとして秘密キーを使用してファウナクライアント機能を作成します.
    const FaunaClient = new Fauna.Client({
    
     secret: process.env.REACT_APP_FAUNADB_SECRET,
    
    })
    
    使用FaunaClient.query , 私たちはFAONAにリクエストを送り、新しいドキュメントを作成しますtweet and date パラメータ.
           FaunaClient.query(
    
             q.Create(q.Collection('tweets'), {
    
               data: {
    
                 tweet,
    
                 date: new Date(`${date} ${time}`).getTime(),
    
               },
    
             })
    
           )
    
    このコードをテストするには、端末を開き、次のコマンドを入力します.
    npm start
    
    そして、“私はパイナップルのピザを理解していない”のようなつぶやきを書くようにしてください(真実を言う)、日付、時刻を選択し、クリックして“スケジュールつぶやき”ボタンをクリックします.リクエストが成功すると、コレクションに新しいドキュメントを作成しましたtweets .
    あなたの動物のダッシュボードの結果を表示することができます

    クライアントの部分が完了しました.

    サーバ


    私たちのサーバーはserver アプリケーションのルートフォルダのフォルダ.フォルダを作成し、単一のファイルを配置します.index.js, その中で我々はサーバーを走らせます.
    当社のサーバーを作成するには、人気のあるnodejsフレームワークを使用しますExpressJS (私たちは、アプリケーションのためのnodejsを使用することができますが、ExpressJSと、我々はAPIルートを作成し、将来的に我々の機能アプリケーションを拡張).
    ExpressJSをインストールするには、次のコマンドをプロジェクトのルートフォルダに実行します.
    npm i express
    
    その後、インストールする必要がありますcron-job パッケージは、我々のサーバーは毎分動物を要求することができます.次のコマンドを端末で実行します.
    npm i node-cron
    
    また、インストールする必要がありますdotenv パッケージ.から環境変数をロードします.env.local ファイルprocess.env. このように、我々はアクセスすることができますREACT_APP_FAUNADB_SECRET サーバーコードからの変数.
    これを行うには、次のコマンドを端末で実行します.
    npm i dotenv
    
    インストールする必要がある最後のパッケージは.それはTwitterでつぶやきを投稿するのに役立ちます.
    npm i twitter-api-v2
    
    コーディングを始める前に、前の手順で保存したTwitter APIベアラートークンを追加する必要があります.ファイルを開くには.env.local そして、下にあなたのTwitterのベアラートークンを追加REACT_APP_FAUNADB_SECRET :
    // .env.local
    
    REACT_APP_FAUNADB_SECRET=your-secret-key
    
    TWITTER_BEARER_TOKEN=your-twitter-bearer-token
    
    さて、サーバ自体を書きましょう.オープンserver/index.js このサーバーコードを追加します.
    // server/index.js
    
    const express = require('express')
    const cron = require('node-cron')
    const Fauna = require('Fauna')
    const {TwitterApi} = require('twitter-api-v2')
    
    const twitterClient = new TwitterApi(process.env.TWITTER_BEARER_TOKEN)
    
    const q = Fauna.query
    
    const faunaClient = new Fauna.Client({
     secret: process.env.REACT_APP_FAUNADB_SECRET,
    })
    
    // run every minute
    cron.schedule('* * * * *', async () => {
     const now = new Date()
     now.setSeconds(0)
     now.setMilliseconds(0)
    
     try {
       // get all tweets from Now - 1 minute to Now
       const {data} = await faunaClient.query(
         q.Map(
           q.Paginate(q.Match(q.Index('tweetsByDate'), now.getTime())),
           q.Lambda(['date', 'ref'], q.Get(q.Var('ref')))
         )
       )
    
       // post all tweets from date range on twitter
       data.forEach(async ({data: {tweet}}) => {
         try {
           console.log(tweet)
           await twitterClient.v1.tweet(tweet)
         } catch (error) {
           console.log(error)
         }
       })
     } catch (error) {
       console.log(error)
     }
    })
    
    const app = express()
    
    app.listen(3001, async () => {
     console.log(`Server listening on ${3001}`)
    })
    
    ここで何が面白いのか見てみましょう.
    The cron.schedule 毎分、Twitterにつぶやきを公開するための機能を呼び出します.
    使用faunaClient, 我々は現在の時刻と分の範囲内のすべてのつぶやきを取得します.
       const {data} = await faunaClient.query(
         q.Map(
           q.Paginate(
             q.Range(
               q.Match(q.Index('tweetsByDate')),
               minuteAgo.toISOString(),
               now.toISOString()
             )
           ),
           q.Lambda(['date', 'ref'], q.Get(q.Var('ref')))
         )
       )
    
    と使用twitterClient.v1.tweet(tweet) 我々はTwitterでそれらを投稿します.
    我々のアプリケーションの準備が整いました.さあ、テストしましょう.

    アプリケーションの実行


    まず、スクリプトを作成するpackage.json コマンドを実行するときにWebサーバを起動しますnpm start server コンソールで
    // package.json
    ...
    
    "scripts": {
      "server": "node -r dotenv/config ./server/index.js dotenv_config_path=./.env.local",
      ...
    }
    
    次に端末を開き、実行するnpm start server つのウィンドウで我々のWebサーバーを起動し、別のウィンドウで実行するにはnpm start クライアントを起動します.
    Twitterのポストスケジューラのアプリが準備ができて!
    最後の例でリポジトリを見つけることができますhere .
    第2部では、アプリケーションを配備しますVercel .