<?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: Naimur Rahman Nahid</title>
    <description>The latest articles on DEV Community by Naimur Rahman Nahid (@naimurrahmannahid).</description>
    <link>https://dev.to/naimurrahmannahid</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3606482%2Ff18fe78f-da32-4685-a959-7dace024c305.png</url>
      <title>DEV Community: Naimur Rahman Nahid</title>
      <link>https://dev.to/naimurrahmannahid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/naimurrahmannahid"/>
    <language>en</language>
    <item>
      <title>Building a Real-Time Earthquake Alert System Using BOT, API &amp; Database</title>
      <dc:creator>Naimur Rahman Nahid</dc:creator>
      <pubDate>Sun, 23 Nov 2025 13:13:08 +0000</pubDate>
      <link>https://dev.to/naimurrahmannahid/building-a-real-time-earthquake-alert-system-using-bot-api-database-1376</link>
      <guid>https://dev.to/naimurrahmannahid/building-a-real-time-earthquake-alert-system-using-bot-api-database-1376</guid>
      <description>&lt;h2&gt;
  
  
  Naimur Rahman Nahid Android Earthquake Apps Idea
&lt;/h2&gt;

&lt;p&gt;The global earthquake monitoring ecosystem provides public APIs for developers to consume real-time seismic activity data. Services like &lt;strong&gt;USGS&lt;/strong&gt;, &lt;strong&gt;IRIS&lt;/strong&gt;, and &lt;strong&gt;EMSC&lt;/strong&gt; offer free feeds, but they also enforce &lt;strong&gt;rate limits&lt;/strong&gt;. If your application has thousands of active users, directly calling these external APIs from each device is not scalable.&lt;/p&gt;

&lt;p&gt;Instead, a more reliable strategy is to create a &lt;strong&gt;background BOT + local database + server API&lt;/strong&gt; architecture.&lt;br&gt;&lt;br&gt;
Your server fetches earthquake data periodically, stores it locally, and your mobile/web users read everything from &lt;em&gt;your&lt;/em&gt; backend — not from external APIs.&lt;/p&gt;

&lt;p&gt;This guide walks you through building a real-time Earthquake Alert System using external feeds, a BOT worker, and a fast backend.&lt;/p&gt;


&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, you should be familiar with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic backend development (Node, PHP, Python)&lt;/li&gt;
&lt;li&gt;REST APIs &amp;amp; JSON parsing&lt;/li&gt;
&lt;li&gt;SQL databases (PostgreSQL/MySQL)&lt;/li&gt;
&lt;li&gt;Basic mobile or web app development concepts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your development environment should include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js v16 or higher
&lt;/li&gt;
&lt;li&gt;PostgreSQL/MySQL database
&lt;/li&gt;
&lt;li&gt;A local or cloud server
&lt;/li&gt;
&lt;li&gt;API testing tools (Postman/Insomnia)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Step 1: Choose an Earthquake Data Source
&lt;/h2&gt;

&lt;p&gt;Reliable free sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;USGS: &lt;a href="https://earthquake.usgs.gov" rel="noopener noreferrer"&gt;Earthquake usgs gov&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IRIS: &lt;a href="https://service.iris.edu/" rel="noopener noreferrer"&gt;service iris edu&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;EMSC: &lt;a href="https://www.emsc-csem.org" rel="noopener noreferrer"&gt;emsc-csem org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommended Feed (USGS GeoJSON):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geo.json" rel="noopener noreferrer"&gt;https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geo.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Magnitude
&lt;/li&gt;
&lt;li&gt;Location (place)
&lt;/li&gt;
&lt;li&gt;Depth
&lt;/li&gt;
&lt;li&gt;Time
&lt;/li&gt;
&lt;li&gt;Coordinates
&lt;/li&gt;
&lt;li&gt;Event ID
&lt;/li&gt;
&lt;li&gt;Tsunami flag
&lt;/li&gt;
&lt;li&gt;Metadata
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Step 2: Set Up Your Project Structure
&lt;/h2&gt;

