Publi

Utilizando la API de MailRelay para enviar correo masivo a nuestra manera.


A pesar del creciente número de canales de comunicación que tenemos a nuestro alcance, el correo electrónico nunca pasa de moda. Prácticamente todos los usuarios de la red tenemos una o más direcciones de e-mail. Y, seguro que más de uno consulta varias veces al día su correo, o está pendiente de la más mínima notificación para mirarlo. No cabe duda que es una potente herramienta de marketing hoy en día, tanto para mantener informados a nuestros clientes como para captarlos o invitarlos a realizar una compra. Es más, si gestionamos un servicio web, seguramente enviaremos mensajes por correo electrónico a nuestros usuarios cuando se registran o cuando debemos notificarles algo.

Aunque a mí me gusta montarme todo tipo de servicios por mí mismo, el envío de correo suele ser un tema delicado que, cuando se vuelve masivo prefiero contratar un servicio que lo haga por mí. Entre otros motivos porque,

  • El servicio de correo es algo un poco pesado, y si hemos montado algo pequeño, el momento del envío, imaginemos, a 1000 personas, puede llegar a colgarnos el servidor. Si tenemos un servidor de correo dedicado para el correo no tendremos problemas, pero normalmente los canales estándar de envío de correo buscarán virus en los e-mails, pasarán algunos filtros anti spam y tendrán que realizar muchas conexiones y si tenemos nuestro servicio de correo en el mismo sitio, éste puede verse perjudicado también..
  • Al mismo tiempo que se envía mucha información, puede recibirse también mucha información. Es muy común que algún servidor de destino no esté disponible en un momento determinado y tengamos que reintentar el envío, puede que tenga un sistema de listas grises, por lo que los correos sean rechazados temporalmente y sean aceptados después de algún intento; y puede que haya correos que no lleguen por lo que se enviarán los famosos mensajes del subsistema de correo (Mail Subsystem) explicando las posibles razones del fallo. Todo esto genera un tráfico que es inofensivo en el caso de 1, 2, o 10 mensajes, pero puede saturarnos si enviamos 1000 o 10000 mensajes.
  • Los servidores se cabrean. Y es que si enviamos muchos mensajes a un mismo servidor de correo, éste verá que todos vienen de la misma dirección IP y algunos empiezan a rechazar los mensajes automáticamente y, por lo tanto no llegarán.
  • Cuando tenemos un volumen pequeño de envío, de unos pocos miles de correos, el hecho de que un pequeño porcentaje de personas marque como correo no deseado nuestros mensajes es terrible. Y es que, aunque hayan escogido una opción en tu web para ser notificados, aunque les envíes una felicitación navideña o aunque te hayan pedido que les envíes un mensaje, siempre habrá gente que lo marque como no deseado. Al menos ha sido mi experiencia desde hace muchos años. Y basta que un servidor grande de correo crea que somos malos, para que no llegue ningún mensaje y nos cueste mucho trabajo hacer que vuelvan a confiar en nosotros.
  • Tracking de mensajes y gestión de suscripciones. Podemos implementar un servicio de tracking de mensajes nosotros mismos, no es difícil, pero puede llegar a generar mucho tráfico y engordaría. Esto nos daría información de quién abre los mensajes. Otro tema es la suscripción, ya que debemos incluir un enlace para que alguien se pueda dar de baja de nuestra lista de correo. Muchos servicios de envío de mailing masivo gestionan estas cosas automáticamente.

Analizar nuestras necesidades

¿Tengo que enviar muchos mensajes? Si, por ejemplo nuestra web genera poco tráfico de mensajes podemos usar nuestro servidor de correo para enviarlos. ¿Cuánto es poco? Depende de las dimensiones de nuestros servidores, pero en un pequeño servidor en un VPS no me gustaría enviar más de 500 mensajes por día y sobre todo si las direcciones pertenecen al mismo dominio. Por ejemplo, si nuestros destinatarios suelen ser de GMail o de Outlook. Eso sí, si nuestro servicio web está en un servidor compartido reduciría drásticamente ese número a unos 200 o así. Tenemos que tener en cuenta que los proveedores de hosting se toman muy en serio el tema del SPAM, tanto en el caso de los compartidos como de los VPS y algunos dedicados. Así que, si detectan tráfico masivo de este tipo pueden desactivar el servicio de correo, tanto por mantener la reputación de sus direcciones IP como para no saturar los servicios que ofrecen.

