<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shash</title>
    <description>The latest articles on DEV Community by Shash (@shash7).</description>
    <link>https://dev.to/shash7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F838480%2Fb09f4fc0-d76d-46df-9a9a-552d52582429.jpeg</url>
      <title>DEV Community: Shash</title>
      <link>https://dev.to/shash7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shash7"/>
    <language>en</language>
    <item>
      <title>Use SocialListeningAPI as a LinkedIn Post API for ChatGPT Research</title>
      <dc:creator>Shash</dc:creator>
      <pubDate>Mon, 24 Aug 2026 02:06:15 +0000</pubDate>
      <link>https://dev.to/shash7/use-sociallisteningapi-as-a-linkedin-post-api-for-chatgpt-research-3dff</link>
      <guid>https://dev.to/shash7/use-sociallisteningapi-as-a-linkedin-post-api-for-chatgpt-research-3dff</guid>
      <description>&lt;p&gt;LinkedIn posts can contain detailed product questions, launch notes, hiring plans, and complaints about tools. Finding those posts by hand takes time, and copying a few links into ChatGPT does not make the process repeatable.&lt;/p&gt;

&lt;p&gt;We're going to use&lt;a href="https://sociallisteningapi.com" rel="noopener noreferrer"&gt;SocialListeningAPI&lt;/a&gt;, which provides a LinkedIn post API that searches public posts by keyword and returns normalized mentions with source URLs. ChatGPT can review those&lt;br&gt;
mentions, group the useful ones, and write a comment that links back to the posts.&lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;
&lt;h2&gt;
  
  
  What the LinkedIn post API returns
&lt;/h2&gt;

&lt;p&gt;The keyword search endpoint is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET https://api.sociallisteningapi.com/api/v1/linkedin/search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It searches public LinkedIn posts by keyword, newest first. Each successful request costs 2 credits. Failed requests do not use credits.&lt;/p&gt;

&lt;p&gt;Results use the shared social response structure. Available fields include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;platform&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;url&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content.title&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content.text&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content.media_urls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;author&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;engagement&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;published_at&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ext&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SocialListeningAPI also has a separate endpoint for public posts from one LinkedIn profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET https://api.sociallisteningapi.com/api/v1/linkedin/profile/posts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That endpoint accepts a LinkedIn profile URL and returns public profile posts newest first, with pagination when available. Use keyword search for topic research. Use profile posts when you already know which public profile you want to follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Search for a specific situation
&lt;/h2&gt;

&lt;p&gt;Broad terms such as &lt;code&gt;marketing&lt;/code&gt; or &lt;code&gt;cybersecurity&lt;/code&gt; produce too much mixed content. A good keyword describes a problem, decision, or change.&lt;/p&gt;

&lt;p&gt;For product research, I would begin with phrases like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recommend a customer support tool
alternative to competitor name
competitor name pricing
how do you track brand mentions
looking for a LinkedIn post search API
we are hiring our first sales person
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each keyword/phase represents a different research question. Keep them separate so you can remove the queries that return weak results.&lt;/p&gt;

&lt;p&gt;Avoid calling every mention a lead. A person may be researching for an article, discussing an old project, or sharing a link without looking for a product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Make the LinkedIn search request
&lt;/h2&gt;

&lt;p&gt;Create a SocialListeningAPI account, activate it, and copy your API key. Send the key in the &lt;code&gt;x-api-key&lt;/code&gt; header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--get&lt;/span&gt; &lt;span class="s1"&gt;'https://api.sociallisteningapi.com/api/v1/linkedin/search'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'query=recommend a customer support tool'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-api-key: YOUR_API_KEY'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set &lt;code&gt;raw=true&lt;/code&gt; only when you need the unchanged provider response as well as the normalized fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--get&lt;/span&gt; &lt;span class="s1"&gt;'https://api.sociallisteningapi.com/api/v1/linkedin/search'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'query=recommend a customer support tool'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'raw=true'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-api-key: YOUR_API_KEY'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the same request in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.sociallisteningapi.com/api/v1/linkedin/search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recommend a customer support tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-api-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOCIALLISTENING_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`LinkedIn post search failed with status &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the API key secure on your server. Browser code, public repositories, screenshots, and logs are poor places for a private key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Tell ChatGPT what to research
&lt;/h2&gt;

&lt;p&gt;ChatGPT needs to know what a useful mention looks like.&lt;/p&gt;

&lt;p&gt;For a product-research workfow, use a prompt like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review these public LinkedIn posts for product research.

