Adding member via @tryghost/admin-api does not send subscribe or signup email

I posted this issue on the TryGhost/Ghost GitHub repository, but I figured I would repost here to get some visibility.

I think I have found a bug in the way that Ghost is processing the api.members.add function from @tryghost/admin-api, which would mean that the members api itself is the source of the bug.

Copy / Paste from GitHub:

I am using Ghost as a Headless CMS with a NextJS front-end. I have been using @tryghost/admin-api to build out UI to allow readers to subscribe to the site using the members api. Unfortunately the members api is undocumented, though I have been able to navigate the repositories to string this together:

import GhostAdminApi from '@tryghost/admin-api'

const api = new GhostAdminApi({/* config */})
const member = { email: 'foo@bar.com' }
const options = { send_email: true, email_type: 'subscribe' }

// ...

await api.members.add(member, options)

This gets me 90% of the way there. Triggering the above code will fire off a POST request to:

/ghost/api/v3/admin/members/?send_email=true&email_type=subscribe

And because I am also supplying the send_email and email_type options, I expect to have an email sent to the reader, and the content of that email to be the subscribe.js email template. Unfortunately, every request I make generates a signin.js email template only.

I’ve done some digging on this and have managed to (I think) find the flow of logic that leads to a potential problem:

  1. Call api.members.add from @tryghost/admin-api
  2. This triggers a handler function to process the request
  3. Because send_email: true is supplied as a request option, the membersService.api.sendEmailWithMagicLink function is executed. It receives the email of the newly added member and the email_type (renamed to requestType)
  4. This conditional passes since the options.forceEmailType argument is not supplied, and is defaulting to false
  5. This conditional passes since a member was generated a few steps prior

Now I don’t have full context of Ghost’s services, but it would seem that in order for the admin-api to properly allow for other email templates to be utilized other than 'signin', this execution site of sendEmailWithMagicLink needs to “force” the email type. If it passed in options.forceEmailType: true, the email_type option to the request would be respected.

To Reproduce

  1. Call the api.members.add function from @tryghost/admin-api with an email to add and the options { email_type: 'subscribe', send_email: true }
  2. Notice that the email you receive is the 'signin' email

Technical details:

  • Ghost Version: 4.10.2
  • Node Version: 12.18.3
  • Browser/OS: Chrome
  • Database: default Ghost DB (not sure)