DEV Community

Cover image for Automate social listening with OpenClaw and Mentionkit
Shash
Shash

Posted on

Automate social listening with OpenClaw and Mentionkit

Social listening tools are great.

They tell you that somebody mentioned your brand, your competitor, or a keyword you care about.

Unfortunately, after that, a human still has to read the thread, decide if it matters, write a reply, and post it.

That works when volume is low. It gets messy once you want a repeatable workflow.

A better setup is to split the job in two:

That gives you a technical pipeline instead of just another dashboard. Mentionkit gives you structured mention data plus endpoints for listing mentions, generating draft comments, and marking a mention handled. OpenClaw gives you an agent runtime plus browser control over tabs, clicks, typing, and navigation.

In this article, I will show a simple version of that setup:

  1. pull mentions from Mentionkit
  2. filter for real opportunities
  3. generate a draft reply automatically
  4. let an AI agent refine it
  5. post it through the user’s signed-in browser session after approval
  6. mark the mention handled so it does not get processed again

That is a good fit for teams that want more than alerts, but do not want to build a full custom agent stack from scratch.

What social listening means in this setup

For this workflow, social listening is very simple.

You track public conversations around:

  • your brand
  • your competitors
  • the problem you solve

For this example, I am using Mentionkit.

Why Mentionkit?

  • it has an API you can use right away
  • mentions come back as structured objects
  • mentions include a relevance field
  • you can generate a draft comment with one API call
  • you can mark a mention handled with one API call

The relevance part matters a lot. The mentions API supports filtering by relevance, and the allowed values are 1-5. In practice, anything with a relevance score of 3 or above is a good candidate for reply review. Mention objects also include fields like comment and commentStatus, which makes idempotent workflows much easier.

Why OpenClaw fits well here

OpenClaw is a self-hosted agent gateway with browser tooling, skills, and scheduled execution.

That matters here because the browser side is real, not theoretical.

OpenClaw’s browser stack supports deterministic tab control like list, open, focus, and close. It also supports page actions like click, type, press, navigate, and snapshot. More importantly, the built-in user browser profile can attach to your real signed-in Chrome session through Chrome MCP. The docs also say that when the attach works, tabs will list your already-open browser tabs and snapshot will operate on the selected live tab.

So yes, if the user already has Reddit, X, and LinkedIn tabs open and signed in on their local Chrome profile, OpenClaw can attach to that live browser session and operate those tabs. The main caveats are that the user profile is host-only and existing-session mode has some limits, like no batch actions and fewer network/debugging features than the isolated OpenClaw-managed profile. For simple “focus tab, type reply, submit post” workflows, it is a good fit.

The workflow

Here is the shape of the workflow:

Mentionkit -> local script -> OpenClaw agent -> approval -> user browser tab -> status update
Enter fullscreen mode Exit fullscreen mode

Step 1: Pull mentions from Mentionkit

First, fetch recent mentions for a project.

import axios from "axios";

const mentionkit = axios.create({
  baseURL: "https://api.mentionkit.com",
  headers: {
    Authorization: `Bearer ${process.env.MENTIONKIT_API_KEY}`,
  },
});

async function listMentions(projectId) {
  const response = await mentionkit.get("/api/v1/mentions", {
    params: {
      projectId,
      sort: "newest",
      relevance: "3,4,5",
    },
  });

  return response.data.items;
}
Enter fullscreen mode Exit fullscreen mode

The GET /api/v1/mentions endpoint supports projectId, sort, and a comma-separated relevance filter, so this is the easiest first pass.

Step 2: Ignore mentions we already handled

Mentionkit includes commentStatus on mention items, and the update endpoint only accepts commentStatus values of 1 or -1. A value of 1 is the obvious flag to use for “we already posted or handled this mention.” That means OpenClaw should ignore any mention where commentStatus === 1.

function isUsefulMention(mention) {
  if (mention.commentStatus === 1) {
    return false;
  }

  if (mention.relevance < 3) {
    return false;
  }

  return true;
}
Enter fullscreen mode Exit fullscreen mode

That one check makes the workflow idempotent enough for a cron job.

Step 3: Generate a draft comment

Once you have a candidate mention, ask Mentionkit to generate the comment.

async function generateComment(mentionId) {
  const response = await mentionkit.put(`/api/v1/mentions/${mentionId}/comment`);
  return response.data;
}
Enter fullscreen mode Exit fullscreen mode

PUT /api/v1/mentions/:id/comment returns the updated mention object and includes the generated comment field.

Step 4: Hand the candidates to OpenClaw

Now build the payload OpenClaw will consume:

async function getCandidates(projectId) {
  const mentions = await listMentions(projectId);
  const results = [];

  for (const mention of mentions) {
    if (!isUsefulMention(mention)) {
      continue;
    }

    const mentionWithComment = await generateComment(mention.id);

    results.push({
      id: mentionWithComment.id,
      platform: mentionWithComment.platform,
      keywordValue: mentionWithComment.keywordValue,
      authorHandle: mentionWithComment.authorHandle,
      relevance: mentionWithComment.relevance,
      text: mentionWithComment.text,
      comment: mentionWithComment.comment,
      sourceUrl: mentionWithComment.url,
    });
  }

  return results;
}
Enter fullscreen mode Exit fullscreen mode