Keep a post only when the author directly describes one of these:
- a problem they are trying to solve
- a tool recommendation request
- a named product comparison
- a pricing or access concern
- a workaround for a missing feature

For every kept post, return:
- author and published date
- exact problem or request
- product or workaround named
- direct statement from the post
- your inference, clearly labelled
- source URL

Reject job ads, event promotions, copied news, vague category mentions, and posts without enough context. Do not estimate purchase intent or lead quality. Do not draft a comment or direct message.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a post says, “We need a way to search public comments,” that is a direct need. Saying the company has a budget or plans to buy this month would be an unsupported guess at most.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Run the search from ChatGPT through MCP
&lt;/h2&gt;

&lt;p&gt;If you prefer to stay in ChatGPT, connect the&lt;br&gt;
&lt;a href="https://sociallisteningapi.com/mcp" rel="noopener noreferrer"&gt;SocialListeningAPI MCP&lt;/a&gt; via its MCP server. ChatGPT can call the LinkedIn search tool and receive current public mentions with source URLs.&lt;/p&gt;

&lt;p&gt;Use a prompt that includes the query, the source, and the output limit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use SocialListeningAPI to search public LinkedIn posts for these phrases:
- recommend a customer support tool
- alternative to CompetitorName
- CompetitorName pricing

Return at most 10 useful posts. Include the matched query, author, published date, short context, fit reason, and source URL. Put uncertain matches in a separate list.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This search will consume SocialListeningAPI credits. ChatGPT performs the grouping and summary.&lt;/p&gt;

&lt;p&gt;Know that ChatGPT does not create a recurring schedule, store old results, or send an alert by itself.&lt;/p&gt;

&lt;p&gt;You can use something external like Zapier, N8N, etc for recurring social listening. Or use ChatGPT scheduled tasks for a super quick setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this workflow has been useful for you. With this workflow, you can detect mentions for B2B brands/products easily and find potential leads.&lt;/p&gt;

&lt;p&gt;If you want a proper social listening tool instead of this, I'd recommend Mentionkit. The main advantage of using a pure API solution is the cost. SociallisteningAPI has usage-based pricing and it comes a lot cheaper than existing brand monitoring products.&lt;/p&gt;

</description>
      <category>api</category>
      <category>mcp</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Build a Reddit Search API Workflow with ChatGPT and SocialListeningAPI</title>
      <dc:creator>Shash</dc:creator>
      <pubDate>Fri, 21 Aug 2026 08:53:17 +0000</pubDate>
      <link>https://dev.to/shash7/build-a-reddit-search-api-workflow-with-chatgpt-and-sociallisteningapi-4b47</link>
      <guid>https://dev.to/shash7/build-a-reddit-search-api-workflow-with-chatgpt-and-sociallisteningapi-4b47</guid>
      <description>&lt;p&gt;Reddit is great for finding people talking about your product, complaining about your competitors, etc. It is also full of repeated jokes, old advice, and posts that match a keyword for the&lt;br&gt;
wrong context.&lt;/p&gt;

&lt;p&gt;A Reddit social listening workflow should do more than collect links. It should preserve the post or&lt;br&gt;
comment text, subreddit, date, and source URL, then give ChatGPT a strict rule for keeping or&lt;br&gt;
rejecting each result.&lt;/p&gt;

&lt;p&gt;For this workflow, we'll be using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sociallisteningapi.com" rel="noopener noreferrer"&gt;SocialListeningAPI&lt;/a&gt; It searches public Reddit posts and comments.&lt;/li&gt;
&lt;li&gt;ChatGPT. It can group the returned records and write a short brief. A human still needs to read the full
thread before treating a comment as evidence or joining the conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PS, you can also use Claude or any other LLM, it doesn't really matter.&lt;/p&gt;
&lt;h2&gt;
  
  
  What this workflow is good for
&lt;/h2&gt;

&lt;p&gt;I would use this setup for research jobs where the exact words matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finding product recommendation questions&lt;/li&gt;
&lt;li&gt;Collecting complaints about a product category&lt;/li&gt;
&lt;li&gt;Finding workarounds people already use&lt;/li&gt;
&lt;li&gt;Grouping repeated feature requests&lt;/li&gt;
&lt;li&gt;Learning how people compare two products&lt;/li&gt;
&lt;li&gt;Finding questions that deserve a clear help article&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a poor fit for counting every mention or declaring broad market sentiment. A keyword result is&lt;br&gt;
a sample of public Reddit content, and a single popular thread can distort the picture.&lt;/p&gt;
&lt;h2&gt;
  
  
  The two Reddit search endpoints
