Twitter API-v2 라이브러리에서 Twitter 검색

개시하다


Twitter API-v2 라이브러리에서

인스턴스 생성


  • TwitterApi의 인스턴스 생성
  • 현재 트위터 API의 v1과 v2가 모두 해당
  • v1 스타일
  • access_키 등 4개의 키나 토큰에서 생성
  • v2 스타일
  • bear-token의 생성

  • 이번에는 v2 스타일로 만들어봤습니다.
    (겸사겸사 트위터에 앞으로 v2가 주류가 될 것이라고 발표했다)
  • const client = new TwitterApi('<YOUR-TWITTER-BEARER-TOKEN>');
    
    // Read+Write level
    const rwClient = client.readWrite;
    
    // Read-only level
    const roClient = client.readOnly;
    

    트위터 가져오기


    example
    // Get and delete old rules if needed
    const rules = await client.v2.streamRules();
    if (rules.data?.length) {
      await client.v2.updateStreamRules({
        delete: { ids: rules.data.map(rule => rule.id) },
      });
    }
    
    // Add our rules
    await client.v2.updateStreamRules({
      add: [{ value: 'JavaScript' }, { value: 'NodeJS' }],
    });
    
    const stream = await client.v2.searchStream({
      'tweet.fields': ['referenced_tweets', 'author_id'],
      expansions: ['referenced_tweets.id'],
    });
    // Enable auto reconnect
    stream.autoReconnect = true;
    
    stream.on(ETwitterStreamEvent.Data, async tweet => {
      // Ignore RTs or self-sent tweets
      const isARt = tweet.data.referenced_tweets?.some(tweet => tweet.type === 'retweeted') ?? false;
      if (isARt || tweet.data.author_id === meAsUser.id_str) {
        return;
      }
    
      // Reply to tweet
      await client.v1.reply('Did you talk about JavaScript? love it!', tweet.data.id);
    });
    
    각 요소를 살펴보겠습니다.

    가져올 규칙 설정


    지난번 규칙이 남았으면 삭제하는 처리입니다.


    // Get and delete old rules if needed
    const rules = await client.v2.streamRules();
    if (rules.data?.length) {
      await client.v2.updateStreamRules({
        delete: { ids: rules.data.map(rule => rule.id) },
      });
    }
    
  • streamRules 방법을 탐색해 보다

  • 연결
  •     /**
         * Return a list of rules currently active on the streaming endpoint, either as a list or individually.
         * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream-rules
         */
        streamRules(options?: Partial<StreamingV2GetRulesParams>): Promise<StreamingV2GetRulesResult>;
        /**
         * Add or delete rules to your stream.
         * To create one or more rules, submit an add JSON body with an array of rules and operators.
         * Similarly, to delete one or more rules, submit a delete JSON body with an array of list of existing rule IDs.
         * https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/post-tweets-search-stream-rules
         */
        updateStreamRules(options: StreamingV2AddRulesParams, query?: Partial<StreamingV2UpdateRulesQuery>): Promise<StreamingV2UpdateRulesAddResult>;
    
  • GET/2/tweet/search/stream/rules의response의 한 예
  • 마지막 검색 시 검색 조건
  • 을 반환합니다.
      {
      "data": [
        {
          "id": "1165037377523306497",
          "value": "dog has:images",
          "tag": "dog pictures"
        },
        {
          "id": "1165037377523306498",
          "value": "cat has:images -grumpy"
        }
      ],
      "meta": {
        "sent": "2019-08-29T01:12:10.729Z"
      }
    }
    
  • 업데이트 스트리밍 방법 탐색

  • 연결
  • StreamRules의 Post Edition
  • streamRules의dd 또는 delete
  • 를 만들 수 있습니다.

    검색하려는 Word 추가 처리


    // Add our rules
    await client.v2.updateStreamRules({
      add: [{ value: 'JavaScript' }, { value: 'NodeJS' }],
    });
    
  • 조건JavaScript 또는 NodeJS의 트위터
  • 설정된 Word로 읽어들이기


  • 공식 example
  • JavaScript 또는 NodeJS 트윗
  • 포함
  • RT 및 자체 트위터 제외
  • 리플리 보내는 중
    const stream = await client.v2.searchStream({
      'tweet.fields': ['referenced_tweets', 'author_id'],
      expansions: ['referenced_tweets.id'],
    });
    // Enable auto reconnect
    stream.autoReconnect = true;
    
    stream.on(ETwitterStreamEvent.Data, async tweet => {
      // Ignore RTs or self-sent tweets
      const isARt = tweet.data.referenced_tweets?.some(tweet => tweet.type === 'retweeted') ?? false;
      if (isARt || tweet.data.author_id === meAsUser.id_str) {
        return;
      }
    

  • 검색 스트림 검색 방법

  • 연결
  • Queryparameter는 다양한 설정을 할 수 있습니다.
  • expansions
  • media.fields
  • tweet.fields 등

  • 트위터에 회신한 처리는 이번 취지와 맞지 않아 생략했다
  • 실행 결과

  • 리플리가 너무 귀찮아서 콘솔.로그(twitter) 확인
  • >  {
    >    data: {
    >      author_id: '84208574',
    >      id: '1517746807451037696',
    >      text: 'Hello guys,\n' +
    >        'Does anyone know where it is a company that has whatsapp api services?\n' +
    >        'I only need to integrate with my backend (node + express) and use it as an outgoing message.\n' +
    >        'I preferred pay as go (per message)\n' +
    >        'Have a green check wa account\n' +
    >        '\n' +
    >        '#Nodejs #whatsappAPI #WebDevelopment'
    >    },
    >    matching_rules: [ { id: '1517746830268067840', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '731117954188775424',
    >      id: '1517746817114554368',
    >      text: 'Siempre habra un color para cada momento del dia, ahorita mismo estoy muy #5df497\n' +
    >        '\n' +
    >        ' #bot #nodejs #random #color #face #emoji #programacion #meme #api https://t.co/Zioq4MbP3B'
    >    },
    >    matching_rules: [ { id: '1517746830268067840', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '1499252873103695873',
    >      id: '1517746858780626945',
    >      text: 'うーいんだよ~\n' +
    >        '\n' +
    >        'これはオススメだね~\n' +
    >        'だってプログラムの書き方や考え方が、 うーいんの中の人と同じ思想だからね~\n' +
    >        '\n' +
    >        'スラスラ読める JavaScript ふりがなプ ログラミング (ふりがなプログラミングシリーズ) https://t.co/qc0ljSyx80\n' +
    >        '\n' +
    >        '#プログラミング勉強中'
    >    },
    >    matching_rules: [ { id: '1517746830268067841', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '69941978',
    >      id: '1517746856687980544',
    >      referenced_tweets: [ [Object] ],
    >      text: "@_gulam_anas_ Thanks Anas for the feedback. Yeah I have considered people's feedbacks from the similar post I made last month. Based on those, I have added/rectified\n" +
    >        '\n' +
    >        '&gt; Other Skills\n' +
    >        '&gt; Practice\n' +
    >        '&gt; Frequently Asked Questions\n' +
    >        '\n' +
    >        'I also added links to HTML/CSS and JavaScript individual roadmaps.'
    >    },
    >    includes: { tweets: [ [Object] ] },
    >    matching_rules: [ { id: '1517746830268067841', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '1401391924754325512',
    >      id: '1517746862173925377',
    >      text: 'UDP is better in the COVID era since it avoids unnecessary handshakes.\n' +
    >        '\n' +
    >        '#programming #programmingjoke #programminghumor #Python #javascript #Java'
    >    },
    >    matching_rules: [ { id: '1517746830268067841', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '1078992647933448192',
    >      id: '1517746892800544769',
    >      text: 'Change file name from backend to server https://t.co/NK0LynUzuM #github #JavaScript #SCSS #HTML #CSS'
    >    },
    >    matching_rules: [ { id: '1517746830268067841', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '950931957860286464',
    >      id: '1517746905190649856',
    >      text: '【人気!】\n' +
    >        'カテゴリー: プログラミング\n' +
    >        '「ゲームを作りながら楽しく学べるHTML5+CSS+JavaScriptプログラミング[改訂版] (Future Coders(NextPublishing))」\n' +
    >        '44%OFF / 821円\n' +
    >        'https://t.co/ACHcL4ZSGa'
    >    },
    >    matching_rules: [ { id: '1517746830268067841', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '1163939968559058944',
    >      id: '1517746926191525888',
    >      referenced_tweets: [ [Object] ],
    >      text: '@sourav_code Well explained 👌'
    >    },
    >    includes: { tweets: [ [Object] ] },
    >    matching_rules: [ { id: '1517746830268067841', tag: '' } ]
    >  }
    >  {
    >    data: {
    >      author_id: '13821792',
    >      id: '1517746998015033344',
    >      referenced_tweets: [ [Object] ],
    >      text: 'Javaが出てきた時はOSを代替すると 言われて期待されたけど、アップレットとかまとも に動かなくてサーバーサイドにピボットした。\n' +
    >        'ネスケのJavascriptは最初バグだらけで 使い物にならなくて、10年くらいたってやっとまと もに使えるようになった。\n' +
    >        '技術が成熟するには時間がかかるね。 https://t.co/AY92UoXZqd'
    >    },
    >    includes: { tweets: [ [Object] ] },
    >    matching_rules: [ { id: '1517746830268067841', tag: '' } ]
    >  }
    !  functions: Your function timed out after ~60s. To configure this timeout, see
          https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation.
    

  • Cloud Function for Firebase에서 실험한 결과, 얻었지만 중간에 시간이 초과되었습니다.
  • 트위터를 너무 많이 얻었나?
  • 얻은 트위터 수를 조정하면 검색 결과를 잘 얻을 수 있을 것 같아
  • Cloud Function의 시간 초과 설정 등은 다음과 같다.
  • https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation

  • 문자의 대문자와 소문자를 검색해도 개의치 않는 모습
  • 끝말

  • 트위터 API-v2를 사용하면 트위터 API를 간단하게 조작할 수 있다(하지만 트위터 API의 규격을 읽어야 한다...)
  • 향후 시간 제한 없이 어플리케이션 개발에 사용
  • 참고 자료


  • Twitter API



  • 좋은 웹페이지 즐겨찾기