Google Apps ScriptとDify APIを使ってニュースを自動取得しLINEに投稿する方法


# Google Apps ScriptとDify APIを使ってニュースを自動取得しLINEに投稿する方法

近年、プログラミングを使ってWeb上の情報を自動的に収集・加工・発信するという取り組みが広がっています。本記事では、Google Apps ScriptとDify APIを利用して、経済ニュースを自動取得しLINEに投稿する方法を解説します。プログラミング初心者の方にも分かるよう、丁寧に手順を追って説明していきますので、ぜひ最後までお付き合いください。

## 必要なもの
- Google アカウント
- [Dify API]（APIキーの発行が必要）
- [LINE Notify](https://notify-bot.line.me/ja/)のアカウント（アクセストークンの発行が必要）

## 手順
### 1. Google Apps Scriptの準備
まずはGoogle Apps Scriptの環境を整えましょう。Google Driveの中に新しいApps Scriptのプロジェクトを作成します。プロジェクト名は任意で構いません。

### 2. Dify APIを利用してニュースを取得する関数を作る
Dify APIを使うと、指定したトピックに関連するニュース記事を簡単に取得することができます。以下のようなコードを書いて、ニュース取得用の関数を定義しましょう。

```js
function fetchNewsAndPost(topic) {
  var url = 'https://api.dify.ai/v1/workflows/run';
  var payload = {
    'inputs': {
      'query': 'today news of ' + topic +' today is ',
      'language':'ja'
    },
    'response_mode': 'blocking',
    'user': 'abc-123'
  };
  var options = {
    'method': 'post',
    'contentType': 'application/json',
    'headers': {
      'Authorization': 'Bearer ' + API_DIFY_KEY
    },
    'payload': JSON.stringify(payload)
  };
  
  var response = UrlFetchApp.fetch(url, options);
  var data = JSON.parse(response.getContentText());
  Logger.log(data);
  message = data['data']['outputs']['text'];
  sendLineNotification(message);
}
function fetcchaboutjapan(){
  fetchNewsAndPost('economy of japan');
}


```

ここでは、`fetchNewsAndPost`という関数を定義しています。引数の`topic`で指定されたトピックのニュースを、Dify APIを使って取得し、LINEに投稿するという一連の処理を行います。

`API_DIFY_KEY`の部分は、実際のAPIキーに置き換えてください。Dify APIのダッシュボードからキーを取得できます。

### 3. 取得したニュースをLINEに投稿する関数を作る
次に、LINE Notifyを使ってニュースをLINEに投稿する関数を定義します。以下のようなコードを追加しましょう。

```js
function sendLineNotification(messageText) {
  // 固定のメッセージを設定
  // var messageText = "Hello World!えいーーい";

  // LINE NotifyのトークンとAPI URL
  var lineNotifyToken = API_LINE_KEY;
  var lineNotifyApiUrl = "https://notify-api.line.me/api/notify";

  // 通知メッセージ作成
  var message = '' + messageText;

  // リクエストヘッダー
  var headers = {
    "Authorization": "Bearer " + lineNotifyToken,
    "Content-Type": "application/x-www-form-urlencoded"
  };
  
  // リクエストパラメータ
  var payload = {
    "message": message
  };
  
  // リクエストオプション
  var options = {
    "method" : "post",
    "headers" : headers,
    "payload" : payload
  };
  
  // LINE Notify APIにリクエストを送信
  var response = UrlFetchApp.fetch(lineNotifyApiUrl, options);

  // レスポンスをログに出力（デバッグ用）
  Logger.log(response.getContentText());
}
```

ここでは、`sendLineNotification`という関数を定義し、引数の`message`をLINEに投稿します。`LINE_NOTIFY_TOKEN`の部分は、LINE Notifyのマイページから発行したアクセストークンに置き換えてください。

### 4. 定期実行の設定をする
最後に、先ほど作った関数を定期的に実行するよう設定しましょう。経済ニュースを例にすると、以下のようなコードを追加します。

```js
function fetcchaboutjapan(){
  fetchNewsAndPost('economy of japan');
}
```

この`fetcchaboutjapan`関数を、Google Apps Scriptの「トリガー」機能で定期実行するように設定すれば完成です。例えば毎朝9時に実行するなら、時間主導型のトリガーを追加し、朝9時を指定します。

## 応用編
本記事では経済ニュースを例にしましたが、`fetchNewsAndPost`関数の引数を変えることで、他のトピックのニュースも簡単に取得・投稿できます。スポーツやエンタメなど、自分の興味関心に合わせてカスタマイズしてみてください。

また、取得したニュースをLINEだけでなく、SlackやTwitterに投稿することもできます。各サービスのAPIを調べて、ぜひ挑戦してみてください。

## Difyワークフローの概要
myNewsScraperは、ユーザー定義のクエリに基づいて関連するニュース記事を収集し、それらを要約して簡潔な概要を提供することを目的としています。ワークフローは、次の4つの主要なステップで構成されています。

1. **ユーザー入力**: ユーザーは、関心のあるニュースのトピックをクエリとして入力します。
2. **Tavily Search**: Tavily Search APIは、ユーザーのクエリと現在の時刻を組み合わせて、ウェブから関連するニュース記事を取得します。
3. **Claude 3 LLM**: Claude 3 LLMは、取得したニュース記事を分析し、ユーザーのクエリに関連する情報を抽出して要約します。
4. **出力**: 要約されたニュースの概要がユーザーに提供されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486826/d9d9b37e-5ad6-792b-a007-9849f82a1280.png)