&lt;/h2&gt;

&lt;p&gt;SocialListeningAPI has separate endpoints for posts and comments.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Search&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Cost per successful request&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public posts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/api/v1/reddit/search-posts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 credit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public comments&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/api/v1/reddit/search-comments&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2 credits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both search newest first. Post results include normalized post text, subreddit, engagement, author,&lt;br&gt;
publication time, and source data. Comment results include normalized comment text, subreddit, and&lt;br&gt;
source data.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;exact&lt;/code&gt; parameter defaults to &lt;code&gt;true&lt;/code&gt; for both searches. SocialListeningAPI wraps the query in&lt;br&gt;
double quotes when exact search is enabled. Set &lt;code&gt;exact=false&lt;/code&gt; when you want the source search to&lt;br&gt;
receive the phrase unchanged.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Start with problem language
&lt;/h2&gt;

&lt;p&gt;Searching a category name such as &lt;code&gt;project management&lt;/code&gt; will return a large mix of discussions.&lt;br&gt;
Search for language that reveals a task or decision.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recommend a project management tool
alternative to competitor name
competitor name too expensive
how do you track project delays
need a tool that exports project reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep each phrase separate. You want to know which query found the result.&lt;/p&gt;

&lt;p&gt;Run the same phrase against posts and comments when the task needs both. Posts often contain the&lt;br&gt;
main question. Comments may contain product comparisons and workarounds that never appear in the&lt;br&gt;
title.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Search Reddit with the API
&lt;/h2&gt;

&lt;p&gt;Create a SocialListeningAPI account, activate it, and copy your API key. You'll get free 100 credits.&lt;br&gt;
Send the key in the &lt;code&gt;x-api-key&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;Search public posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--get&lt;/span&gt; &lt;span class="s1"&gt;'https://api.sociallisteningapi.com/api/v1/reddit/search-posts'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'query=recommend a project management tool'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'exact=true'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-api-key: YOUR_API_KEY'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search public comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--get&lt;/span&gt; &lt;span class="s1"&gt;'https://api.sociallisteningapi.com/api/v1/reddit/search-comments'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'query=recommend a project management tool'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'exact=true'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'x-api-key: YOUR_API_KEY'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successful responses return records under &lt;code&gt;data.items&lt;/code&gt;. Failed requests do not use credits.&lt;/p&gt;

&lt;p&gt;For a JavaScript workflow, keep the API key on your server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.sociallisteningapi.com/api/v1/reddit/search-posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recommend a project management tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exact&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-api-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOCIALLISTENING_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Reddit search failed with status &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Keep the fields ChatGPT needs
&lt;/h2&gt;

&lt;p&gt;Do not send only the post title to ChatGPT. That removes the context needed to make a useful call.&lt;/p&gt;

&lt;p&gt;For each record, keep:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query
result type: post or comment
subreddit
title, when available
text
author
published_at
engagement, when available
source URL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also keep the query beside the result. A comment may match several searches, but the query explains&lt;br&gt;
why it entered this run.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Ask ChatGPT to reject weak matches
&lt;/h2&gt;

&lt;p&gt;You can connect ChatGPT through the &lt;a href="https://sociallisteningapi.com/mcp" rel="noopener noreferrer"&gt;SocialListeningAPI MCP&lt;/a&gt; and&lt;br&gt;
ask it to run the Reddit searches, or pass API results into your own ChatGPT workflow. In both&lt;br&gt;
cases, use a prompt with an explicit reject path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review these public Reddit posts and comments for product research.

Keep a result only when the author describes one of these:
- a clear problem
- a current workaround
- a product recommendation request
- a comparison between named tools
- a missing capability

Reject jokes, copied news, job posts, vague mentions, and results where the keyword
has a different meaning.

For each kept result, return:
- subreddit
- post or comment
- the problem in the author's own terms
- product or workaround named
- why the result fits
- published date
- source URL

Separate direct statements from your inference. Do not draft a reply.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask for the author's own terms because polished summaries can erase useful language. If five people&lt;br&gt;
describe the same problem in five different ways, those phrases may be more valuable than a generic&lt;br&gt;
label.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 5: Read the whole thread before using the finding
&lt;/h2&gt;

