<?php
require_once "../../../config/settings.inc.php";
require_once "../../../include/network.php";
$nt = new NetworkTable("WFO");
require_once "../../../include/myview.php";
require_once "../../../include/database.inc.php";

$btable = <<<EOM
<table class="table table-striped table-bordered">
<thead>
<tr>
  <th>Twitter/X User</th>
  <th>Channels</th>
</tr></thead>
<tbody>
EOM;
$pgconn = iemdb("iembot");
$rs = pg_query(
    $pgconn, <<<EOM
    select o.screen_name, string_agg(channel_name, ', ' order by channel_name)
    as channels from
    iembot_twitter_oauth o, iembot_subscriptions s, iembot_channels c
    WHERE
        o.iembot_account_id = s.iembot_account_id and
        o.iem_owned and s.channel_id = c.id
    GROUP by o.screen_name ORDER by screen_name ASC
EOM
        );
while ($row = pg_fetch_assoc($rs)) {
    $btable .= sprintf(
        "<tr>".
        "<td><a href=\"https://x.com/%s\">@%s</a></td>".
        "<td>%s</td></tr>",
        $row["screen_name"],
        $row["screen_name"],
        $row["channels"]
    );
}
$btable .= "</tbody></table>";

$t = new MyView();
$t->title = "IEMBot Project";
$t->jsextra = <<<EOM
<script src="index.js"></script>
EOM;

$wselect = "<select name=\"wfo\" id=\"wfoselect\">";
foreach ($nt->table as $key => $val) {
    $wselect .= "<option value=\"$key\">[$key] " . $val["name"] . "\n";
}
$wselect .= "</select>";

$channels = file_get_contents('channels.html');
$t->content = <<<EOM
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
 <li class="breadcrumb-item"><a href="/current/severe.phtml">Severe Weather</a></li>
 <li class="breadcrumb-item active" aria-current="page">IEMBot Project</li>
</ol>
</nav>

<p><i>iembot</i> is a XMPP chat bot that relays National Weather Service issued
text products to XMPP chat rooms hosted on the conference.weather.im multi-user
chat service. <i>iembot</i> was written to aid the dissemination and use of NWS issued
warnings by their chat partners.</p>

<ul>
    <li><a href="#channels"><i class="bi bi-list"></i> IEMBot Channels</a></li>
    <li><a href="#bots"><i class="bi bi-list"></i> List of IEMBots on Social Media + Channel Subscriptions</a></li>
</ul>


<h3>Where to access <i>iembot</i> messages?</h3>

<ul>
 <li><a href="public.phtml">Public Chatrooms</a> (requires XMPP client and public XMPP account)</li>
 <li><a href="https://weather.im/iembot/">HTML web interface</a>  anybody can view and monitor online!</li>
 <li><a href="https://weather.im/live/">Weather.IM Live Client</a>, interactive chat client.</li>
 <li>Configure IEMBot to post messages to your <a href="twitter.php">Twitter/X account</a>.</li>
 <li>Configure IEMBot to post to <a href="/projects/iembot/mastodon">Mastodon</a></li>
 <li>Configure IEMBot to post to your <a href="/projects/iembot/slack/">Slack</a></li>
 <li>Configure IEMBot for your <a href="https://weather.im/iembot/config/">Webhooks</a></li>
</ul>

<form name="myForm">
<p><img src="/images/rss.gif"> RSS feed of <i>iembot</i> messages per NWS Forecast Office:
<br /><b>WFO:</b>{$wselect}

<br /><div id="wfolink" style="float: left;"><b>URL: </b><a href="https://weather.im/iembot-rss/room/abqchat.xml">https://weather.im/iembot-rss/room/abqchat.xml</a></div>

<br />
<p>All iembot messages are here: <a href="https://weather.im/iembot-rss/room/botstalk.xml">https:/weather.im/iembot-rss/room/botstalk.xml</a>
</form>

<h3>How does <i>iembot</i> work?</h3>

<p><i>iembot</i> consists of two programs that run on the Iowa Mesonet server.  The first is a parser that ingests text products issued by the NWS.  The parser picks out the important information
regarding the product and sends it via a XMPP instant message to the bot
logged in on the chat server.  The bot then
routes the incoming message to a WFO chatroom from which the product was
issued.  The entire process takes much less than a second.</p>

