We need to create a prototype of a service. The service to need to emulate sending of messages to popular messengers (Viber, Telegram, WhatsApp).
The app should be able to do the following:
- take messages though its API and send to messengers (with user identifier);
- be able to schedule sending on specific date and time;
- if delivery failed - re-send it N times;
- no possibility of a message sent more than once to a single recipient;
- ability to send the same message to different recipients in just one incoming api request;
- Sidekiq is used to queue and send requests in background (also allows scheduling). While Rails API part is free to take new requests.
- Redis is used by Sidekiq to store all of its job and operational data.
- Posgtres is used to have historical requests' data in persistent storage.
- Grape allows for easier and faster of API making, validation of incoming requests.
- AASM is for taking advantage of finite state machine pattern. Allows dynamically change request statuses and persist it in database.
- httparty allows to make requests to api stubs. This way stubs emulate behaviour of a fake live service.
Make sure you have the latest stable ruby version which is currently for this project - 2.7.0
In addition, you need to install Redis (currently it's redis-5.0.7 used). Redis is used by background worker Sidekiq.
Go to the project's directory in your command line bundle install
or simply bundle
.
Find database.yml.sample and configure your own database.yml out of it.
Then run:
bundle exec rails db:create && bundle exec rails db:migrate
Run the following to start Redis:
redis-server
Launch Rails app:
bundle exec rails s
Launch Sidekiq:
bundle exec sidekiq -C ./config/sidekiq.yml
To send requests to API you can use Postman's desktop app.
To see what is going on with requests you can go to http://localhost:3000/sidekiq
(the 'Live poll' button can be handy too).
Request fields
Parameter | Type | Required? |
---|---|---|
message | string | yes |
send_to | array | yes |
schedule_at | array | no |
messenger_type | string | yes |
phone_number | string | yes |
JSON body example:
{
"message": "Some message",
"send_to": [
{
"messenger_type": "viber",
"phone_number": "79991234567891"
},
{
"messenger_type": "whatsapp",
"phone_number": "79998976543212"
}
]
}
or with schedule_at
option:
{
"message": "Some message",
"schedule_at": "2020-02-02 21:33:57.917883 +0300",
"send_to": [
{
"messenger_type": "viber",
"phone_number": "79991234567891"
}
]
}
Note: 20% of the time messengers' stubs will return error which is on purpose. It emulates the case when a service is unavailable so request can be retried again but no more than 4 times (set by default).