&lt;p&gt;A comment can look clear when removed from its parent discussion and mean something else in the&lt;br&gt;
thread. Before adding a result to a research report, check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The post date&lt;/li&gt;
&lt;li&gt;The subreddit and its purpose&lt;/li&gt;
&lt;li&gt;The parent post or comment&lt;/li&gt;
&lt;li&gt;Whether the author is speaking from experience&lt;/li&gt;
&lt;li&gt;Whether another comment corrects the claim&lt;/li&gt;
&lt;li&gt;Whether the linked product or policy has changed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Treat public opinions as opinions. A highly upvoted comment is still not proof that every customer&lt;br&gt;
has the same problem.&lt;/p&gt;

&lt;p&gt;If you decide to reply, read the subreddit rules and disclose your product connection when it is&lt;br&gt;
relevant. Keep replies under human control. This workflow does not automate comments or direct&lt;br&gt;
messages.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 6: Store URLs before running the search again
&lt;/h2&gt;

&lt;p&gt;For a one-time research task, a ChatGPT conversation may be enough. A recurring workflow needs&lt;br&gt;
external storage.&lt;/p&gt;

&lt;p&gt;Save the result ID or source URL, query, subreddit, result type, published date, and first-seen time&lt;br&gt;
in a database, n8n Data Table, or sheet. On the next run, exclude URLs already stored.&lt;/p&gt;

&lt;p&gt;Scheduling and deduplication happen outside SocialListeningAPI. Use cron, n8n, Make, Zapier, or your&lt;br&gt;
own worker when you need repeated searches.&lt;/p&gt;

&lt;p&gt;Start weekly. Daily searches can produce nearly identical result sets for narrow phrases, which&lt;br&gt;
uses credits and creates more review work without adding much information.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 7: Add a ChatGPT scheduled reminder
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://learn.chatgpt.com/docs/automations" rel="noopener noreferrer"&gt;ChatGPT scheduled tasks&lt;/a&gt; can run in the background and return to the same chat on a schedule. I would&lt;br&gt;
use this as a reminder before building a fully automatic workflow. It keeps the first few searches under human review and makes bad queries easier to spot.&lt;/p&gt;

&lt;p&gt;Open the ChatGPT conversation that contains&lt;br&gt;
your query list and ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a scheduled task in this chat.

Every Monday at 9:00 AM local time, run the weekly
Reddit product research check.

Include this checklist in the reminder:
1. Search Reddit posts and comments through SocialListeningAPI for:
   - recommend a project management tool
   - alternative to CompetitorName
   - CompetitorName too expensive
2. Check the saved-source-URL sheet before reviewing results.
3. Exclude links already seen.
4. Group new results into recommendation request, product problem,
   competitor comparison, feature request, unrelated, or unclear.
5. Keep the source URL beside every result.
6. Do not draft or publish Reddit replies.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenAI's &lt;a href="https://learn.chatgpt.com/docs/automations" rel="noopener noreferrer"&gt;scheduled tasks guide&lt;/a&gt; says you can create and&lt;br&gt;
manage tasks from ChatGPT on the web or desktop app when the feature is enabled. Open &lt;code&gt;Scheduled&lt;/code&gt; to&lt;br&gt;
check recent runs, pause the reminder, or change its timing. Test the prompt once in a normal chat&lt;br&gt;
before scheduling it, then review the first few reminders.&lt;/p&gt;

&lt;p&gt;The scheduled task handles the reminder. SocialListeningAPI performs each search when requested,&lt;br&gt;
and your sheet or database stores old URLs. ChatGPT scheduled tasks can use connected tools available&lt;br&gt;
to the chat, but I would keep the first version manual until the queries and rejection rules produce&lt;br&gt;
a useful brief.&lt;/p&gt;
&lt;h2&gt;
  
  
  Output format
&lt;/h2&gt;

&lt;p&gt;Keep the final report small and sourced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repeated problems
- Problem, number of distinct sources, representative URLs

Recommendation questions
- Requested outcome, tools already tried, source URL

Competitor comparisons
- Products compared, stated decision factor, source URL

Unclear or conflicting claims
- What is uncertain, source URLs

Queries that produced no useful results
- Query and reason it should be changed or removed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last section prevents a bad query from staying in the schedule forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Use the Reddit search API to collect current public posts and comments. Use ChatGPT to sort the&lt;br&gt;
results. Keep the original source URL beside every finding, and read the thread before responding.&lt;/p&gt;

