Medusa is an open source headless commerce platform. It is an alternative to Shopify, especially for developers who want more customization and control over their ecommerce websites.
Medusa has organized a hackathon to run through October 2022. You can win awesome prizes by building ecommerce projects using Medusa. You can learn more about it by visiting this page: Medusa Hackathon sign-up: Win Merch and Prizes up to $1,500 During Hacktoberfest.
In this tutorial, you’ll see a submission example for the hackathon. You’ll learn how to use Medusa’s customization capabilities to set up Discord as the notification provider. A message will be sent to the Discord server when a new order is placed.
You can find the code for this tutorial in this GitHub repository.
Prerequisites
Ensure these tools are installed on your machine:
- NodeJS: It is a JavaScript runtime build. You need to have at least v14 of NodeJS to run commands for installing packages and the Medusa server.
- Git: It is an open source version control system. Medusa uses Git behind the scenes while creating a Medusa project.
- Medusa CLI: It will be used while running the Medusa server on a local machine. Install the CLI by running the command below after installing NodeJS:
npm install @medusajs/medusa-cli -g
- Redis: It is an in-memory data structure store and message broker. Medusa uses Redis as the event queue in the server.
Install Medusa
The process of installing Medusa is quite simple; you just need to run a single command on the terminal. Run the below command to start installing Medusa:
npx create-medusa-app
After running the command, you need to enter the name of the project. By default, it’s my-medusa-store
. Hit enter once you choose the name for your project.
Now, you need to choose the Medusa starter. Choose the medusa-starter-default
.
After this, you need to choose the storefront server. You have options such as Next.js starter, Gatsby starter, and others. Choose a starter that you are comfortable with; I chose the Next.js starter
.
After choosing all this, the installation process will move forward. All the necessary dependencies for your project will be installed. After completion of the installation, you will have these three directories inside the my-medusa-store
:
- storefront: This is the frontend of your store, which is created with the framework you chose during the installation process.
- backend: This is where all the magic happens; it has the code for your Medusa server.
- admin: It is the place for the seller. It helps in managing the products, offers, payments, and other seller-related features. It is made in Gatsby. You need not change anything in the admin codebase.
Configure Redis
Redis runs locally and we need to add the URL of the server to the project. Go to backend/medusa-config.js
and add redis_url: REDIS_URL
into the projectConfig
. By default, REDIS_URL
is set to redis://localhost:6379
:
module.exports = {
projectConfig: {
//...
redis_url: REDIS_URL // Redis URL
},
plugins,
};
After all this, the setup is now done. Now, it's time to set up the webhooks in our Discord server.
Create Discord Webhook
Discord webhook is a way of sending messages from a third-party integration or application to the Discord server. A webhook is like a member of the server with a name and profile picture. This webhook will post messages coming from the other application.
Let’s set up the Webhook on our server.
Click on your server name at the top-left corner, then choose server settings. In the server settings, click on the Integration
tab from the left panel. The integration panel lets you manage webhooks and bots of your server.
Click on Create Webhook to create a random webhook.
You can edit it to display the profile pic, name, and channel in which messages will be posted. After editing the webhook, click on Save Changes.
Here is the Order Notification
webhook that will post messages in the general channel.
At the bottom of the webhook, you can see the Copy Webhook URL
button. Click on it and copy the URL of the created webhook. Now go to backend/.env/
and add the URL as the environment variable:
DISCORD_WEBHOOK_URL="discord_webhook_url"
Implement Discord Notification Provider
Let’s first understand how the notification provider works in Medusa. Whenever an event occurs in the Medusa server, such as a product added to the cart or an order placed, the event is passed into the event bus and directed to the notification plugin.
First, let’s create the notification provider that will have the discord-notification
as an identifier and run when someone places an order.
Go to /backend/src/services
and create a file with thediscord.js
name. Here, you’ll define the function to run when someone places the order.
Place the following code inside the file:
import axios from 'axios';
import {NotificationService} from 'medusa-interfaces'
class DiscordNotification extends NotificationService {
static identifier = "discord-notification";
constructor({ orderService }) {
super();
this.orderService_ = orderService;
}
async sendNotification(eventName, eventData) {
if (eventName === 'order.placed') {
//retrieve order
const order = await this.orderService_.retrieve(eventData.id, {
relations: ['items']
}
)
const URL = process.env.DISCORD_WEBHOOK_URL
let content = `New Order Placed⚡\nNumber of products: ${order.items.length}`
const embeds = []
order.items.map(item => {
content += `\n\nProduct : ${item.title} \nQuantity : ${item.quantity} \nDescription:${item.description}`
embeds.push({
image: {
url: item.thumbnail
}
});
})
await axios.post(URL, {
content,
embeds
})
return {
to: URL,
data: {
content,
embeds
}
};
}}}
export default DiscordNotification;
You name the class DiscordNotification
and it extends the NotificationService
. In the constructor, you can access different services in Medusa. In this case, you access orderServices
that contains data regarding the orders.
You add an asynchronous function with the name sendNotificaiton
. At the top of the function, there is the code to verify whether the event is order.placed
or not. If it is, then, you’ll proceed further.
After that, the order ID is retrieved from eventData
and the full details of the order are retrieved using the orderService
and stored in the order
variable.
In the next step, you’ll access the webhook’s URL from the environment and store it in the URL
variable. You then initialize two variables: content
is for the text that contains information about the order and embeds
for the image of the product.
You’ll use the map function to iterate over the order items. In the map function, you are concatenating the previous string of content
with the new item's data. In embeds
, you are pushing the URL of the image. After the loop, you use Axios to send a request to the Discord webhook to send the message to the server.
In the end, an object with two properties will return: to
and data
.
-
to
contains the medium of notification, which is Discord in our case. Therefore, the URL of the webhook is given. -
data
contains the message that was sent to Discord.
This will create a notification record in Medusa’s database.
You then must subscribe to the order.placed
event with a subscriber. For this, create a subscriber that calls the notificationService.subscribe
function.
To create a subscriber, go to the /backend/src/subscribers
directory and create a file with thediscord.js
name with the following content:
class DiscordNotification {
constructor({ notificationService }) {
// Subscribe to order.placed events
notificationService.subscribe("order.placed", "discord-notification");
}
}
export default DiscordNotification;
The subscriber calls notificationService.subscribe
in the constructor. It takes two arguments: the first is the name of the event and the second is the name of the identifier. The notification provider that has the discord-notification
identifier is subscribed to the order.placed
event.
Test the Integration
The project has been completed and it’s time to see it work live.
Run the Environment
First, run the Medusa server, storefront, and Redis server.
For Backend:
Go to backend/
and run the Medusa server with the below command:
npm run start
For Storefront:
Change to the storefront
directory and add the command below to run Medusa’s storefront at localhost:8000
by default:
npm run dev
Place an Order
If your storefront runs well, you will be able to see the storefront on the localhost:8000
. Select the product and click on checkout from the cart. Now, fill in the shipping details. The details need not be accurate as you are only testing. Select the fake delivery options and payment will be already completed for testing.
After filling in the details, click on the Checkout
button on the right-side panel. If everything goes well, your order will be placed.
The notification regarding the order will be sent to your Discord server.
Conclusion
Using Medusa’s plugin system, you can integrate any third-party service and tool for different purposes such as Notifications, Payment, or CMS. You can also publish your plugins for the community to use and benefit from.
If you’re interested in seeing more Medusa plugins, check out the Integrations page. You can also learn more about plugins in the Medusa documentation.
Should you have any issues or questions related to Medusa, then feel free to reach out to the Medusa team via Discord.
Top comments (6)
If it's in my Discord, then I can def see it 👀
Easily you can do that with webhook URL
Super cool tutorial and contribution to the Hackathon 🚀
Thanks Nick👍
Thank you for writing this tutorial! 🙏🏻
My pleasure and thanks to you too for feedbacks🔥