adjust for cardicast

This commit is contained in:
Hugh Rundle 2024-09-16 10:23:55 +10:00
parent ed6f7d7ca8
commit 92c1524acf
Signed by: hugh
GPG key ID: A7E35779918253F9
6 changed files with 53 additions and 67 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.env
log.txt

View file

@ -1,6 +1,6 @@
# Discord cardiParty webhook # Discord cardiCast webhook
This is a simple webhook to push new cardiParties into the cardiParty channel. This is a simple webhook to push new cardiCast episodes into the cardiCast Discord channel.
## install ## install
@ -14,43 +14,37 @@ This is a simple webhook to push new cardiParties into the cardiParty channel.
We run this on the newcardigan wordpress server. We run this on the newcardigan wordpress server.
1. With a cron job we call `get_party.sh` 1. With a cron job we call `trigger.sh`
2. The shell script set env values and uses the civiCRM API using `cv` to grab the details of the latest cardiParty 2. The shell script sets env values then calls `webhook.py`
3. We pipe that string into `webhook.py` 4. The python script checks a custom RSS feed for new podcast episodes
4. The script checks a custom RSS feed for new parties 5. If no new episode, end
5. If no new party, end 6. If new episode,
6. If new party,
1. save the guid to `latest_post.txt` for the next round of checking 1. save the guid to `latest_post.txt` for the next round of checking
2. use the image and title from the RSS feed and the details from the cv API call 2. use the values from the RSS feed
3. publish via a webhook to Discord 3. publish via a webhook to Discord
## env values ## env values
These are all set in `get_party.sh`, not in crontab. Because we need most of them in a subsequent call (either inside `cv` or in `webhook.py`) we `export` them all. These are all set in `trigger.sh`, not in crontab, to keep things contained.
We need to include some secrets via environment values: We need to include some secrets via environment values:
**channel** is the channel ID (`DISCORD_CHANNEL`) * the guild/server ID (`DISCORD_GUILD`)
**token** is the secret token for the webhook (`DISCORD_TOKEN`) * the secret token for the webhook (`DISCORD_TOKEN`)
**cardiparty_ping** is the ID of the `@cardiParty ping` role (`DISCORD_CARDIPARTY_PING`) * the ID of the `@cardiCast ping` role (`DISCORD_CARDICAST_PING`)
And because we run python in a virtual environment:
There are also a couple of other things we need to do:
**civicrm_settings** - set `CIVICRM_SETTINGS` so that `cv` can find it
**venv** - we need to activate the venv using `source <path/to/venv>` **venv** - we need to activate the venv using `source <path/to/venv>`
## Cron job command ## Cron job command
```sh ```sh
*/15 * * * * cd /home/cardigan/rss-discord-bot && ./get_party.sh */18 * * * * cd /home/cardigan/rss-discord-bot && ./trigger.sh
```
`get_party.sh` should pipe a string like this into `webhook.py`:
```
[{"id":108,"title":"Melbourne Art Library","address.city":"Melbourne","start_date":"2024-04-06 16:30:00","summary":"Melbourne Art Library (MAL) is a not-for-profit lending library that collects specialised art and design texts. They are proudly independent and are curious about what being a 'library' means."}]
``` ```
## RSS feed ## RSS feed
The rss feed is `https://newcardigan.org/category/cardiparties/?feed=cardipartyfeed`. The rss feed is `https://newcardigan.org/category/cardiparties/?feed=featured_image_feed`.
This special `cardipartyfeed` is a slightly modified RSS2 feed. The only thing it does differently is filter out everything that isn't a cardiparty ,and include the featured image in an `enclosure` so that we can pick it up directly from the feed. See the newcardigan WordPress theme for how this works. This special `featured_image_feed` is a slightly modified RSS2 feed. The only thing it does differently is include the featured image in an `enclosure` so that we can pick it up directly from the feed. See the newcardigan WordPress theme for how this works.

View file

