DEV Community

shamnad-sherief
shamnad-sherief

Posted on

Automate Like a Pro: Flutter Meets n8n for Real-Time Hacker News Search + Auto-Posting

In this post, I’ll walk you through how I connected a Flutter mobile app with n8n, a powerful low-code automation tool, to:

  • Accept a search query from Flutter,

  • Trigger a workflow via Webhook,

  • Fetch results from the Hacker News Algolia API,

  • Return the results back to the app in real-time,

Let’s break it down step by step.

🛠 Step 1: Set Up n8n with Docker

You can get up and running with n8n in seconds using Docker. Here’s the docker-compose.yml I used:

version: '3.8'

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    container_name: n8n
    ports:
      - "5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n
    restart: unless-stopped
    environment:
      - N8N_SECURE_COOKIE=false  # disable secure cookie flag for local development

volumes:
  n8n_data:
Enter fullscreen mode Exit fullscreen mode

Run it:

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

n8n will be available at http://localhost:5678

🧠 Step 2: Create the n8n Workflow

Here’s what the workflow does:

  1. Receives a POST request from Flutter

  2. Calls the Hacker News API via HTTP Request

  3. Formats the top 5 results using a Function node

  4. Returns them to the mobile app

Workflow Diagram

Hacker News API Used:

GET https://hn.algolia.com/api/v1/search?query=<keyword>
Enter fullscreen mode Exit fullscreen mode

Function Code in Format Articles Node:

const results = $json.hits.slice(0, 5).map(hit => ({
  title: hit.title || hit.story_title,
  url: hit.url || hit.story_url
}));

return [{ json: { articles: results } }];
Enter fullscreen mode Exit fullscreen mode

📱 Step 3: Flutter Integration

Here’s the core Flutter code that sends the query and displays the result.

Search Function

Future<void> searchHackerNews(String keyword) async {
  final response = await http.post(
    Uri.parse('http://localhost:5678/webhook/hn-search?query=$keyword'),
    headers: {'Content-Type': 'application/json'},
  );

  final data = jsonDecode(response.body);
  for (var article in data['articles']) {
    print('${article['title']}${article['url']}');
  }
}
Enter fullscreen mode Exit fullscreen mode

UI Snippet with ListView

ListView.builder(
  itemCount: articles.length,
  itemBuilder: (context, index) {
    final article = articles[index];
    return ListTile(
      title: Text(article['title']),
      subtitle: Text(article['url']),
      onTap: () => launch(article['url']),
    );
  },
)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)