<h3>Why was <i>iembot</i> written?</h3>
<ol>
 <li>During chats, the NWS should not need to relay details of already issued
 products to the chatroom.  Replication should always be avoided.</li>
 <li>During onair coverage, the media often are not able to quickly read
 severe text products that come off the printer.  Instead, they can quickly
 view the chatroom and clearly see what has just been issued.</li>
 <li>The NWS can get instant verification that their product was disseminated
 over NOAAport and processed by a computerized ingestor.</li>
 <li>With the advent of Valid Time Event Code (VTEC), the NWS can issue
 complex statements.  The bot's report of these products can help clear
 confusion with the media partners.</li>
 <li>With the products and timestamps in the chatroom logs, it is an outstanding log of how the severe weather event played out for historical review.</li>
 <li>It is a proof of concept for how NWS products can be disseminated securely and synchronously to clients in an Open Source and standards based framework.</li>
</ol>

<h3>What does <i>iembot</i> look like in the chatroom?</h3>

<p>Here is a screenshot from the "botstalk" chatroom where <i>iembot</i> dumps all processed messages.  The text in blue can be clicked on for the product text and perhaps a visual display.<br />

<img src="iembot.png" class="img-fluid">

<a name="channels"><h3>Channels</h3></a>

<p>The following is a reference of the association of a NWS Text Product and
the channels it is assigned.  If you click on the plus button, you can expand
the listing to show an example product.  The channel templates should not be
used literally, but the following are the placeholders used and what they
mean.</p>

<dl class="dl-horizontal">
 <dt>&lt;afos_pil&gt;</dt><dd>The 4-6 character 'AWIPS ID' or 'AFOS PIL' used
 within the products WMO header.</dd>
 <dt>&lt;afos_pil_prefix&gt;...</dt><dd>The first three characters of the
 'AWIPS ID' or 'AFOS PIL' used within the products WMO header.  The dots here
 are literal, so the channel to get all Record Event Reports would be "RER..."</dd>
 <dt>&lt;vtec_phenomena&gt;</dt><dd>2 character VTEC Phenomena</dd>
 <dt>&lt;vtec_significance&gt;</dt><dd>1 character VTEC Significance</dd>
 <dt>&lt;vtec_action&gt;</dt><dd>3 character VTEC Action</dd>
 <dt>&lt;wfo&gt;</dt><dd>3 character NWS Forecast Office Idenitifer</dd>
 <dt>&lt;ugc&gt;</dt><dd>6 character UGC Code <a href="/nws/list_ugcs.php">List Codes</a></dd>
 <dt>&lt;state&gt;</dt><dd>2 character state code</dd>
 <dt>&lt;aaa&gt;</dt><dd>First 3 Characters in AWIPS ID</dd>
 <dt>&lt;wmo_source&gt;</dt><dd>Full 4 Character WMO Source ID</dd>
 </dl>

<p><strong>Changelog:</strong>
<ul>
    <li><strong>3 Mar 2026</strong>:  The IEM website had HTTP redirects for
    some legacy iembot URI endpoints.  Those were removed.</li>
    <li><strong>18 May 2022:</strong> VTEC products that are purely
    continues, cancels, or expires updates now go into more isolated
    channels than the default phenomena/significance channels. These channels
    have a suffix of <code>-ACT</code>ion.  For example, a continues Tornado
    Warning statement would be in <code>TO.W-CON</code>.</li>
    <li><strong>20 Dec 2022:</strong> Added documentation on handling of
    ASOS/METAR wind gusts.  Mount Washington KMWN was thresholded to 80kts.
    </li>
</ul></p>

<p><strong>ASOS/METAR Wind Gusts</strong>

<p>The IEM realtime ingest attempts to properly handle wind gust and peak
wind gust reports.  When either of these meet or exceed 50 kts, an alert like
so is generated. <code>Dakota Hills,CO (C99) ASOS  reports gust of 54 knots
(62.1 mph) from WNW @ 1415Z KC99 201415Z AUTO 30029G54KT 10SM CLR M12/M18 A3009 RMK AO2</code>.</p>

<p>The channels associated with this alert include the corresponding WFO <code>XXX</code>,
the 4-character ICAO for the site <code>METAR.ICAO</code>, and in increments of ten thresholded
wind channels for the site <code>METAR.ICAO.WIND##</code>.  This allows one to subscribe to
alerts that meet or exceed a given threshold.  For example, a 75 knot gust for Mount Washington
(KMWN) would go to channels <code>METAR.KMWN</code>, <code>METAR.KMWN.WIND50</code>
, <code>METAR.KMWN.WIND60</code>, and <code>METAR.KMWN.WIND70</code>.</p>

{$channels}

<a name="bots"><h3>IEMBots on Social Media and Channel Subscriptions</h3></a>

<p>These are bots on social media controlled by the IEM. Presently, the
channel subscriptions are shared between the three social media services.</p>

{$btable}

EOM;
$t->render('single.phtml');
