headline command which uses NewsAPI.org
This commit is contained in:
SpudGunMan
2025-10-29 23:28:14 -07:00
parent d330f3e0d6
commit e07c5a923e
6 changed files with 115 additions and 10 deletions
+5 -1
View File
@@ -62,7 +62,11 @@ rssFeedURL = http://www.hackaday.com/rss.xml,http://rss.slashdot.org/Slashdot/sl
rssFeedNames = default,slashdot,mesh
rssMaxItems = 3
rssTruncate = 100
# enable or disable the headline command which uses NewsAPI.org key at https://newsapi.org/register
enableNewsAPI = False
newsAPI_KEY =
newsAPIregion = us
#
# enable or disable the wikipedia search module
wikipedia = True
# Use local Kiwix server instead of online Wikipedia
+6 -4
View File
@@ -84,6 +84,7 @@ def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_n
"cartremove": lambda: handle_inventory(message, message_from_id, deviceID),
"cartsell": lambda: handle_inventory(message, message_from_id, deviceID),
"joke": lambda: tell_joke(message_from_id),
"latest": lambda: get_newsAPI(message),
"leaderboard": lambda: get_mesh_leaderboard(message, message_from_id, deviceID),
"lemonstand": lambda: handleLemonade(message, message_from_id, deviceID),
"lheard": lambda: handle_lheard(message, message_from_id, deviceID, isDM),
@@ -1560,12 +1561,14 @@ def handle_boot(mesh=True):
if my_settings.wikipedia_enabled:
if my_settings.use_kiwix_server:
logger.debug(f"System: Wikipedia search Enabled using Kiwix server at {kiwix_url}")
logger.debug(f"System: Wikipedia search Enabled using Kiwix server at {my_settings.kiwix_url}")
else:
logger.debug("System: Wikipedia search Enabled")
if my_settings.rssEnable:
logger.debug(f"System: RSS Feed Reader Enabled for feeds: {rssFeedNames}")
logger.debug(f"System: RSS Feed Reader Enabled for feeds: {my_settings.rssFeedNames}")
if my_settings.enable_headlines:
logger.debug("System: News Headlines Enabled from NewsAPI.org")
if my_settings.radio_detection_enabled:
logger.debug(f"System: Radio Detection Enabled using rigctld at {my_settings.rigControlServerAddress} broadcasting to channels: {my_settings.sigWatchBroadcastCh}")
@@ -1579,8 +1582,7 @@ def handle_boot(mesh=True):
if my_settings.read_news_enabled:
logger.debug(f"System: File Monitor News Reader Enabled for {my_settings.news_file_path}")
if my_settings.bee_enabled:
logger.debug("System: File Monitor Bee Monitor Enabled for bee.txt")
logger.debug("System: File Monitor Bee Monitor Enabled for 🐝bee.txt")
if my_settings.usAlerts:
logger.debug(f"System: Emergency Alert Broadcast Enabled on channel {my_settings.emergency_responder_alert_channel} for interface {my_settings.emergency_responder_alert_interface}")
if my_settings.enableDEalerts:
+55
View File
@@ -475,7 +475,62 @@ Configure in `[wikipedia]` section of `config.ini`.
---
## News & Headlines (`latest` Command)
The `latest` command allows you to fetch current news headlines or articles on any topic using the NewsAPI integration. This is useful for quickly checking the latest developments on a subject, even from the mesh.
### Usage
- **Get the latest headlines on a topic:**
```
latest <topic>
```
Example:
```
latest meshtastic
```
This will return the most recent news articles about "meshtastic".
- **General latest news:**
```
latest
```
Returns the latest general news headlines.
### How It Works
- The bot queries NewsAPI.org for the most recent articles matching your topic.
- Each result includes the article title and a short description.
You need to go register for the developer key and read terms of use.
```ini
# enable or disable the headline command which uses NewsAPI.org
enableNewsAPI = True
newsAPI_KEY = key at https://newsapi.org/register
newsAPIregion = us
```
### Example Output
```
🗞️:📰Meshtastic project launches new firmware
The open-source mesh radio project Meshtastic has released a major firmware update...
📰How Meshtastic is changing off-grid communication
A look at how Meshtastic devices are being used for emergency response...
📰Meshtastic featured at DEF CON 2025
The Meshtastic team presented new features at DEF CON, drawing large crowds...
```
### Notes
- You can search for any topic, e.g., `latest wildfire`, `latest ham radio`, etc.
- The number of results can be adjusted in the configuration.
- Requires internet access for the bot to fetch news.
___
## DX Spotter Module
The DX Spotter module allows you to fetch and display recent DX cluster spots from [spothole.app](https://spothole.app) directly in your mesh-bot.
+39 -1
View File
@@ -1,11 +1,13 @@
# rss feed module for meshing-around 2025
from modules.log import logger
from modules.settings import rssFeedURL, rssFeedNames, rssMaxItems, rssTruncate, urlTimeoutSeconds, ERROR_FETCHING_DATA
from modules.settings import rssFeedURL, rssFeedNames, rssMaxItems, rssTruncate, urlTimeoutSeconds, ERROR_FETCHING_DATA, newsAPI_KEY
import urllib.request
import xml.etree.ElementTree as ET
import html
from html.parser import HTMLParser
import bs4 as bs
import requests
import datetime
# Common User-Agent for all RSS requests
COMMON_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
@@ -136,3 +138,39 @@ def get_rss_feed(msg):
logger.error(f"Error fetching RSS feed from {feed_url}: {e}")
return ERROR_FETCHING_DATA
def get_newsAPI(user_search="meshtastic"):
# Fetch news from NewsAPI.org
user_search = user_search.lower().replace("latest ", "", 1).strip()
try:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome'}
last_week = datetime.datetime.now() - datetime.timedelta(days=7)
newsAPIurl = (
f"https://newsapi.org/v2/everything?"
f"q={user_search}&language=en&from={last_week.strftime('%Y-%m-%d')}&sortBy=popularity&pageSize=7&apiKey={newsAPI_KEY}"
)
response = requests.get(newsAPIurl, headers=headers, timeout=10)
news_data = response.json()
if news_data.get("status") != "ok":
error_message = news_data.get("message", "Unknown error")
logger.error(f"NewsAPI error: {error_message}")
return [f"NewsAPI error: {error_message}"]
logger.debug(f"System: NewsAPI Searching for '{user_search}' got {news_data.get('totalResults', 0)} results")
articles = news_data.get("articles", [])[:3]
news_list = []
for article in articles:
title = article.get("title", "No Title")
url = article.get("url", "")
description = article.get("description", '')
news_list.append(f"📰{title}\n{description}")
# Make a nice newspaper style output
msg = f"🗞️:"
for item in news_list:
msg += item + "\n\n"
return msg.strip()
except Exception as e:
logger.error(f"Error fetching news: {e}")
return [f"Exception: {e}"]
+3
View File
@@ -276,6 +276,9 @@ try:
rssMaxItems = config['general'].getint('rssMaxItems', 3) # default 3 items
rssTruncate = config['general'].getint('rssTruncate', 100) # default 100 characters
rssFeedNames = config['general'].get('rssFeedNames', 'default,arrl').split(',')
newsAPI_KEY = config['general'].get('newsAPI_KEY', '') # default empty
newsAPIregion = config['general'].get('newsAPIregion', 'us') # default us
enable_headlines = config['general'].getboolean('enableNewsAPI', False) # default False
# sentry
sentry_enabled = config['sentry'].getboolean('SentryEnabled', False) # default False
+7 -4
View File
@@ -153,10 +153,14 @@ if wikipedia_enabled or use_kiwix_server:
help_message = help_message + ", wiki"
# RSS Feed Configuration
if rssEnable:
if rssEnable or enable_headlines:
from modules.rss import * # from the spudgunman/meshing-around repo
trap_list = trap_list + ("readrss",)
help_message = help_message + ", readrss"
if rssEnable:
trap_list = trap_list + ("readrss",)
help_message = help_message + ", readrss"
if enable_headlines:
trap_list = trap_list + ("latest",)
help_message = help_message + ", latest"
# LLM Configuration
if llm_enabled:
@@ -1153,7 +1157,6 @@ def handleAlertBroadcast(deviceID=1):
if enableDEalerts:
deAlerts = get_nina_alerts()
if usAlerts:
alert_types = [
("fema", alertFema, ipawsAlertEnabled),