&lt;p&gt;I hope this was helpful. If you're looking for a full social listening experience, try &lt;a href="https://mentionkit.com" rel="noopener noreferrer"&gt;Mentionkit&lt;/a&gt;. SociallisteningAPI powers Mentionkit under the hood.&lt;/p&gt;

</description>
      <category>reddit</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Automate B2B Marketing With Hermes Agent, LinkedIn, and X</title>
      <dc:creator>Shash</dc:creator>
      <pubDate>Tue, 11 Aug 2026 05:01:41 +0000</pubDate>
      <link>https://dev.to/shash7/automate-b2b-marketing-with-hermes-agent-linkedin-and-x-4ech</link>
      <guid>https://dev.to/shash7/automate-b2b-marketing-with-hermes-agent-linkedin-and-x-4ech</guid>
      <description>&lt;p&gt;Checking LinkedIn and X for posts where you can plug your product can get tiring and repetitive.&lt;/p&gt;

&lt;p&gt;Instead of doing this manually, Hermes Agent can run the same&lt;br&gt;
searches each weekday, skip posts it has already found, and prepare one short brief for review.&lt;/p&gt;

&lt;p&gt;The SociallisteningAPI searches current public LinkedIn and X posts&lt;br&gt;
and returns normalized records with source URLs. Hermes handles the schedule, deduplication,&lt;br&gt;
analysis, and delivery outside the API. You still decide whether to reply or send a message.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Connect Hermes Agent to the SocialListeningAPI MCP
&lt;/h2&gt;

&lt;p&gt;Install and configure Hermes using its &lt;a href="https://hermes-agent.nousresearch.com/docs/" rel="noopener noreferrer"&gt;official setup&lt;br&gt;
guide&lt;/a&gt;. Then create a SocialListeningAPI account and&lt;br&gt;
claim the 100 free credits.&lt;/p&gt;

&lt;p&gt;Add the &lt;a href="https://dev.to/mcp"&gt;SocialListeningAPI MCP&lt;/a&gt; as a remote OAuth server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes mcp add sociallisteningapi &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.sociallisteningapi.com/mcp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--auth&lt;/span&gt; oauth

hermes mcp &lt;span class="nb"&gt;test &lt;/span&gt;sociallisteningapi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Complete the browser sign-in and approve access to your workspace credits. The &lt;a href="https://hermes-agent.nousresearch.com/docs/reference/cli-commands#hermes-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;hermes mcp&lt;/code&gt;&lt;br&gt;
documentation&lt;/a&gt; covers&lt;br&gt;
connection and login commands.&lt;/p&gt;

&lt;p&gt;Run this in Hermes to confirm the connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List the SocialListeningAPI tools available to you. Do not run a search.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see &lt;code&gt;search_social_posts&lt;/code&gt;. If the connection works but the tool is missing, start a new&lt;br&gt;
Hermes session or reload the MCP tools.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Choose searches that show a real problem
&lt;/h2&gt;

&lt;p&gt;Broad searches such as &lt;code&gt;marketing software&lt;/code&gt; return too much noise. Begin with four to eight phrases&lt;br&gt;
that someone may use when asking for help, comparing tools, or describing a problem.&lt;/p&gt;

&lt;p&gt;For a social listening product, useful examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;recommend a social listening tool&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;how to track brand mentions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;missing LinkedIn mentions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LinkedIn post search API&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alternative to social monitoring software&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;social listening tool too expensive&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep each phrase at least four characters long and do not include quotation marks. Add your ideal&lt;br&gt;
customer, excluded industries, supported locations, and minimum fit rules to the prompt.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Test one B2B opportunity brief
&lt;/h2&gt;

&lt;p&gt;Run the workflow by hand before scheduling it. Open Hermes and use this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prepare a B2B opportunity brief from public LinkedIn and X posts.

Search both platforms for every phrase below:
- recommend a social listening tool
- how to track brand mentions
- LinkedIn post search API
- alternative to social monitoring software

Keep only posts where the author asks for a recommendation, describes the problem, compares tools,
or wants to replace a product. Exclude generic news, reposts, job posts, and promotional content.

For each useful post, return:
- platform and author
- published date
- source URL
- exact problem or request
- why it may fit a social listening API
- one helpful next action

Deduplicate by source URL. Do not contact anyone or publish a reply.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Four phrases across LinkedIn and X cost up to 12 credits per run. Each successful LinkedIn search&lt;br&gt;
costs 2 credits and each successful X search costs 1. Failed requests use no credits.&lt;/p&gt;