@ -1,11 +0,0 @@
#!/bin/bash
# set envs and paths
export PATH=/home/cardigan/rss-discord-bot/venv/bin:usr/local/bin:usr/bin:
source /home/cardigan/rss-discord-bot/venv/bin/activate
export CIVICRM_SETTINGS="/var/www/html/wp-content/uploads/civicrm/civicrm.settings.php"
export DISCORD_SERVER="<server_id>"
export DISCORD_TOKEN="<token>"
export DISCORD_CARDIPARTY_PING="<group_id>"
cv api4 Event.get '{"select":["title","address.city","start_date","summary"],"join":[["Address AS address","LEFT",["loc_block_id.address_id","=","address.id"]]],"orderBy":{"start_date":"DESC"},"limit":1}' | ./webhook.py >> /home/cardigan/discord.log 2>&1

0
latest_post.txt Normal file
View file

10
trigger.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/bash
# set envs and paths
export PATH=/home/cardigan/rss-discord-bot/venv/bin:usr/local/bin:usr/bin:
source /home/cardigan/rss-discord-bot/venv/bin/activate
export DISCORD_GUILD=""
export DISCORD_TOKEN=""
export DISCORD_CARDICAST_PING=""
./webhook.py >> /home/cardigan/discord.log 2>&1

View file

@ -8,54 +8,45 @@ import sys
import feedparser import feedparser
import requests import requests
dc_server = os.getenv("DISCORD_SERVER") # this is actually the instance, not a channel guild = os.getenv("DISCORD_GUILD") # Discord server code
token = os.getenv("DISCORD_TOKEN") # token for this bot token = os.getenv("DISCORD_TOKEN") # token for this bot
cardiparty_ping = os.getenv("DISCORD_CARDIPARTY_PING") cardicast_ping = os.getenv("DISCORD_CARDICAST_PING") # Discord role
# get the latest cardiparty with image as enclosure # get the latest post with image as enclosure
f = feedparser.parse("https://newcardigan.org/category/cardiparties/?feed=cardipartyfeed") f = feedparser.parse("https://newcardigan.org/category/cardicast/?feed=featured_image_feed")
first = f.entries[0] p = f.entries[0]
# check whether we have already seen this entry # check whether we have already seen this entry
with open("latest_post.txt", "r+") as f: with open("latest_post.txt", "r+") as f:
guid = f.read().strip() guid = f.read().strip()
f.close() f.close()
if guid != first.guid: if guid != p.guid:
# update the guid # update the guid
with open("latest_post.txt", "w+") as f: with open("latest_post.txt", "w+") as f:
f.write(first.guid) f.write(p.guid)
f.close() f.close()
api_response = sys.stdin.read() # read the API call output that was piped in content = f"[<:newCardigan:1280097925149626419> **{p.title}**]({p.link})\n\n{p.description}\n\n<@&{cardicast_ping}>\n\n"
api_data = json.loads(api_response)[0] embeds = [
{
title = api_data["title"] "title": "Listen to this episode right now",
city = api_data["address.city"] "url": p.enclosures[1].href,
start_date = api_data["start_date"]
summary = api_data["summary"]
start_date = datetime.fromisoformat(start_date).astimezone().strftime(
"%I:%M%p %a %d %b %Y"
).strip("0") # remove time zero padding if any
content = f"[<:newCardigan:1280097925149626419> **{title}**]({first.link})\n_{city}_\n_{start_date}_\n\n{summary}\n\n<@&{cardiparty_ping}>"
embeds = [{
"title": "Find out more and register!",
"url": first.link,
"color": 16741516, "color": 16741516,
"image": { "image": {
"url": first.enclosures[0].href "url": p.enclosures[0].href
} }
}] }
]
headers = {'user-agent': 'cardiParty-discord-bot/1.0.0'} headers = {'user-agent': 'cardiCast-discord-bot/1.0.0'}
url = f"https://discord.com/api/webhooks/{dc_server}/{token}" url = f"https://discord.com/api/webhooks/{guild}/{token}"
payload = { payload = {
"thread_name": f"{first.title} | {title}", "thread_name": f"{p.title}",
"content": content, "content": content,
"embeds": embeds, "embeds": embeds,
"allowed_mentions": { "roles": [cardiparty_ping] } "allowed_mentions": { "roles": [cardicast_ping] }
} }
r = requests.post(url, json=payload, headers=headers) r = requests.post(url, json=payload, headers=headers)
print(r) print(datetime.now().isoformat(' '), r)
r.raise_for_status() # if we got a 4xx response this will log it r.raise_for_status() # if we got a 4xx response