This commit is contained in:
Hugh Rundle 2024-09-15 17:20:50 +10:00
parent c919c0ccf4
commit ed6f7d7ca8
Signed by: hugh
GPG key ID: A7E35779918253F9
3 changed files with 28 additions and 23 deletions

View file

@ -6,10 +6,7 @@ This is a simple webhook to push new cardiParties into the cardiParty channel.
1. Create and activate [virtual env](https://docs.python.org/3/library/venv.html) 1. Create and activate [virtual env](https://docs.python.org/3/library/venv.html)
2. Install requirements: `pip install -r requirements.txt` 2. Install requirements: `pip install -r requirements.txt`
3. Set up a cronjob 3. Set up a cronjob (see below)
1. set the env values (see below)
2. set a time to run e.g. every 30 mins
3. set the command listed below under "Cron job command"
4. Test cronjob works 4. Test cronjob works
5. Relax 5. Relax
@ -17,29 +14,36 @@ 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 the civiCRM API use `cv` to grab the details of the latest cardiParty 1. With a cron job we call `get_party.sh`
2. We pipe that string into a python script 2. The shell script set env values and uses the civiCRM API using `cv` to grab the details of the latest cardiParty
3. The script checks a custom RSS feed for new parties 3. We pipe that string into `webhook.py`
4. If no new party, end 4. The script checks a custom RSS feed for new parties
5. If new party, 5. If no new party, end
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 image and title from the RSS feed and the details from the cv API call
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.
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`) **channel** is the channel ID (`DISCORD_CHANNEL`)
**token** is the secret token for the webhook (`DISCORD_TOKEN`) **token** is the secret token for the webhook (`DISCORD_TOKEN`)
**cardiparty_ping** is the ID of the `@cardiParty ping` role (`DISCORD_CARDIPARTY_PING`) **cardiparty_ping** is the ID of the `@cardiParty ping` role (`DISCORD_CARDIPARTY_PING`)
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>`
## Cron job command ## Cron job command
```sh ```sh
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 */15 * * * * cd /home/cardigan/rss-discord-bot && ./get_party.sh
``` ```
This should pipe a string like this into the script: `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."}] [{"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."}]
@ -49,4 +53,4 @@ This should pipe a string like this into the script:
The rss feed is `https://newcardigan.org/category/cardiparties/?feed=cardipartyfeed`. The rss feed is `https://newcardigan.org/category/cardiparties/?feed=cardipartyfeed`.
This special `cardipartyfeed` 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. 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.

12
get_party.sh Normal file → Executable file
View file

@ -1,11 +1,11 @@
#!/bin/bash #!/bin/bash
# set envs and paths # 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 source /home/cardigan/rss-discord-bot/venv/bin/activate
python /home/cardigan/rss-discord-bot/venv/bin/python3.11 export CIVICRM_SETTINGS="/var/www/html/wp-content/uploads/civicrm/civicrm.settings.php"
DISCORD_CHANNEL="" export DISCORD_SERVER="<server_id>"
DISCORD_TOKEN="" export DISCORD_TOKEN="<token>"
DISCORD_CARDIPARTY_PING="" export DISCORD_CARDIPARTY_PING="<group_id>"
# let's go 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
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

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/home/cardigan/rss-discord-bot/venv/python/python3.11
from datetime import datetime from datetime import datetime
import json import json
@ -8,8 +8,8 @@ import sys
import feedparser import feedparser
import requests import requests
channel = os.getenv("DISCORD_CHANNEL") dc_server = os.getenv("DISCORD_SERVER") # this is actually the instance, not a channel
token = os.getenv("DISCORD_TOKEN") token = os.getenv("DISCORD_TOKEN") # token for this bot
cardiparty_ping = os.getenv("DISCORD_CARDIPARTY_PING") cardiparty_ping = os.getenv("DISCORD_CARDIPARTY_PING")
# get the latest cardiparty with image as enclosure # get the latest cardiparty with image as enclosure
@ -48,7 +48,7 @@ if guid != first.guid:
}] }]
headers = {'user-agent': 'cardiParty-discord-bot/1.0.0'} headers = {'user-agent': 'cardiParty-discord-bot/1.0.0'}
url = f"https://discord.com/api/webhooks/{channel}/{token}" url = f"https://discord.com/api/webhooks/{dc_server}/{token}"
payload = { payload = {
"thread_name": f"{first.title} | {title}", "thread_name": f"{first.title} | {title}",
"content": content, "content": content,
@ -57,4 +57,5 @@ if guid != first.guid:
} }
r = requests.post(url, json=payload, headers=headers) r = requests.post(url, json=payload, headers=headers)
r.raise_for_status() # if we got a 4xx response this will log it out print(r)
r.raise_for_status() # if we got a 4xx response this will log it