&lt;p&gt;Open every source before keeping it. Remove phrases that mostly find unrelated posts. A useful match&lt;br&gt;
should contain a clear problem, fit the product, and still be recent enough for a reply to help.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Save seen URLs and schedule the brief
&lt;/h2&gt;

&lt;p&gt;Hermes cron jobs run in fresh sessions, so give the job a fixed working directory. This lets it keep&lt;br&gt;
a small file of URLs already included in earlier briefs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/hermes-workflows/b2b-opportunity-brief"&lt;/span&gt;

hermes cron create &lt;span class="s2"&gt;"0 9 * * 1-5"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"Search LinkedIn and X through the SocialListeningAPI MCP for: recommend a social listening tool; how to track brand mentions; LinkedIn post search API; alternative to social monitoring software. Read seen-urls.txt if it exists and exclude stored URLs. Append each new source URL after preparing the brief. Return platform, author, published date, source URL, exact problem, fit reason, and one helpful next action. Never contact anyone or publish a reply. If there are no new useful posts, respond with only [SILENT]."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--workdir&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/hermes-workflows/b2b-opportunity-brief"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"B2B opportunity brief"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--deliver&lt;/span&gt; &lt;span class="nb"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cron expression runs at 9:00 a.m. from Monday to Friday. Four phrases use up to 60 credits over&lt;br&gt;
five runs. Reduce the phrases or frequency when that is more than you need.&lt;/p&gt;

&lt;p&gt;Hermes needs its gateway scheduler running. Install it as a service, check the job, then trigger one&lt;br&gt;
test run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes gateway &lt;span class="nb"&gt;install
&lt;/span&gt;hermes cron status
hermes cron run &lt;span class="s2"&gt;"B2B opportunity brief"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hermes saves local cron output under &lt;code&gt;~/.hermes/cron/output/&lt;/code&gt;. You can change &lt;code&gt;--deliver local&lt;/code&gt; to a&lt;br&gt;
configured Telegram, Slack, email, or other supported destination. The &lt;a href="https://hermes-agent.nousresearch.com/docs/user-guide/features/cron" rel="noopener noreferrer"&gt;Hermes cron&lt;br&gt;
documentation&lt;/a&gt; explains working&lt;br&gt;
directories, delivery targets, and job history.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SocialListeningAPI and Hermes each do
&lt;/h2&gt;

&lt;p&gt;SocialListeningAPI searches public posts and returns available post data with source URLs. It does&lt;br&gt;
not provide the schedule, URL history, ranking, brief, CRM update, or outreach.&lt;/p&gt;

&lt;p&gt;Hermes performs those external steps, but its summary can be wrong. Read the original post before&lt;br&gt;
acting. Keep all outreach human-approved and disclose your connection when mentioning your product.&lt;/p&gt;

&lt;p&gt;This workflow suits founders and small B2B teams that want a short, current research queue. Use a&lt;br&gt;
dedicated sales platform when you need private contact data, native CRM enrichment, or automated&lt;br&gt;
outreach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this guide was helpful. We run this setup for our SaaS products and its been super helpful.&lt;br&gt;
We're exploring on automation social media posting and other bits now.&lt;/p&gt;

</description>
      <category>hermes</category>
      <category>webdev</category>
      <category>automation</category>
    </item>
    <item>
      <title>Automate social listening with OpenClaw and Mentionkit</title>
      <dc:creator>Shash</dc:creator>
      <pubDate>Thu, 09 Apr 2026 06:37:10 +0000</pubDate>
      <link>https://dev.to/shash7/automate-social-listening-with-openclaw-and-mentionkit-34ci</link>
      <guid>https://dev.to/shash7/automate-social-listening-with-openclaw-and-mentionkit-34ci</guid>
      <description>&lt;p&gt;Social listening tools are great.&lt;/p&gt;

&lt;p&gt;They tell you that somebody mentioned your brand, your competitor, or a keyword you care about.&lt;/p&gt;

&lt;p&gt;Unfortunately, after that, a human still has to read the thread, decide if it matters, write a reply, and post it.&lt;/p&gt;

&lt;p&gt;That works when volume is low. It gets messy once you want a repeatable workflow.&lt;/p&gt;