Otra de las preguntas clave sería la región para la que vamos a enviar nuestros mensajes. Ya que vamos a utilizar un servicio externo para enviar los mensajes, por un lado, nos interesa que los servidores estén lo más cerca posible del servidor de destino, aunque por ejemplo si los destinatarios son ciudadanos de la Unión Europea, debemos almacenar sus datos en servidores situados en Europa. Y esto se puede extender a contratos con posibles clientes que soliciten que los mensajes se envíen desde servidores en Europa. Es más, en ocasiones nuestros servicios pueden estar en varios lugares, incluyendo EEUU y puede que tengamos un problema.

Si finalmente optamos por enviar los mensajes desde un proveedor externo, debemos ver la forma de comunicarnos con él. En algunos casos puede que nos interese utilizar el mismo protocolo SMTP para el envío, o en otros casos puede que nos sea más útil utilizar una API HTTP (SOAP, REST,…) para comunicarnos con él.

Incluso una vez hemos optado por utilizar un software mailing o una plataforma de envío de correo, puede que nos valga sólo con las herramientas web que nos brindan.

Empresas de envío de correo

Existen muchas empresas que nos permitirán enviar mensajes desde su infraestructura. Hoy centraré el post en MailRelay. Es una empresa que envía correos desde Europa, y nos permite enviar hasta 75000 correos de manera gratuita. Y, aunque nos permite crear boletines de forma interactiva desde el panel de control de la web a mí me gusta curiosear y exprimir estos servicios para cumplir mis necesidades.

A la hora de enviar correos masivos puedo crear scripts que realicen envíos extrayendo datos directamente de mi base de datos, sin necesidad de crear importaciones en el servicio de un tercero, e incluso, si son mails de notificaciones, no pertenecientes a una lista de mailing puedo crear el e-mail directamente en mi servidor con un contenido personalizado y enviarlo a través del servicio de MailRelay.

Además, disponen de servicio SMTP, por lo que podemos configurar nuestro ordenador de casa o nuestro servidor para enviar los correos a través del servidor SMTP de MailRelay y ellos se pelearán con el envío, con los reintentos, rebotes, etc.

Obtener clave API

Una vez nos registramos en MailRelay, y verificar nuestra dirección de correo (preferiblemente para nuestro dominio), nos darán una URL para conectar con nuestro servicio que puede ser http://midominio.ip-zone.com (podemos utilizar HTTPS aunque ellos no nos lo den así), debemos crear una clave API. Para ello, debemos ir a Configuración / Acceso a la API / Generar nueva clave API:

A partir de ahí podemos utilizar una serie de acciones a través de una API HTTP. Y, ya que la API es HTTP, podemos crear ejemplos con cURL desde Bash para realizar pruebas o scripts de envío y, no será muy dificil extenderlo a cualquier lenguaje de programación: PHP, Python, Ruby, C, C++…

Todas las llamadas a la API de MailRelay se harán con la misma dirección base. Esta dirección será https://midominio.ip-zone.com/

Usando la API de MailRelay

Para empezar a interactuar con MailRelay lo primero que tenemos que hacer es autentificarnos en el sistema. Para ello debemos enviar una petición POST a https://midominio.ip-zone.com/ccm/admin/api/version/2/, donde midominio.ip-zone.com nos lo van a mandar en un e-mail anterior. Esa API nos enviará respuestas en XML, aunque adicionalmente podemos añadir «&type=json» a la URL para recibir respuestas en JSON.

Autentificarnos en el sistema