Let OpenClaw use the signed-in tabs

This is the part that matters most.

OpenClaw should use the user browser profile, not the isolated openclaw profile, because you want the agent to reuse the tabs where the user is already logged in. The browser docs explicitly say the user profile attaches to the real signed-in Chrome session, and the CLI supports listing tabs, selecting a tab, focusing it, and then clicking or typing into the page.

A practical skill would say something like this:

---
name: mentionkit-review
description: "Review Mentionkit mentions and post approved replies with the user browser profile."
---

1. Run the local Mentionkit review script.
2. Read the returned JSON.
3. Ignore mentions where commentStatus is already 1.
4. Ignore mentions where relevance is below 3.
5. Prioritize mentions with relevance 4 or 5.
6. Rewrite the draft so it sounds natural and specific to the thread.
7. Use browser profile "user".
8. List open tabs and focus the tab that matches the mention platform:
   - reddit.com for REDDIT
   - x.com for X
   - linkedin.com for LINKEDIN
9. Open the thread URL if needed.
10. Paste the final reply and submit it only after approval.
11. After a successful post, call the Mentionkit status endpoint with commentStatus: 1.
12. Record the posting receipt locally with mentionId, platform, sourceUrl, postedUrl, and postedAt.
Enter fullscreen mode Exit fullscreen mode

That is the right split of responsibility. Mentionkit decides which mentions are promising. OpenClaw handles the browser work.

Updating Mentionkit after posting

Mentionkit’s status endpoint is useful, but it has one important limitation.

The documented POST /api/v1/mentions/:id request body only accepts commentStatus, and the docs show valid values of 1 or -1. The response only returns id, commentStatus, and commentStatusAt. So you can use this endpoint to mark a mention as handled, but based on the current docs you cannot store extra posting metadata like the Reddit comment URL or the exact tab where it was posted.

So the final pattern is to set commentStatus: 1 inside Mentionkit after a successful post.

Here is the Mentionkit update call:

async function updateMentionStatus(mentionId) {
  const response = await mentionkit.post(`/api/v1/mentions/${mentionId}`, {
    commentStatus: 1,
  });

  return response.data;
}
Enter fullscreen mode Exit fullscreen mode

Use it like this after OpenClaw posts:

await updateMentionStatus(mention.id);

await recordPostingReceipt({
  mentionId: mention.id,
  platform: mention.platform,
  sourceUrl: mention.sourceUrl,
  postedUrl: finalPostedUrl,
  postedAt: new Date().toISOString(),
});
Enter fullscreen mode Exit fullscreen mode

That gives you both layers:

  • Mentionkit knows the mention is already handled
  • your local store knows exactly where OpenClaw posted

Full filtering logic

import axios from "axios";
import fs from "fs/promises";

const mentionkit = axios.create({
  baseURL: "https://api.mentionkit.com",
  headers: {
    Authorization: `Bearer ${process.env.MENTIONKIT_API_KEY}`,
  },
});

async function listMentions(projectId) {
  const response = await mentionkit.get("/api/v1/mentions", {
    params: {
      projectId,
      sort: "newest",
      relevance: "3,4,5",
    },
  });

  return response.data.items;
}

function isUsefulMention(mention) {
  if (mention.commentStatus === 1) {
    return false;
  }

  if (mention.relevance < 3) {
    return false;
  }

  return true;
}

async function generateComment(mentionId) {
  const response = await mentionkit.put(`/api/v1/mentions/${mentionId}/comment`);
  return response.data;
}

async function updateMentionStatus(mentionId) {
  const response = await mentionkit.post(`/api/v1/mentions/${mentionId}`, {
    commentStatus: 1,
  });

  return response.data;
}

async function recordPostingReceipt(receipt) {
  const path = "./posted-mentions.json";
  let items = [];

  try {
    const raw = await fs.readFile(path, "utf8");
    items = JSON.parse(raw);
  } catch (error) {
    items = [];
  }

  items.push(receipt);
  await fs.writeFile(path, JSON.stringify(items, null, 2));
}

async function getCandidates(projectId) {
  const mentions = await listMentions(projectId);
  const results = [];

  for (const mention of mentions) {
    if (!isUsefulMention(mention)) {
      continue;
    }

    const mentionWithComment = await generateComment(mention.id);

    results.push({
      id: mentionWithComment.id,
      platform: mentionWithComment.platform,
      relevance: mentionWithComment.relevance,
      text: mentionWithComment.text,
      comment: mentionWithComment.comment,
      sourceUrl: mentionWithComment.url,
    });
  }

  return results;
}
Enter fullscreen mode Exit fullscreen mode

Final take

For this workflow, the answer is yes: Openclaw can automate the user’s already-open, already-signed-in browser tabs for Reddit, X, and LinkedIn by attaching to the real Chrome session through the user profile, listing and focusing tabs, and then performing click/type/press actions.

But the cleaner setup is to keep Mentionkit as the source of mention truth, use commentStatus: 1 as the handled flag, and store the exact posting receipt in your own local log because the current Mentionkit status endpoint does not document arbitrary extra metadata fields.

Top comments (0)