&lt;p&gt;A better setup is to split the job in two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;a href="https://mentionkit.com/docs/introduction" rel="noopener noreferrer"&gt;Mentionkit&lt;/a&gt; to collect and organize mentions&lt;/li&gt;
&lt;li&gt;use &lt;a href="https://docs.openclaw.ai/" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt; to run the agent workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;In this article, I will show a simple version of that setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;pull mentions from Mentionkit&lt;/li&gt;
&lt;li&gt;filter for real opportunities&lt;/li&gt;
&lt;li&gt;generate a draft reply automatically&lt;/li&gt;
&lt;li&gt;let an AI agent refine it&lt;/li&gt;
&lt;li&gt;post it through the user’s signed-in browser session after approval&lt;/li&gt;
&lt;li&gt;mark the mention handled so it does not get processed again&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What social listening means in this setup
&lt;/h2&gt;

&lt;p&gt;For this workflow, social listening is very simple.&lt;/p&gt;

&lt;p&gt;You track public conversations around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your brand&lt;/li&gt;
&lt;li&gt;your competitors&lt;/li&gt;
&lt;li&gt;the problem you solve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this example, I am using &lt;a href="https://mentionkit.com/docs/introduction" rel="noopener noreferrer"&gt;Mentionkit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Why Mentionkit?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it has an API you can use right away&lt;/li&gt;
&lt;li&gt;mentions come back as structured objects&lt;/li&gt;
&lt;li&gt;mentions include a &lt;code&gt;relevance&lt;/code&gt; field&lt;/li&gt;
&lt;li&gt;you can generate a draft comment with one API call&lt;/li&gt;
&lt;li&gt;you can mark a mention handled with one API call&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  Why OpenClaw fits well here
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.openclaw.ai/" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt; is a self-hosted agent gateway with browser tooling, skills, and scheduled execution.&lt;/p&gt;

&lt;p&gt;That matters here because the browser side is real, not theoretical.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;user&lt;/code&gt; browser profile can attach to your &lt;strong&gt;real signed-in Chrome session&lt;/strong&gt; through Chrome MCP. The docs also say that when the attach works, &lt;code&gt;tabs&lt;/code&gt; will list your already-open browser tabs and &lt;code&gt;snapshot&lt;/code&gt; will operate on the selected live tab.&lt;/p&gt;

&lt;p&gt;So yes, if the user already has &lt;strong&gt;Reddit&lt;/strong&gt;, &lt;strong&gt;X&lt;/strong&gt;, and &lt;strong&gt;LinkedIn&lt;/strong&gt; 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 &lt;code&gt;user&lt;/code&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow
&lt;/h2&gt;

&lt;p&gt;Here is the shape of the workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mentionkit -&amp;gt; local script -&amp;gt; OpenClaw agent -&amp;gt; approval -&amp;gt; user browser tab -&amp;gt; status update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Pull mentions from Mentionkit
&lt;/h3&gt;

&lt;p&gt;First, fetch recent mentions for a project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.mentionkit.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MENTIONKIT_API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;listMentions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/mentions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3,4,5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  Step 2: Ignore mentions we already handled
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isUsefulMention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commentStatus&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relevance&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one check makes the workflow idempotent enough for a cron job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Generate a draft comment
&lt;/h3&gt;

&lt;p&gt;Once you have a candidate mention, ask Mentionkit to generate the comment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/v1/mentions/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/comment`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PUT /api/v1/mentions/:id/comment&lt;/code&gt; returns the updated mention object and includes the generated &lt;code&gt;comment&lt;/code&gt; field. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Hand the candidates to OpenClaw
&lt;/h3&gt;

&lt;p&gt;Now build the payload OpenClaw will consume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCandidates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mentions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;listMentions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mention&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;mentions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isUsefulMention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;keywordValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keywordValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;authorHandle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sourceUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let OpenClaw use the signed-in tabs
&lt;/h2&gt;

&lt;p&gt;This is the part that matters most.&lt;/p&gt;

&lt;p&gt;OpenClaw should use the &lt;code&gt;user&lt;/code&gt; browser profile, not the isolated &lt;code&gt;openclaw&lt;/code&gt; profile, because you want the agent to reuse the tabs where the user is already logged in. The browser docs explicitly say the &lt;code&gt;user&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;A practical skill would say something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mentionkit-review&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Review&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Mentionkit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;mentions&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;post&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;approved&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;replies&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;browser&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;profile."&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;That is the right split of responsibility. Mentionkit decides which mentions are promising. OpenClaw handles the browser work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating Mentionkit after posting
&lt;/h2&gt;

&lt;p&gt;Mentionkit’s status endpoint is useful, but it has one important limitation.&lt;/p&gt;

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

&lt;p&gt;So the final pattern is to set &lt;code&gt;commentStatus: 1&lt;/code&gt; inside Mentionkit after a successful post.&lt;/p&gt;

&lt;p&gt;Here is the Mentionkit update call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateMentionStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/v1/mentions/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;commentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it like this after OpenClaw posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateMentionStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;recordPostingReceipt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sourceUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sourceUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;postedUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;finalPostedUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;postedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you both layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mentionkit knows the mention is already handled&lt;/li&gt;
&lt;li&gt;your local store knows exactly where OpenClaw posted&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Full filtering logic
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.mentionkit.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MENTIONKIT_API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;listMentions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/v1/mentions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3,4,5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isUsefulMention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commentStatus&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relevance&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/v1/mentions/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/comment`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateMentionStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mentionkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/v1/mentions/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;mentionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;commentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;recordPostingReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./posted-mentions.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCandidates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mentions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;listMentions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mention&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;mentions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isUsefulMention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sourceUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mentionWithComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final take
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;user&lt;/code&gt; profile, listing and focusing tabs, and then performing click/type/press actions.&lt;/p&gt;