&lt;p&gt;Example folder layout:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;earthquake-alert/&lt;br&gt;
├─ src/&lt;br&gt;
│ ├─ bot/&lt;br&gt;
│ │ └─ fetch.js&lt;br&gt;
│ ├─ api/&lt;br&gt;
│ │ └─ earthquakes.js&lt;br&gt;
│ └─ server.js&lt;br&gt;
├─ package.json&lt;br&gt;
├─ .env&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 3: Create the Earthquake Database Table
&lt;/h2&gt;

&lt;p&gt;Using PostgreSQL:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE TABLE earthquakes (&lt;br&gt;
id SERIAL PRIMARY KEY,&lt;br&gt;
external_id VARCHAR(100) UNIQUE,&lt;br&gt;
magnitude NUMERIC(4,2),&lt;br&gt;
depth NUMERIC(6,2),&lt;br&gt;
place TEXT,&lt;br&gt;
time_utc TIMESTAMP,&lt;br&gt;
latitude NUMERIC(9,6),&lt;br&gt;
longitude NUMERIC(9,6),&lt;br&gt;
url TEXT,&lt;br&gt;
source VARCHAR(20),&lt;br&gt;
created_at TIMESTAMP DEFAULT NOW()&lt;br&gt;
);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Indexes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE INDEX idx_quake_time ON earthquakes(time_utc DESC);&lt;br&gt;
CREATE INDEX idx_quake_mag ON earthquakes(magnitude DESC);&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 4: Build the BOT to Fetch Earthquake Data
&lt;/h2&gt;