```yaml
app:
  description: ''
  icon: "\U0001F916"
  icon_background: '#FFEAD5'
  mode: workflow
  name: myNewsScraper
workflow:
  features:
    file_upload:
      image:
        enabled: false
        number_limits: 3
        transfer_methods:
        - local_file
        - remote_url
    opening_statement: ''
    retriever_resource:
      enabled: false
    sensitive_word_avoidance:
      enabled: false
    speech_to_text:
      enabled: false
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
      language: ''
      voice: ''
  graph:
    edges:
    - data:
        sourceType: start
        targetType: tool
      id: 1715050473214-1715050485745
      source: '1715050473214'
      sourceHandle: source
      target: '1715050485745'
      targetHandle: target
      type: custom
    - data:
        sourceType: tool
        targetType: llm
      id: 1715051776861-1715050510521
      source: '1715051776861'
      sourceHandle: source
      target: '1715050510521'
      targetHandle: target
      type: custom
    - data:
        sourceType: llm
        targetType: end
      id: 1715050510521-1715050718573
      source: '1715050510521'
      sourceHandle: source
      target: '1715050718573'
      targetHandle: target
      type: custom
    - data:
        sourceType: tool
        targetType: tool
      id: 1715050485745-1715051776861
      source: '1715050485745'
      sourceHandle: source
      target: '1715051776861'
      targetHandle: target
      type: custom
    nodes:
    - data:
        desc: ''
        selected: false
        title: "\u958B\u59CB"
        type: start
        variables:
        - label: query
          max_length: 1000
          options: []
          required: true
          type: paragraph
          variable: query
        - label: language
          max_length: 48
          options:
          - ja
          - en
          required: true
          type: select
          variable: language
      height: 115
      id: '1715050473214'
      position:
        x: 84.18917648389794
        y: 282
      positionAbsolute:
        x: 84.18917648389794
        y: 282
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 243
    - data:
        desc: ''
        provider_id: time
        provider_name: time
        provider_type: builtin
        selected: false
        title: Current Time
        tool_configurations:
          timezone: UTC
        tool_label: Current Time
        tool_name: current_time
        tool_parameters: {}
        type: tool
      height: 89
      id: '1715050485745'
      position:
        x: 381.04729412097447
        y: 282
      positionAbsolute:
        x: 381.04729412097447
        y: 282
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 243
    - data:
        context:
          enabled: false
          variable_selector: []
        desc: ''
        model:
          completion_params:
            temperature: 0.7
          mode: chat
          name: claude-3-haiku-20240307
          provider: anthropic
        prompt_template:
        - id: 644283ed-ac64-4c88-9da4-8537f1fcb8da
          role: system
          text: "\u3042\u306A\u305F\u306F\u89E3\u8AAC\u8005\u3067\u3059\u3002\u9AD8\
            \u6821\u751F\u30EC\u30D9\u30EB\u3067\n### current time \n{{#1715050485745.text#}}\n"
        - id: 78211716-b212-4304-81ef-cd5e8ca61879
          role: user
          text: "fallowing result\u306B\u3064\u3044\u3066\u3001\u89E3\u8AAC\u3057\u3066\
            \u3002\u9577\u304F\u306A\u3063\u3066\u3082\u3044\u3044\u3088\nprovide\
            \ hyperlinks which you used to explain(ex [link](http://url.example.com)).\n\
            the language should be: {{#1715050473214.language#}}\n### tavily result\n\
            {{#1715051776861.text#}}\n"
        selected: false
        title: LLM
        type: llm
        variables: []
        vision:
          configs:
            detail: high
          enabled: true
      height: 97
      id: '1715050510521'
      position:
        x: 1234.6116957432907
        y: 398.6731092838602
      positionAbsolute:
        x: 1234.6116957432907
        y: 398.6731092838602
      selected: true
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 243
    - data:
        desc: ''
        outputs:
        - value_selector:
          - '1715050510521'
          - text
          variable: text
        selected: false
        title: "\u7D42\u4E86"
        type: end
      height: 89
      id: '1715050718573'
      position:
        x: 1666.0522300754467
        y: 398.6731092838602
      positionAbsolute:
        x: 1666.0522300754467
        y: 398.6731092838602
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 243
    - data:
        desc: ''
        provider_id: tavily
        provider_name: tavily
        provider_type: builtin
        selected: false
        title: TavilySearch
        tool_configurations:
          exclude_domains: null
          include_answer: 0
          include_domains: null
          include_images: 0
          include_raw_content: 0
          max_results: 5
          search_depth: basic
        tool_label: TavilySearch
        tool_name: tavily_search
        tool_parameters:
          query:
            type: mixed
            value: '{{#1715050473214.query#}} {{#1715050485745.text#}}'
        type: tool
      height: 245
      id: '1715051776861'
      position:
        x: 977.6484707745717
        y: 39.64258750658581
      positionAbsolute:
        x: 977.6484707745717
        y: 39.64258750658581
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 243
    viewport:
      x: 193.2857745351865
      y: 121.21643267573307
      zoom: 0.5484124867538025

```
## ニュースの例
```markdown
[テストgas] 提示された結果は、2024年5月14日に開催されたGoogle I/Oカンファレンスに関連するニュースやブログ記事のようです。主な内容は以下の通りです:

1. [Techradar](https://www.techradar.com/computing/live/google-io-2024-live-blog)
   - Geminiと呼ばれる新しいGoogleのAI技術について言及されています。
   - GeminiがクロームブラウザやPixelスマートフォンなどのGoogleのメインプロダクトとどのように統合されるかが注目されています。

2. [The Verge](https://www.theverge.com/24153841/google-io-2024-ai-gemini-android-chrome-photos)
   - Androidアプリでユーザーの顔を使ってカーソルを操作できるようになるという情報が報じられています。
   - Geminiを中心としたGoogleのAI関連の発表が大きな注目を集めていることがわかります。

3. [CNET](https://www.cnet.com/news-live/google-io-2024-live-blog-gemini-ai-features-are-coming-to-many-apps/)
   - Geminiを活用したAI機能がさまざまなアプリに搭載されていくことが示唆されています。
   - 生成型AIが多くの出力に関わってくるようになることが予想されています。

4. [Google公式ブログ](https://blog.google/products/search/generative-ai-google-search-may-2024/)
   - 検索にも生成型AIが活用されるようになり、これまでにない検索体験が提供されるようです。
   - 季節に合わせたイラストの表示や、旅行に役立つ情報の提供など、検索機能の拡張が期待されています。

5. [CNBC](https://www.cnbc.com/2024/05/08/how-generative-chatgpt-like-ai-is-accelerating-humanoid-robots.h...
```

## さいごに
本記事では、Google Apps ScriptとDify APIを使ってニュースを自動取得し、LINEに投稿する方法を解説しました。プログラミングの知識を使って、情報収集や発信を自動化することで、日々の生活をより豊かにすることができます。本記事がみなさんのアイデアのヒントになれば幸いです。