La primera petición que tenemos que enviar para trabajar con la API de MailRelay es nuestra identificación. Para ello, enviamos una petición con los siguientes argumentos. Con esta petición obtendremos la clave API del sistema (si la tenemos anotada nos podemos saltar este paso):

  • function: doAuthentication
  • username: [el usuario que nos enviaron en el mail de confirmación]
  • password: [contraseña correspondiente a ese usuario]

Un ejemplo sería este:

curl «https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json» -d «function=doAuthentication&username=totakiapi&password=********»
{«status»:1,»data»:»******NUESTRA API KEY*******»}

Si queremos extraer ésta información desde Bash podemos hacerlo utilizando la utilidad jq:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

USERNAME="[nombre_de_usuario]"
PASSWORD="[password]"
URL="https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json"

_RESPONSE=$(curl "$URL" -d "function=doAuthentication&username=$USERNAME&password=$PASSWORD")
_STATUS=$(echo $_RESPONSE | jq '.status')
APIKEY=$(echo $_RESPONSE | jq -r '.data')

echo "Status: $_STATUS"
echo "Data: $APIKEY"

Obteniendo información de nuestra cuenta

Antes de proceder a enviar correos, necesitamos información de los buzones que tenemos configurados en nuestra cuenta. Para ello, vamos a hacer peticiones con las funciones getMailboxes y getPackages, dichas peticiones llevarán el nombre de la función y nuestra APIKEY, que como la tenemos en una variable (del ejemplo anterior) voy a utilizarla para no exponerla. Aquí podréis utilizar vuestra API KEY directamente si así lo deseáis.

curl «https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json» -d «function=getMailboxes&apiKey=$APIKEY»
{
«status»: 1,
«data»: [
{
«id»: «1»,
«mailbox_name»: «[nombre del mailbox]»,
«name»: «[mi nombre]»,
«email»: «[mi correo]»,
«check»: «0»,
«username»: null,
«password»: null,
«hostname»: null,
«imap»: «0»,
«apop»: «0»,
«delete»: «0»,
«enable»: «1»,
«confirmed»: «1»,
«internal»: «0»
}
]
}

De aquí debemos quedarnos con el «id», que será nuestro MAILBOXID. Podríamos extraerlo con:
1
2
_RESPONSE=$(curl "https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json" -d "function=getMailboxes&apiKey=$APIKEY")
MAILBOXID=$(echo $_RESPONSE | jq -r '.data[0].id')

