Download

Sending email?

Hi,

I have a pretty noob question, how do I send an email from my game? I imagine this is something that cannot be accomplished without external tools, so I guess I can’t use Blueprints, that’s why I’m asking here. I tried searching for solution online, but I couldn’t find any.

My goal is to allow the user to send an email message from a certain email address to any email address.

Would it be really complicated to achieve this? I have some experience with C++, but I am definitely not a programmer, so i would appreciate any ideas/guidelines regarding this. How do I get started with it? What plugins/libraries do I have to use?

Thanks.

C++ Standalone EMail application. Though, I would like to know, what use case do you have? In most cases you would want seperate servers to handle EMails and not instances of your game and thus your game-servers.


#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <iostream.h>
#include <windows.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

// Insist on at least Winsock v1.1
const VERSION_MAJOR = 1;
const VERSION_MINOR = 1;

#define CRLF "
"                 // carriage-return/line feed pair

void ShowUsage(void)
{
  cout << "Usage: SENDMAIL mailserv to_addr from_addr messagefile" << endl
       << "Example: SENDMAIL smtp.myisp.com rcvr@elsewhere.com my_id@mydomain.com message.txt" << endl;

  exit(1);
}

// Basic error checking for send() and recv() functions
void Check(int iStatus, char *szFunction)
{
  if((iStatus != SOCKET_ERROR) && (iStatus))
    return;

  cerr << "Error during call to " << szFunction << ": " << iStatus << " - " << GetLastError() << endl;
}

int main(int argc, char *argv])
{
  int         iProtocolPort        = 0;
  char        szSmtpServerName[64] = "";
  char        szToAddr[64]         = "";
  char        szFromAddr[64]       = "";
  char        szBuffer[4096]       = "";
  char        szLine[255]          = "";
  char        szMsgLine[255]       = "";
  SOCKET      hServer;
  WSADATA     WSData;
  LPHOSTENT   lpHostEntry;
  LPSERVENT   lpServEntry;
  SOCKADDR_IN SockAddr;

  // Check for four command-line args
  if(argc != 5)
    ShowUsage();

  // Load command-line args
  lstrcpy(szSmtpServerName, argv[1]);
  lstrcpy(szToAddr, argv[2]);
  lstrcpy(szFromAddr, argv[3]);

  // Create input stream for reading email message file
  ifstream MsgFile(argv[4]);

  // Attempt to intialize WinSock (1.1 or later)
  if(WSAStartup(MAKEWORD(VERSION_MAJOR, VERSION_MINOR), &WSData))
  {
    cout << "Cannot find Winsock v" << VERSION_MAJOR << "." << VERSION_MINOR << " or later!" << endl;

    return 1;
  }

  // Lookup email server's IP address.
  lpHostEntry = gethostbyname(szSmtpServerName);
  if(!lpHostEntry)
  {
    cout << "Cannot find SMTP mail server " << szSmtpServerName << endl;

    return 1;
  }

  // Create a TCP/IP socket, no specific protocol
  hServer = socket(PF_INET, SOCK_STREAM, 0);
  if(hServer == INVALID_SOCKET)
  {
    cout << "Cannot open mail server socket" << endl;

    return 1;
  }

  // Get the mail service port
  lpServEntry = getservbyname("mail", 0);

  // Use the SMTP default port if no other port is specified
  if(!lpServEntry)
    iProtocolPort = htons(IPPORT_SMTP);
  else
    iProtocolPort = lpServEntry->s_port;

  // Setup a Socket Address structure
  SockAddr.sin_family = AF_INET;
  SockAddr.sin_port   = iProtocolPort;
  SockAddr.sin_addr   = *((LPIN_ADDR)*lpHostEntry->h_addr_list);

  // Connect the Socket
  if(connect(hServer, (PSOCKADDR) &SockAddr, sizeof(SockAddr)))
  {
    cout << "Error connecting to Server socket" << endl;

    return 1;
  }

  // Receive initial response from SMTP server
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() Reply");

  // Send HELO server.com
  sprintf(szMsgLine, "HELO %s%s", szSmtpServerName, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() HELO");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() HELO");

  // Send MAIL FROM: <sender@mydomain.com>
  sprintf(szMsgLine, "MAIL FROM:<%s>%s", szFromAddr, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() MAIL FROM");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() MAIL FROM");

  // Send RCPT TO: <receiver@domain.com>
  sprintf(szMsgLine, "RCPT TO:<%s>%s", szToAddr, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() RCPT TO");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() RCPT TO");

  // Send DATA
  sprintf(szMsgLine, "DATA%s", CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() DATA");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() DATA");

  // Send all lines of message body (using supplied text file)
  MsgFile.getline(szLine, sizeof(szLine));             // Get first line

  do         // for each line of message text...
  {
    sprintf(szMsgLine, "%s%s", szLine, CRLF);
    Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() message-line");
    MsgFile.getline(szLine, sizeof(szLine)); // get next line.
  } while(MsgFile.good());

  // Send blank line and a period
  sprintf(szMsgLine, "%s.%s", CRLF, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() end-message");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() end-message");

  // Send QUIT
  sprintf(szMsgLine, "QUIT%s", CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() QUIT");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() QUIT");

  // Report message has been sent
  cout << "Sent " << argv[4] << " as email message to " << szToAddr << endl;

  // Close server socket and prepare to exit.
  closesocket(hServer);

  WSACleanup();

  return 0;
}