&lt;p&gt;But the cleaner setup is to keep Mentionkit as the source of mention truth, use &lt;code&gt;commentStatus: 1&lt;/code&gt; 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.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>automation</category>
      <category>marketing</category>
      <category>openclaw</category>
    </item>
    <item>
      <title>Receive event notifications from your nodejs backend</title>
      <dc:creator>Shash</dc:creator>
      <pubDate>Tue, 11 Mar 2025 07:24:50 +0000</pubDate>
      <link>https://dev.to/shash7/receive-event-notifications-from-your-nodejs-backend-5ml</link>
      <guid>https://dev.to/shash7/receive-event-notifications-from-your-nodejs-backend-5ml</guid>
      <description>&lt;p&gt;While building products, there are many times where you need to get notified of a json payload, env vars in production, webhook data, etc.&lt;/p&gt;

&lt;p&gt;Unfortunately, most notification tools are designed for simple user-to-user tasks.&lt;/p&gt;

&lt;p&gt;In comes &lt;a href="https://operational.co" rel="noopener noreferrer"&gt;Operational&lt;/a&gt;, a Event tracker tool. With this tool, pass json, structured json, image urls and more in your events and get notified in the webapp or on your mobile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh11b5x5e7pnkxt4ddvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frh11b5x5e7pnkxt4ddvu.png" alt="Image description" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending your first event
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Signup to Operational.co and get your API token&lt;/li&gt;
&lt;li&gt;Install the Operational SDK
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Operational from "@operational.co/sdk"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then paste this code in your project. Replace the TOKEN with your API key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ops = new Operational("TOKEN");

await ops.events.ingest({
  name : "User trial ended",
  avatar : "🤔"
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking it further
&lt;/h2&gt;

&lt;p&gt;Now let's try sending a large javascript object to operational. This could be useful for getting notified of Stripe webhooks, 3rd party API webhooks, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi63mvfvyra9h9qaqti93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi63mvfvyra9h9qaqti93.png" alt="Image description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const webhookData = {
}
await ops.events.ingest({
  name : "User signed up",
  avatar : "🤔",
  type : "json",
  content : {
    user_name : "Shash",
    email : "shash@operational",
    id : 13760
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Contextual events
&lt;/h2&gt;

&lt;p&gt;Sometimes, it is helpful to chain events together.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firwdnu5gkrexmnm01we0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firwdnu5gkrexmnm01we0.png" alt="Image description" width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is super helpful for understanding complex workflows, cronjobs and other scenarios. This is what Operational calls contextual events.&lt;/p&gt;

&lt;p&gt;Here’s how you can setup contextual events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
 * Set a unique Id to chain events together.
 * We will use this id for related events later
 */
const contextId = "user-12312-signup";

// First event
await ops.events.ingest({
  name : "User signup",
  avatar : "🤔",
  contextStart : true,
  contextId : contextId,
  actions : [
    {
      key : "Ban",
      url: "https://xyz.com/webhook/ban",
    }
  ]
});

// second event some time later
await ops.events.ingest({
  name : "User activated",
  avatar : "😁",
  contextId : contextId,
});

// third event
await ops.events.ingest({
  name : "User created their project",
  avatar : "👍",
  contextId : contextId,
  content : "Project Operational created for user Shash"
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As long as the contextId is same, all these events will show up in the ‘chain’.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this guide has been helpful for you. Let me know in the comments how you're using Operational to track events in your own backend!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