GetPackages, obtendría los servicios que tenemos contratados y lo podríamos invocar así (en el ejemplo vemos sólo el plan gratuito, que suele ser el ID=6:

curl «https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json» -d «function=getPackages&apiKey=$APIKEY» | jq
{
«status»: 1,
«data»: [
{
«id»: «6»,
«contractId»: «1»,
«type»: «email»,
«softLimit»: «15000»,
«hardLimit»: «15000»,
«period»: «1 month»,
«startDate»: «2017-12-31»,
«description»: «Bono de emails»,
«warningDate»: «0000-00-00»,
«hardWarningDate»: «0000-00-00»,
«warningPercentage»: «90»,
«active»: «1»,
«subscribersLimit»: «3000»,
«subscribersLimitDate»: null,
«usage»: {
«startDate»: «2017-12-31 00:00:00»,
«endDate»: «1970-01-01 01:33:37»,
«totalItems»: «15000»,
«sentItems»: 0
}
}
]
}

Y de la misma manera que antes, podemos obtener el ID de la siguiente manera:
1
2
_RESPONSE=$(curl "https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json" -d "function=getPackages&apiKey=$APIKEY")
PACKAGEID=$(echo $_RESPONSE | jq -r '.data[0].id')

Envío de un correo de ejemplo

Una vez tenemos la clave API, el buzón de correo de envío y el contrato seleccionados, procedemos a enviar un e-mail. En el ejemplo he creado un programa en BASH donde pongo los valores de todas las variables deseadas, aunque APIKEY, MAILBOXID y PACKAGEID ya los tenemos de antes. Tendremos que crear un asunto de mensaje, un mensaje y un listado de direcciones y nombres de destinatarios:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

URL="https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json"
APIKEY="**********"
MAILBOXID=1
PACKAGEID=1
SUBJECT="Asundo del mensaje"
HTML="<html><body><h2>Mi primer mensaje</h2>Este es el cuerpo del mensaje</body></html>"
EMAILS_Names=("Destinatario 1" "Destinatario 2")
EMAILS_Addresses=("destinatario1@dominio.com" "destinatario2@gmail.com")

# Creamos el dato que tenemos que mandar con los destinatarios.
_EMAILSTR=""
for ndx in ${!EMAILS_Names[*]}; do _
  EMAILSTR=$(echo "$_EMAILSTR&emails[$ndx][name]=${EMAILS_Names[$ndx]}&emails[$ndx][email]=${EMAILS_Addresses[$ndx]}");
done

#Enviamos el correo
curl "$URL" -d "function=sendMail&apiKey=$APIKEY&subject=$SUBJECT&html=$HTML&mailboxFromId=$MAILBOXID&mailboxReplyId=$MAILBOXID&mailboxReportId=$MAILBOXID&packageId=$PACKAGEID&${_EMAILSTR:1}" | jq

La orden sendMail nos debe enviar también una respuesta dividida en status y data. Cuando todo va bien, status vale 1 y data vale true. Debemos comprobar esos valores para saber si el mensaje se ha enviado bien al sistema de MailRelay. Eso no garantiza que el mensaje haya llegado, sólo que ha sido enviado correctamente a MailRelay. Luego debemos comprobar que efectivamente ha llegado en los reportes de la página web o ver las estadísticas desde la propia API.

Aunque podemos enviar correos a listas completas de correo no voy a contemplarlo en este post

Recibir estadísticas desde la API

Para ver las estadísticas e información sobre los correos enviados tenemos varias funciones:
GetMailingLists: Que nos devolverá todos los mensajes que hemos enviado junto con información sobre el envío, detección de SPAM, rebotes, mensajes enviados, estado y demás. Podemos verlo así:

curl «https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json» -d «function=getMailingLists&apiKey=$APIKEY» | jq
{
«status»: 1,
«data»: [
{
«id»: «62»,
«subject»: «[Asunto del menssaje]»,
«mailbox_from_id»: «1»,
«mailbox_reply_id»: «1»,
«mailbox_report_id»: «1»,
«groups»: «7»,
«text»: «»,
«html»: «[contenido del mensaje]»,
«attachs»: «a:0:{}»,
«date»: «2017-12-30 17:56:47»,
«created»: «2017-12-30 17:56:47»,
«last_sent»: «2017-12-30 17:58:05»,
«deleted»: «0»,
«status»: «idle»,
«start_sent»: «2017-12-30 17:58:05»,
«send_date»: «2017-12-30 17:56:00»,
«subscribers_total»: 2,
«package_id»: «6»,
«id_mailing_list_folder»: «-3»,
«admin_id»: «0»,
«is_spam»: «0»,
«spam_report»: «Spam detection software, running on the system \»services.mr.ip-zone.com\»,\nhas NOT identified this incoming email as spam.  The original\nmessage has been attached to this so you can view it or label\nsimilar future email.  If you have any questions, see\nthe administrator of that system for details.\n\nContent preview:  Asunto del menssajeHola mundo te mando un mensaje tio Asunto\n   del menssaje Hola mundo te mando un mensaje tio […] \n\nContent analysis details:   (0.4 points, 5.0 required)\n\n pts rule name              description\n---- ---------------------- --------------------------------------------------\n-0.0 NO_RELAYS              Informational: message was not relayed via SMTP\n 0.0 HTML_MESSAGE           BODY: HTML included in message\n 0.3 HTML_IMAGE_ONLY_04     BODY: HTML: images with 0-400 bytes of words\n-0.0 NO_RECEIVED            Informational: message has no Received headers\n 0.0 T_REMOTE_IMAGE         Message contains an external image»,
«analytics_utm_campaign»: «»,
«auth_token»: null,
«notification_url»: null,
«campaign_id»: «7»,
«sent»: 2,
«bounced»: 0
},
…..
]
}

En esta función podremos, adicionalmente utilizar los parámetros startDate, endDate para especificar un rango de fechas con el que filtrar la lista, offset para decir por qué mailing list empezar, porque podemos tener cientos o miles de ellas y count para especificar cuántas mailing lists queremos en la salida.

Tras ello, la siguiente función interesante es getStats que podemos utilizar especificando el ID de la mailing list o no:

curl «https://mi-direccion-mailrelay.com/ccm/admin/api/version/2/&type=json» -d «function=getStats&apiKey=$APIKEY&id=62» | jq
{
«status»: 1,
«data»: {
«impressions»: 0,
«unique_impressions»: false,
«clicks»: 0,
«unique_clicks»: «0»,
«sent»: 2,
«bounced»: 0,
«reported_spam»: 0,
«delivered»: 1,
«optouts»: 0,
«forwarded»: 0,
«ignored»: 1,
«subscribers_total»: 2
}
}

Evitar que nuestros mails caigan como correo no deseado

Pero claro, los e-mails enviados pueden llegar como correo no deseado en ciertos entornos, de hecho deberían si el servidor de correo del receptor está bien configurado. Y es que los servidores no deben permitir que cualquiera envíe correos suplantando el dominio o la identidad de otra persona. Sabemos que el correo no se diseñó en un primer momento para ser seguro en ese aspecto y es muy fácil, de hecho muchos virus se aprovechan de eso, enviar correos en nombre de otra persona/empresa/entidad. Afortunadamente los sistemas antispam modernos suelen eliminar casi todos los correos de ese estilo, aunque siempre se cuela alguno.

Algunas de las medidas que se toman para, al menos se compruebe la autenticidad del dominio son los registros SPF y DKIM. Estos registros implican grosso modo que el propietario del dominio es el propietario del servidor de correo de envío. Son registros DNS que debemos añadir en nuestro dominio. El registro SPF indica qué servidores tienen permiso para enviar correos con mi dominio, especificando las direcciones IP o los nombres de dominio permitidos. El mecanismo DKIM es algo más complicado y crea una firma digital que se complementa con un registro DNS de nuestro dominio de forma que es muy rápido comprobar que el correo es legítimo, pero es muy costoso computacionalmente falsificarlo.

Así que es muy recomendable configurar este par de cosas antes de empezar a utilizar nuestra nueva plataforma de mailing.

Foto principal:
unsplash-logoKelli Stirrett

También podría interesarte....

There are 25 comments left Ir a comentario

  1. Pingback: Utilizando la API de MailRelay para enviar correo masivo a nuestra manera. | PlanetaLibre /

  2. kdetony /
    Usando Mozilla Firefox Mozilla Firefox 60.0 en Windows Windows NT

    hola que tal, buen tutorial
    una consulta, cuando ejecuto el script me sale este mensaje

    «status»: 0,
    «error»: «Please, provide at least one email.»

    He ingresado correos validos… pero aun asi me marca ese error…

    espero me puedas guiar

    sls

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 61.0 en Ubuntu Linux Ubuntu Linux

      Lo siento kdetony, ya no tengo cuenta en MailRelay para probar el código de nuevo. Desconozco si han cambiado algo en la API.

  3. 먹튀신고 /
    Usando Google Chrome Google Chrome 117.0.0.0 en Windows Windows NT

    Full and equal enjoyment of the goods, services, facilities, or accommodations in public places were expected. And of course public accommodations also included most places of education. 먹튀신고

  4. 먹튀사이트 /
    Usando Google Chrome Google Chrome 117.0.0.0 en Windows Windows NT

    Hi there, I would like to subscribe for this website to get latest updates, thus where can i do it please help out. 먹튀사이트

  5. OKBet /
    Usando Google Chrome Google Chrome 118.0.0.0 en Windows Windows NT

    Excellent to the point article and news.. Well appreciated, My sites: DOTA 2

  6. Jim /
    Usando Google Chrome Google Chrome 118.0.0.0 en Windows Windows NT

    It’s indeed important to choose the right tools and services for effective email campaigns.

  7. sulo /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Thank you for the article! I have studied about similar subjects! Unlike other submissions, however, I have a very unique impression of yours. I hope you will continue to share articles of this caliber with the public.
    five nights at freddy’s

  8. laeliaralph /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    I wanted to thank you for the time and work you put into making this paper in this message with iq test free. I really appreciate you sharing it with me because it has been very helpful to me. Many thanks for your kindness and charity.

  9. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    The adrenaline rush is real! These web slots are the epitome of excitement. สล็อตเว็บใหญ่

  10. herringbur /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    it has been very helpful to me. Many thanks for your kindness and charity. dordle

  11. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Users should share their experiences with slots breaking easily to raise awareness. เว็บสล็อตแตกง่าย

  12. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    This is exceptionally fascinating, yet it is important to tap on this connection: แหล่งรวมสล็อตทุกค่าย

  13. sheetrock contractor /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    It’s great to see the recognition of email’s enduring effectiveness in marketing.

  14. CiVault /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    It is very much specialized in sending large batches of emails, such as newsletters, or automatic transactional emails which is a traditional method to send a message to the rating loved one, but now through email or a website in this way is an easy and quick method doing now, using the free trial period we’ve seen, there are two ways to send a mass email.
    Google Maps Citations

  15. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    This is essential, however it’s important to enable you to make a beeline for it weblink: เว็บสล็อตโรม่า

  16. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    These you will then observe the most vital thing, the application gives you a site an effective critical web page: เกมป๊อกเด้งออนไลน์

  17. jsimitseo /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    I am keen on such themes so I will address page where it is cool depicted. best concierge doctor

  18. Rank Xone /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    The allure of online casinos is not just about winning money; it’s also about the social aspect. Connecting with players from around the world adds another layer of fun. 프리카지노

  19. gereay er catalá /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    Amí me pone malo el chatgt ese no se como os las apañáis los loas formaticos en España son fuertes

    https://poesiabinaria.net/2019/01/utilizar-php-desde-contenedores-docker-tanto-forma-local-produccion/#comment-95750

  20. Rank Xone /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    Casinos are where you can turn a little luck into a lot of money. 로즈카지노

  21. Beauty /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    Hi there! This is my first visit to your blog! We are a group of volunteers and starting a new initiative in a community in the same niche.
    Your blog provided us beneficial information to work on. You have done a marvellous job!

  22. Rank Xone /
    Usando Google Chrome Google Chrome 123.0.0.0 en Windows Windows NT

    Hallo guys, selamat datang di situs OKEPLAY777, pernahkah anda mendengar atau sudah bermain disini ?, Mari kita bahas sedikit tentang kelebihan situs slot online ini, sebagai situs slot gacor hari ini yang menggunakan slot server thailand terbaru gampang menang dengan winrate tertinggi di bandingkan situs lain, bermain di OKEPLAY777 memiliki experience yang berbeda pada saat mendapatkan kemenangan sensasional hanya dengan modal deposit slot dana Rp.15,000 dan menang berapapun di bayar tanpa potongan.

  23. Rank Xone /
    Usando Google Chrome Google Chrome 123.0.0.0 en Windows Windows NT

    No matter which sub-field problem you are facing, our ghostwriting service can provide you with professional, efficient and original help. assignment代写

  24. Rank Xone /
    Usando Google Chrome Google Chrome 123.0.0.0 en Windows Windows NT

    However, we cannot deny that the cost of living and education investment abroad are generally higher than at home. This also results in the relatively high price of overseas ghostwriting services. 北美代写

Leave a Reply to Anónimo Cancle Reply