There’s a lot of ways to solve this problem.
However, as an example, you could use one of the many SaaS offerings for sending emails such as
SendGrid. That way you won’t really be sending an email directly, but instead using a REST API to do it.
If you are using a traditional random number based OTP, then yes you’ll need a form of persistence, to associate the OTP to a user and probably an expiry timestamp. An alternative stateless approach would be to encode the user Id, and expiry and whatever else makes sense into a JSON object and then encode it using JWS/JWE. You can then include the encoded value into the email as a URL link to your server. The server, upon receiving the link can verify the signature and decrypt the value.
Take a look at
Nimbus JOSE for this.