Skip to content

Commit 6aa1f93

Browse files
committed
mod_irc_bouncer: If mentioned, use PM email digest frequency.
If a user has been mentioned by username, ignore the normal email digest frequency and use the PM digest frequency, since the user probably wants to be notified of these sooner. Additionally, handle the email frequency variable properly in a few cases where we were not before.
1 parent bc24c1a commit 6aa1f93

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

configs/templates/.bouncer.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
; specify the email digest period in minutes.
3333
; To disable interactive digests and only do email digests, negate the digest period.
3434
; 0 will disable email digests while keeping interactive digests enabled (default).
35+
; Note that if you have been mentioned by username, the PM email digest frequency is used,
36+
; as presumably these digests occur more frequently.
3537
;
3638
; Please note that the log file size is limited by your system administrator; therefore,
3739
; if you use interactive mode, truncation may occur if you do not regularly check the channel.

modules/mod_irc_bouncer.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct bouncer_channel {
109109
time_t last_flush; /*!< Last flush */
110110
unsigned int email_frequency; /*!< Email flush frequency (0 to disable) */
111111
unsigned int interactive:1; /*!< Interactive flushing? */
112+
unsigned int user_mentioned:1; /*!< Whether user has been mentioned in channel chat since last flush */
112113
RWLIST_ENTRY(bouncer_channel) entry;
113114
char *data; /* Not quite a flexible struct member, but sufficient */
114115
};
@@ -439,14 +440,23 @@ static void *periodic_emailer(void *unused)
439440

440441
/* First, flush any PMs */
441442
if (TIME_TO_FLUSH(bu->pmbc)) {
443+
if (!bu->pmbc->email_frequency) {
444+
continue; /* Don't flush if email is disabled */
445+
}
442446
if (!periodic_channel_flush(bu->pmbc, now)) {
443447
bu->pmbc->last_flush = now;
444448
}
445449
}
446450

447451
/* Now, check the channels */
448452
RWLIST_TRAVERSE(&bu->channels, bc, entry) {
449-
if (TIME_TO_FLUSH(bc)) {
453+
if (!bc->email_frequency) {
454+
continue; /* Don't flush if email is disabled */
455+
}
456+
/* We don't have an explicit frequency for email digests if mentioned in a channel,
457+
* we just use the PM digest frequency (which is presumably lower). */
458+
if (TIME_TO_FLUSH(bc) || (bc->user_mentioned && bu->pmbc->email_frequency && (bc->last_flush < now - (60 * bu->pmbc->email_frequency)))) {
459+
bc->user_mentioned = 0;
450460
if (!periodic_channel_flush(bc, now)) {
451461
bc->last_flush = now;
452462
}
@@ -806,6 +816,15 @@ static void privmsg_cb(const char *hostmask, const char *sender, const char *rec
806816
RWLIST_UNLOCK(&bouncer_users);
807817
}
808818

819+
static inline int user_mentioned(const char *username, const char *msg)
820+
{
821+
char mention[64];
822+
/* Most IRC clients will notify the user for normal channel chat if the user's username is present in a message.
823+
* It's generally customary to mention users with "username: message" syntax, so that's what we look for here, to avoid false positives. */
824+
snprintf(mention, sizeof(mention), "%s:", username);
825+
return strstr(msg, username) ? 1 : 0;
826+
}
827+
809828
static void command_cb(const char *cb_username, enum irc_command_callback_event event, const char *cmd, const char *channel, const char *hostmask, const char *username, const char *data)
810829
{
811830
struct bouncer_channel *bc;
@@ -851,6 +870,10 @@ static void command_cb(const char *cb_username, enum irc_command_callback_event
851870
/* The bouncer client is active for this user, but this channel is not being watched. */
852871
bbs_debug(7, "Ignoring, no bouncer channel for %s:%s\n", cb_username, channel);
853872
} else {
873+
if (data && user_mentioned(cb_username, data)) {
874+
/* If we were mentioned in the message, then flush via email ~immediately if needed */
875+
bc->user_mentioned = 1;
876+
}
854877
/* We only log if the bouncer is actually enabled.
855878
* i.e. if the user is in the channel, we don't. */
856879
if (bc->fp) {
@@ -1014,6 +1037,7 @@ static int join_leave(const char *username, const char *channel, int is_join)
10141037
bbs_assert(bc->fp == NULL); /* The log file should already be closed. */
10151038
if (bc->interactive) {
10161039
interactive_flush(bu, bc->channel); /* If interactive digest enabled, flush any messages for this channel now */
1040+
bc->user_mentioned = 0;
10171041
}
10181042

10191043
bbs_mutex_unlock(&bc->bu->lock);
@@ -1093,6 +1117,7 @@ static int load_config(const char *filename, unsigned int userid)
10931117
bbs_config_val_set_int(cfg, "general", "email_digest_freq", &email_digest_freq);
10941118
if (email_digest_freq <= 0) {
10951119
interactive = 1; /* At least one or the other needs to be enabled */
1120+
email_digest_freq = 0; /* Negative isn't valid for the PM digest frequency, so disable */
10961121
}
10971122

10981123
RWLIST_WRLOCK(&bouncer_users);

0 commit comments

Comments
 (0)