&lt;p&gt;Create file: &lt;code&gt;src/bot/fetch.js&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fetch&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;node-fetch&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pool&lt;/span&gt; &lt;span class="p"&gt;}&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;pg&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;pool&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;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;connectionString&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;DATABASE_URL&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;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
 &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&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;fetchEarthquakes&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;res&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;API_URL&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;json&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;res&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;client&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;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BEGIN&lt;/span&gt;&lt;span class="dl"&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;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;features&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;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;properties&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;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;geometry&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s2"&gt;`INSERT INTO earthquakes 
         (external_id, magnitude, depth, place, time_utc, latitude, longitude, url, source)
         VALUES ($1, $2, $3, $4, to_timestamp($5/1000), $6, $7, $8, 'USGS')
         ON CONFLICT (external_id) DO NOTHING`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="nx"&gt;item&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;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coordinates&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="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coordinates&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="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coordinates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="nx"&gt;p&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;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;COMMIT&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="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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ROLLBACK&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="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;release&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="nx"&gt;Run&lt;/span&gt; &lt;span class="nx"&gt;BOT&lt;/span&gt; &lt;span class="nx"&gt;every&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;setInterval(fetchEarthquakes, 30000);&lt;br&gt;
fetchEarthquakes();&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 5: Create a Backend API for Your App

Inside src/api/earthquakes.js:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;app.get("/api/earthquakes/recent", async (req, res) =&amp;gt; {&lt;br&gt;
  const minutes = req.query.minutes || 60;&lt;/p&gt;

&lt;p&gt;const result = await pool.query(&lt;br&gt;
    &lt;code&gt;SELECT * FROM earthquakes&lt;br&gt;
     WHERE time_utc &amp;gt;= NOW() - ($1 || ' minutes')::interval&lt;br&gt;
     ORDER BY time_utc DESC&lt;/code&gt;,&lt;br&gt;
    [minutes]&lt;br&gt;
  );&lt;/p&gt;

&lt;p&gt;res.json(result.rows);&lt;br&gt;
});&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clients fetch from your backend only — no rate limits.

---

Step 6: Add Real-Time Alerts (Socket.io)

Server emit:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;io.emit("earthquake-alert", {&lt;br&gt;
  magnitude,&lt;br&gt;
  latitude,&lt;br&gt;
  longitude,&lt;br&gt;
  place&lt;br&gt;
});&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Client receive:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;socket.on("earthquake-alert", (data) =&amp;gt; {&lt;br&gt;
  // Show notification&lt;br&gt;
  // Play siren sound&lt;br&gt;
});&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 7: Notification Logic (Mobile/Web)

Simple example:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if (distance &amp;lt;= 300 &amp;amp;&amp;amp; magnitude &amp;gt;= 4.5) {&lt;br&gt;
  triggerSiren();&lt;br&gt;
  showNotification();&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Only relevant earthquakes trigger alerts.

-------

Step 8: Test, Deploy &amp;amp; Scale

Checklist:

- BOT updates data successfully
- API returns latest earthquakes
- Filters work (time, magnitude, region)
- Mobile/web client connects
- Push notifications triggered correctly
Deploy BOT + Backend on any server:

- VPS (DigitalOcean / Linode)
- Render
- Railway
- AWS / GCP


By using a BOT-driven architecture, you can:

1. Avoid API rate limits
2. Support unlimited users
3. Improve performance
4. Deliver fast, real-time alerts

This architecture works for mobile apps, dashboards, emergency systems, or public alert applications.

More From Me

[Blog Website:](https://www.nijerinfo-bd.com/)

Web Development Agency: [Naimur Rahman Nahid](https://naimurrahmannahid.com/)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>api</category>
      <category>node</category>
      <category>backend</category>
      <category>mobile</category>
    </item>
    <item>
      <title>How to Build a Fully Custom WordPress Block Using React</title>
      <dc:creator>Naimur Rahman Nahid</dc:creator>
      <pubDate>Fri, 14 Nov 2025 06:18:08 +0000</pubDate>
      <link>https://dev.to/naimurrahmannahid/how-to-build-a-fully-custom-wordpress-block-using-react-5f3c</link>
      <guid>https://dev.to/naimurrahmannahid/how-to-build-a-fully-custom-wordpress-block-using-react-5f3c</guid>
      <description>&lt;p&gt;The WordPress Block Editor (Gutenberg) has transformed the way content is created and managed. Instead of relying on classic shortcodes or page builders, developers can now build reusable, React-powered custom blocks that integrate directly into WordPress. If you want to modernize your WordPress development workflow, learning how to build custom blocks is a valuable skill.&lt;/p&gt;

&lt;p&gt;In this guide, we will walk through how to create a fully custom WordPress block using React and the official WordPress block development tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Before starting, you should be familiar with:&lt;/li&gt;
&lt;li&gt;Basic WordPress theme or plugin development&lt;/li&gt;
&lt;li&gt;ESNext JavaScript and React&lt;/li&gt;
&lt;li&gt;Node.js and npm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your development environment should include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js v16 or higher&lt;/li&gt;
&lt;li&gt;A local WordPress installation&lt;/li&gt;
&lt;li&gt;A custom plugin folder to contain your block source files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 1: Setting up the project structure&lt;/p&gt;

&lt;p&gt;Inside your WordPress installation, navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wp-content/plugins/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new folder named:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-custom-block
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside this folder, create the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-custom-block/
  ├─ build/
  ├─ src/
  │   └─ index.js
  ├─ block.php
  └─ package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Step 2: Initialize the project using @wordpress/scripts&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;code&gt;npm init @wordpress/block&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Follow the on-screen prompts. This will automatically generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;package.json&lt;/li&gt;
&lt;li&gt;src/index.js&lt;/li&gt;
&lt;li&gt;block.json&lt;/li&gt;
&lt;li&gt;Build configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your plugin now has a working starter block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Register the block in PHP&lt;br&gt;
**&lt;br&gt;
Inside **block.php&lt;/strong&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
/**
 * Plugin Name: Custom Gutenberg Block
 */

function create_custom_block_init() {
    register_block_type( __DIR__ );
}
add_action( 'init', 'create_custom_block_init' );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Editing the React block code&lt;/p&gt;

&lt;p&gt;Open src/index.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { registerBlockType } from '@wordpress/blocks';
import { RichText } from '@wordpress/block-editor';

registerBlockType('myplugin/custom-block', {
    title: 'Custom Block',
    icon: 'admin-customizer',
    category: 'design',

    attributes: {
        content: { type: 'string', source: 'html', selector: 'p' }
    },

    edit({ attributes, setAttributes }) {
        return (
            &amp;lt;RichText
                tagName="p"
                value={attributes.content}
                onChange={(value) =&amp;gt; setAttributes({ content: value })}
                placeholder="Write something..."
            /&amp;gt;
        );
    },

    save({ attributes }) {
        return &amp;lt;RichText.Content tagName="p" value={attributes.content} /&amp;gt;;
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Adding Inspector Controls&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { InspectorControls } from '@wordpress/block-editor';&lt;br&gt;
import { PanelBody, TextControl } from '@wordpress/components';&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Update the edit function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;edit({ attributes, setAttributes }) {
    return (
        &amp;lt;&amp;gt;
            &amp;lt;InspectorControls&amp;gt;
                &amp;lt;PanelBody title="Settings"&amp;gt;
                    &amp;lt;TextControl
                        label="Extra Class"
                        value={attributes.className}
                        onChange={(value) =&amp;gt;
                            setAttributes({ className: value })
                        }
                    /&amp;gt;
                &amp;lt;/PanelBody&amp;gt;
            &amp;lt;/InspectorControls&amp;gt;

            &amp;lt;RichText
                tagName="p"
                value={attributes.content}
                onChange={(value) =&amp;gt; setAttributes({ content: value })}
            /&amp;gt;
        &amp;lt;/&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6: Build the block&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;code&gt;npm start&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Activate and test&lt;/strong&gt;&lt;br&gt;
Go to WordPress dashboard&lt;/p&gt;

&lt;p&gt;Open Plugins&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Activate “&lt;strong&gt;Custom Gutenberg Block&lt;/strong&gt;”&lt;/li&gt;
&lt;li&gt;Insert it into any post or page&lt;/li&gt;
&lt;li&gt;Your block is now fully functional.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building custom Gutenberg blocks with React gives you full control over how content is created in WordPress. &lt;/p&gt;

&lt;p&gt;By using @wordpress/scripts, the setup becomes much simpler and more efficient.&lt;/p&gt;

&lt;p&gt;You can visit our more website:&lt;br&gt;
&lt;a href="https://www.nijerinfo-bd.com/" rel="noopener noreferrer"&gt;Nijer Info BD&lt;/a&gt; Blogging Website&lt;br&gt;
Web Development agency "&lt;a href="https://naimurrahmannahid.com/" rel="noopener noreferrer"&gt;Naimur Rahman Nahid&lt;/a&gt;"&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>react</category>
      <category>blacklivesmatter</category>
    </item>
    <item>
      <title>Integrating OpenAI API with WordPress: Generate Content Automatically</title>
      <dc:creator>Naimur Rahman Nahid</dc:creator>
      <pubDate>Tue, 11 Nov 2025 20:11:36 +0000</pubDate>
      <link>https://dev.to/naimurrahmannahid/integrating-openai-api-with-wordpress-generate-content-automatically-2o95</link>
      <guid>https://dev.to/naimurrahmannahid/integrating-openai-api-with-wordpress-generate-content-automatically-2o95</guid>
      <description>&lt;p&gt;AI is revolutionizing the way we create content — and as WordPress developers, we can bring that power directly into our websites. In this tutorial, I’ll show you how to integrate the OpenAI API with WordPress to automatically generate blog post content, product descriptions, or any text-based data you need.&lt;/p&gt;

&lt;p&gt;Why Integrate OpenAI with WordPress?&lt;/p&gt;

&lt;p&gt;By connecting OpenAI’s API with WordPress, you can:&lt;/p&gt;

&lt;p&gt;Generate SEO-friendly blog posts automatically&lt;/p&gt;

&lt;p&gt;Create AI-written summaries or product descriptions&lt;/p&gt;

&lt;p&gt;Add chat-based features or auto-reply functionality&lt;/p&gt;

&lt;p&gt;Reduce content writing time by 70–80%&lt;/p&gt;

&lt;p&gt;This kind of automation can be a real productivity booster for bloggers, agencies, and eCommerce store owners.&lt;/p&gt;

&lt;p&gt;Step 1: Get Your OpenAI API Key&lt;br&gt;
Go to OpenAI API Keys&lt;br&gt;
Create a new key and copy it&lt;br&gt;
Keep it safe — you’ll need it in your WordPress code&lt;/p&gt;

&lt;p&gt;Step 2: Create a Simple WordPress Plugin&lt;br&gt;
Let’s create a minimal plugin to connect with OpenAI.&lt;br&gt;
Folder structure:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/wp-content/plugins/wp-openai-generator/&lt;br&gt;
    - wp-openai-generator.php&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;wp-openai-generator.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
/**
 * Plugin Name: WP OpenAI Generator
 * Description: Generate blog content using OpenAI API.
 * Version: 1.0
 * Author: Naimur Rahman Nahid
 */

if ( ! defined( 'ABSPATH' ) ) exit;

// Main function
function nahid_generate_ai_content( $prompt ) {
    $api_key = 'YOUR_OPENAI_API_KEY';
    $endpoint = 'https://api.openai.com/v1/chat/completions';

    $response = wp_remote_post( $endpoint, array(
        'headers' =&amp;gt; array(
            'Authorization' =&amp;gt; 'Bearer ' . $api_key,
            'Content-Type'  =&amp;gt; 'application/json',
        ),
        'body' =&amp;gt; json_encode(array(
            'model' =&amp;gt; 'gpt-3.5-turbo',
            'messages' =&amp;gt; array(
                array('role' =&amp;gt; 'user', 'content' =&amp;gt; $prompt),
            ),
            'max_tokens' =&amp;gt; 300,
        )),
    ));

    if ( is_wp_error( $response ) ) {
        return 'Error: ' . $response-&amp;gt;get_error_message();
    }

    $body = json_decode( wp_remote_retrieve_body( $response ), true );
    return $body['choices'][0]['message']['content'] ?? 'No response.';
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Add a WordPress Admin Interface&lt;/p&gt;

&lt;p&gt;Let’s make it user-friendly by adding a small settings page in the dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_action('admin_menu', function() {
    add_menu_page('AI Content Generator', 'AI Generator', 'manage_options', 'ai-generator', 'nahid_ai_admin_page');
});

function nahid_ai_admin_page() {
    if ( isset($_POST['ai_prompt']) ) {
        $prompt = sanitize_text_field($_POST['ai_prompt']);
        $output = nahid_generate_ai_content($prompt);
        echo '&amp;lt;h3&amp;gt;AI Generated Content:&amp;lt;/h3&amp;gt;&amp;lt;div style="background:#fff;padding:10px;border:1px solid #ddd;"&amp;gt;' . esc_html($output) . '&amp;lt;/div&amp;gt;';
    }

    echo '&amp;lt;form method="post"&amp;gt;
        &amp;lt;textarea name="ai_prompt" rows="5" cols="60" placeholder="Enter your content idea..."&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
        &amp;lt;input type="submit" class="button button-primary" value="Generate Content"&amp;gt;
    &amp;lt;/form&amp;gt;';
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now go to:&lt;br&gt;
Dashboard → AI Generator&lt;br&gt;
Enter any topic (like “Write a blog post about WordPress security best practices”) — and OpenAI will generate content for you inside WordPress.&lt;/p&gt;

&lt;p&gt;Step 4: Secure Your API Key&lt;/p&gt;

&lt;p&gt;Never hardcode your API key in production.&lt;br&gt;
Instead, save it in &lt;strong&gt;&lt;code&gt;wp-config.php&lt;/code&gt;&lt;/strong&gt; 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;define('OPENAI_API_KEY', 'your-secret-key');

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$api_key = OPENAI_API_KEY;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Extend It Further&lt;/p&gt;

&lt;p&gt;You can extend this concept by:&lt;/p&gt;

&lt;p&gt;Auto-generating post drafts&lt;/p&gt;

&lt;p&gt;Adding AI-powered title &amp;amp; meta description generators&lt;/p&gt;

&lt;p&gt;Using the WordPress REST API to expose your AI endpoint&lt;/p&gt;

&lt;p&gt;Building a Gutenberg block that fetches AI-generated content&lt;/p&gt;

&lt;p&gt;AI is not here to replace creators — it’s here to amplify creativity and productivity.&lt;br&gt;
By integrating OpenAI into WordPress, we can automate repetitive content work, enhance SEO, and help users focus on strategy and design instead of typing endlessly.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>openai</category>
    </item>
  </channel>
</rss>