Thank you very much for your help!

Where should I use this code? Sorry, I have never done anything like this before. Could you please provide me a link or something about this topic? I did a quick google search about ‘C++ standalone email application’ but I didn’t find anything related to this.

The reason I want to send the emails from the game is to avoid any additional work (setting up servers, etc). The ‘game’ will be a software for a small company, to help them handle everyday tasks in a virtual environment. It will only be a test first, so right now I’m not concerned about security at all, I just want a really simple system that let’s the user send an email message from a pre-defined email address.

Thanks.

Sending email that will actually be delivered is actually quite tricky, because of the fight against spam, senderscores, honeypots, and all the rest.

If you want to send email on a server, you can use popen() to call the “sendmail” application and give it your email contents (assuming Linux server.) Then you can set your server/host up to use whatever hosting provider email delivery you get with your hosting plan.
If you want to send from a client, then you need to hook into the email server that the user’s ISP uses, and typically also the ISP name/password for the user.
This is, again, because most email forwarders don’t accept email from any random computer on the internet.

Finally, if you are really hell-bent on allowing people to send email, from the client, then the best option is probably to build a web service that sends email, and POST the email information to that service, to send the email. That’s almost 100% non-Unreal code at that point, except for the part that POSTs a web request to your web service.
However, if you build a web service like that, it will only be a few weeks before the spammers of the world find out about it, and start POST-ing their spam emails to your service, so you have to keep that in mind.
Best is to make the actual text of the message be hard-coded on the server, and just accept a list of email addresses in the POST request; that way spammers have less incentive to use it (but not zero, for various arcane email deliverability reasons.)

My suggestion is to be more specific about why you want to do this. Is this for a “viral invite loop?” If so, wouldn’t it be better to use an existing contact network, like Facebook, Google Plus, and Steam? Those networks have their own SDKs for dealing with messaging and invites.
Also, the mass market doesn’t use email particularly much – sending phone SMS messages is likely a better avenue if you want an invite system that works with modern human beings.

We can’t really answer your question better unless you give us more information.

Hi jwatte, thank you for your answer!

Wow, this seems much harder to implement than I initialy thought.

Okay, here is what exactly I want to do:

The users are clients, connected to a listen server. The server stores a bunch information about people (basically I built a very very primitive database system) including email addresses. On certain days of the month, I want to send an automatic email message to some of the stored email addresses. The text of the email would be composed using data from the database. Example: ‘Dear XY! You have been inactive for X days’.

About the why: currently, this process has to be done by human workforce, and it could be easily automated. My only problem is the actual act of sending the email.

I don’t know if this makes a difference, but it won’t be a ‘game’, but more like a ‘virtual office’ specialized for a company. There wouldn’t be an insane amount of emails to send, maybe 50-60 a row, once a month.

Unfortunately, I have no networking experience (except some basic Unreal networking stuff), so I hardly even understand the concerns you have raised, but that is my fault.

I really hope there is a solution to this which an incompetent human like me can accoplish, because it really would be an important part of the program.

Thanks!