# Script for sending welcome message in background

**URL:** <https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879>\
**Category:** Support\
**Created:** [January 24, 2025, 7:06pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879 "2025-01-24T19:06:19Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jacob\_Peebles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jacob_peebles/32/168161_2.png) [@Jacob\_Peebles](https://meta.discourse.org/u/Jacob_Peebles)\
**Post date:** [January 24, 2025, 7:06pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/1 "2025-01-24T19:06:19Z")

</div>

Hello,

I’m interested in sending a welcome message to our large user base as a background process, so:

- Create the message
- Queue users
- Send message to each user, one at a time, one per second until the full list is done
- Also would like to organize the send by most recent login/visit

Does anyone have any idea how to do this, or if someone can write a script to do this?

---

<div class="post-metadata">

**Author:** ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)\
**Post date:** [January 24, 2025, 7:47pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/2 "2025-01-24T19:47:23Z")

</div>

[ask.discourse.org](http://ask.discourse.org) output a good starting point, as a rails script:

```rb
MAX_MESSAGES = 1000 # Optional limit for testing
SECONDS_BETWEEN_MESSAGES = 3 # 3 second interval

Rails.logger.info "Starting bulk message script..."

# Define the content of your message
message_title = "Welcome to Our Community"
message_body = "Hello! We're so excited to have you here. Let us know if you have any questions!"

# Fetch users ordered by last seen
users = User.where(active: true)
            .where.not(staged: true) # Exclude staged users
            .order(last_seen_at: :desc)
            .limit(MAX_MESSAGES)

Rails.logger.info "Found #{users.count} active users to message."

users.each_with_index do |user, index|
  begin
    Rails.logger.info "Queuing message for #{user.username} (#{index + 1}/#{users.count})..."

    PostCreator.create!(
      Discourse.system_user,
      title: message_title,
      raw: message_body,
      archetype: Archetype.private_message,
      target_usernames: user.username,
      skip_validations: true
    )

    Rails.logger.info "Message successfully queued for #{user.username}."

    # Wait for the specified interval before processing the next user
    sleep(SECONDS_BETWEEN_MESSAGES)
  rescue => e
    Rails.logger.error "Failed to send message to #{user.username}: #{e.message}"
  end
end

Rails.logger.info "Bulk message script completed!"

```

I didn’t do any modification, and the user `system` sent the MP to all my users in my test instance:

 ![The image shows a messaging system with an inbox section containing a single email thread labeled "Welcome to Our Community" with multiple perspective icons and timestamps. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/0/5/5/055c475da65737f08cb36a423d8e17e3d074a96c.png)  
 ![The image is a screenshot of a community welcome message along with an option to add or remove a camera overlay filter, with 1 view and a timestamp of 3 minutes. (Captioned by AI)](https://global.discourse-cdn.com/meta/original/4X/4/7/1/47133e4ab62be7e5df4485ab787fdf1a4ea56081.png)

How many users do you have?

---

<div class="post-metadata">

**Author:** ![Jacob\_Peebles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jacob_peebles/32/168161_2.png) [@Jacob\_Peebles](https://meta.discourse.org/u/Jacob_Peebles)\
**Post date:** [January 24, 2025, 10:04pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/3 "2025-01-24T22:04:58Z")

</div>

@Canapin first that’s an amazing handle…but your response is even more amazing! This is really right along the lines of what we want to do. Some more detail.

We have 3.5 million users. We do not plan to send to all of them at once, the idea would be to run this script, maybe for batches of 10k, then stop for a few days, see what kinda of activity we have, check email reputation, and then start again, and so on.

We would like to send this though from an admin with a profile rather than ‘system’, I assume that’s possible?

Again, thanks so much, very very helpful.

---

<div class="post-metadata">

**Author:** ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)\
**Post date:** [January 24, 2025, 10:19pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/4 "2025-01-24T22:19:40Z")

</div>

> [@Jacob\_Peebles](#):
>
> We would like to send this though from an admin with a profile rather than ‘system’, I assume that’s possible?

~~Yes, just replace `system` with the desired username in the script.~~  
Sorry, I skimmed the code, there is no `system` to replace, so it must be done another way.

You’ll probably want to use a session manager like [screen](https://en.wikipedia.org/wiki/GNU_Screen) or [tmux](https://en.wikipedia.org/wiki/Tmux) so your script can run in the background.

I assume you’ll also want to be able stop the script when desired and restart it later from the user it stopped at.

Since I’m not a programmer (I mean, besides printing `hello world`…), I’ll let others give advice on how to set up this feature properly, as well as safely managing the sending to millions of users 😄

---

<div class="post-metadata">

**Author:** ![Jacob\_Peebles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jacob_peebles/32/168161_2.png) [@Jacob\_Peebles](https://meta.discourse.org/u/Jacob_Peebles)\
**Post date:** [January 24, 2025, 10:31pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/5 "2025-01-24T22:31:52Z")

</div>

@Canapin All sensible, and thanks. Yes I am thinking there is a way to just do some sort of count of records the system would run through, so basically it would just stop itself, but understood on the other options.

If anyone else has any ideas on how to make this more automated (run for batches of 10k users for example) that would be great.

---

<div class="post-metadata">

**Author:** ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)\
**Post date:** [January 24, 2025, 10:37pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/6 "2025-01-24T22:37:15Z")

</div>

> [@Jacob\_Peebles](#):
>
> Yes I am thinking there is a way to just do some sort of count of records the system would run through, so basically it would just stop itself

Yeah. If I were to create this kind of script, I’d set up something that would allow me to restart from the last user in case the script is forcibly interrupted by something (server restart, crash…, etc.).

---

<div class="post-metadata">

**Author:** ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)\
**Post date:** [January 24, 2025, 10:46pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/7 "2025-01-24T22:46:28Z")

</div>

Here’s the updated script with the sender username:

```rb
MAX_MESSAGES = 1000 # Optional limit for testing
SECONDS_BETWEEN_MESSAGES = 3 # 3 second interval
SENDER_USERNAME = "coco"

message_sender = User.find_by(username: SENDER_USERNAME)

if message_sender.nil?
  Rails.logger.error "Sender user '#{message_sender_username}' not found!"
  exit
end

Rails.logger.info "Starting bulk message script..."

# Define the content of your message
message_title = "Welcome to Our Community"
message_body = "Hello! We're so excited to have you here. Let us know if you have any questions!"

# Fetch users ordered by last seen
users = User.where(active: true)
            .where.not(staged: true) # Exclude staged users
            .order(last_seen_at: :desc)
            .limit(MAX_MESSAGES)

Rails.logger.info "Found #{users.count} active users to message."

users.each_with_index do |user, index|
  begin
    Rails.logger.info "Queuing message for #{user.username} (#{index + 1}/#{users.count})..."

    PostCreator.create!(
      message_sender,
      title: message_title,
      raw: message_body,
      archetype: Archetype.private_message,
      target_usernames: user.username,
      skip_validations: true
    )

    Rails.logger.info "Message successfully queued for #{user.username}."

    # Wait for the specified interval before processing the next user
    sleep(SECONDS_BETWEEN_MESSAGES)
  rescue => e
    Rails.logger.error "Failed to send message to #{user.username}: #{e.message}"
  end
end

Rails.logger.info "Bulk message script completed!"

```

---

<div class="post-metadata">

**Author:** ![Jacob\_Peebles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jacob_peebles/32/168161_2.png) [@Jacob\_Peebles](https://meta.discourse.org/u/Jacob_Peebles)\
**Post date:** [January 24, 2025, 10:58pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/8 "2025-01-24T22:58:43Z")

</div>

That is bonus @Canapin - we will run this likely tomorrow, if we adjust further we will post back here with updates…

CC: @Abdelrahman_MoHamed

---

<div class="post-metadata">

**Author:** ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)\
**Post date:** [January 25, 2025, 7:02am UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/9 "2025-01-25T07:02:08Z")

</div>

> [@Jacob\_Peebles](#):
>
> I assume that’s possible?

Likely, you’ll need to edit this line:

> [@Canapin](#):
>
> `Discourse.system_user`

---

<div class="post-metadata">

**Author:** ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)\
**Post date:** [January 25, 2025, 12:21pm UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/10 "2025-01-25T12:21:10Z")

</div>

> [@NateDhaliwal](#):
>
> Likely, you’ll need to edit this line:
> 
> > [@Canapin](#):
> >
> > `Discourse.system_user`

My last reply already contains the needed changes.

---

<div class="post-metadata">

**Author:** ![Jacob\_Peebles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jacob_peebles/32/168161_2.png) [@Jacob\_Peebles](https://meta.discourse.org/u/Jacob_Peebles)\
**Post date:** [January 27, 2025, 2:36am UTC](https://meta.discourse.org/t/script-for-sending-welcome-message-in-background/348879/11 "2025-01-27T02:36:12Z")

</div>

Another question here. Does anyone have any idea how to keep track of where the script is in the process? For example we send 10k emails and stop. Then want to start again, how would we know which record to start with?
