Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tools/google_search/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=debug-plugin.dify.dev
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=********-****-****-****-************
56 changes: 56 additions & 0 deletions tools/google_search/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Google Search

## Overview

The **Google Search tool** integrates with the official **Google Custom Search JSON API**, enabling real-time access to search results such as web pages, images, and news. It provides structured data that can be directly used in applications.

---

## Configuration

### 1. Enable Google Custom Search API

1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
2. Create a project (or select an existing one).
3. Enable the **Custom Search JSON API** service.
4. Generate an **API Key** under **APIs & Services > Credentials**.

### 2. Create a Programmable Search Engine

1. Open [Programmable Search Engine](https://programmablesearchengine.google.com/).
2. Create a new search engine:
- Choose to search the entire web or specify certain sites.
3. Copy the **Search Engine ID (CX)**.

### 3. Install Google Search Tool in Dify

1. In the **Dify Console**, go to **Plugin Marketplace**.
2. Search for **Google Search** and install it.

### 4. Configure in Dify

In **Dify Console > Tools > Google Search > Authorize**, enter:

- **API Key**: The key from Google Cloud Console.
- **Search Engine ID (CX)**: The ID from Programmable Search Engine.

---

## Usage

The Google Search tool can be used in the following application types:

### Chatflow / Workflow Applications
Add a **Google Search node** to fetch real-time search results during flow execution.

### Agent Applications
Enable the **Google Search tool** in Agent applications.
When users request online searches (e.g., *“Find the latest updates on AI research”*), the tool will automatically call the Google Search API to return results.

---

## Notes

- The **free quota** for Google Custom Search API is limited (typically **100 queries/day**).
- To increase quota, upgrade your plan in **Google Cloud Console**.
- Both **API Key** and **Search Engine ID (CX)** are required; missing either will cause request failures.
6 changes: 6 additions & 0 deletions tools/google_search/_assets/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions tools/google_search/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from dify_plugin import Plugin, DifyPluginEnv

plugin = Plugin(DifyPluginEnv())

if __name__ == "__main__":
plugin.run()
33 changes: 33 additions & 0 deletions tools/google_search/manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
version: 0.0.1
type: plugin
author: "langgenius"
name: "google_search"
label:
en_US: "Google"
created_at: "2025-08-30T08:03:44.365065261Z"
icon: icon.svg
description:
en_US: A tool for performing a Google search and extracting snippets and webpages.Input should be a search query.
zh_Hans: 一个用于执行 Google 搜索并提取片段和网页的工具。输入应该是一个搜索查询。
tags:
- "search"
resource:
memory: 1048576
permission:
tool:
enabled: true
model:
enabled: true
llm: true
plugins:
tools:
- "provider/google_search.yaml"
meta:
version: 0.0.1
arch:
- "amd64"
- "arm64"
runner:
language: "python"
version: "3.12"
entrypoint: "main"
17 changes: 17 additions & 0 deletions tools/google_search/provider/google_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Any

from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError

from tools.google_search import GoogleSearchTool


class GoogleProvider(ToolProvider):
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
try:
for _ in GoogleSearchTool.from_credentials(credentials).invoke(
tool_parameters={"q": "test"},
):
pass
except Exception as e:
raise ToolProviderCredentialValidationError(str(e)) from e
52 changes: 52 additions & 0 deletions tools/google_search/provider/google_search.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
identity:
author: Dify
name: google_search
label:
en_US: GoogleSearch
zh_Hans: GoogleSearch
pt_BR: GoogleSearch
description:
en_US: GoogleSearch
zh_Hans: GoogleSearch
pt_BR: GoogleSearch
icon: icon.svg
tags:
- search
credentials_for_provider:
key:
type: secret-input
required: true
label:
en_US: Google Search key
zh_Hans: Google Search key
pt_BR: Google Search key
placeholder:
en_US: Please input your Google Search key
zh_Hans: 请输入你的 Google Search key
pt_BR: Please input your Google Search key
help:
en_US: Get your Google Search key from GoogleSearch
zh_Hans: 从 GoogleSearch 获取您的 Google Search key
pt_BR: Get your Google Search key from GoogleSearch
url: https://programmablesearchengine.google.com/controlpanel/all
cx:
type: secret-input
required: true
label:
en_US: Google Search cx
zh_Hans: cx(搜索引擎 ID)
pt_BR: Google Search cx
placeholder:
en_US: Please input your Google Search cx
zh_Hans: 请输入你的 Google Search cx
pt_BR: Please input your Google Search cx
help:
en_US: Get your Google Search cx from GoogleSearch
zh_Hans: 从 GoogleSearch 获取您的 Google Search cx
pt_BR: Get your Google Search cx from GoogleSearch
url: https://programmablesearchengine.google.com/controlpanel/all
tools:
- tools/google_search.yaml
extra:
python:
source: provider/google_search.py
1 change: 1 addition & 0 deletions tools/google_search/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dify_plugin==0.4.3
66 changes: 66 additions & 0 deletions tools/google_search/tools/google_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import logging
from collections.abc import Generator
from typing import Any

import requests
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage

CUSTOM_SEARCH_URL = "https://www.googleapis.com/customsearch/v1"

PARAMETER_KEYS = [
"q",
"c2coff",
"cr",
"cx",
"dateRestrict",
"exactTerms",
"excludeTerms",
"fileType",
"filter",
"gl",
"lowRange",
"highRange",
"hl",
"hq",
"imgColorType",
"imgDominantColor",
"imgSize",
"imgType",
"linkSite",
"lr",
"num",
"start",
"orTerms",
"rights",
"safe",
"searchType",
"siteSearch",
"siteSearchFilter",
"sort",
]


class GoogleSearchTool(Tool):

def _invoke(
self, tool_parameters: dict[str, Any]
) -> Generator[ToolInvokeMessage, None, None]:
params = {
"key": self.runtime.credentials.get("key"),
"cx": self.runtime.credentials.get("cx"),
}
for parameter_key in PARAMETER_KEYS:
if parameter_key in tool_parameters and tool_parameters[parameter_key] != "":
params.update({parameter_key: tool_parameters[parameter_key]})
try:
response = requests.get(CUSTOM_SEARCH_URL, params=params)
response.raise_for_status()
response_json = response.json()

results = response_json.get("items", [])
yield self.create_json_message(results)

except Exception as e:
logging.error("Failed google search %s, %s", tool_parameters, e, exc_info=True)
yield self.create_text_message(f"Failed to google search, error: {type(e).__name__}")
Loading