mailgun / documentation Goto Github PK
View Code? Open in Web Editor NEWMailgun Documentation
Home Page: http://documentation.mailgun.com/
License: MIT License
Mailgun Documentation
Home Page: http://documentation.mailgun.com/
License: MIT License
In the User Manual, the sample code for verifying the Mailgun authentication signature uses ==
.
E.g. e306a37#diff-229131ed0af7cf80ed3a9470ec7beb4cR701
But ==
comparisons are vulnerable to timing attacks.
Is it worth mentioning to use a constant time comparison?
In Ruby, there's a secure_compare
method provided by Rack and Rails.
# Rack
Rack::Utils.secure_compare(a, b)
# Rails
ActiveSupport::SecurityUtils.secure_compare(a, b)
In Python, there's a compare_digest
function in the standard library.
import hmac
hmac.compare_digest(a, b)
Both languages also have 3rd party libraries if the reader doesn't want to use any of the above methods.
http://documentation.mailgun.com/user_manual.html#tracking-messages
o:tracking ... _____?
On the user manual and API routes pages, there's an example where a route is created with the highest priority.
Create a route of the highest priority with multiple actions:
def create_route
data = Multimap.new
data[:priority] = 1
data[:description] = "Sample route"
data[:expression] = "match_recipient('.*@samples.mailgun.org')"
data[:action] = "forward('http://myhost.com/messages/')"
data[:action] = "stop()"
RestClient.post "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
"@api.mailgun.net/v2/routes", data
end
The priority used is 1. But on the API routes page, the documentation describes the priority field as
Integer: smaller number indicates higher priority.
Higher priority routes are handled first. Defaults to 0.
So wouldn't 0 be the highest priority?
https://documentation.mailgun.com/libraries.html#php
Bellow are all the steps needed to install this library having a fresh Ubuntu installation.
Should be
Below are all the steps needed to install this library having a fresh Ubuntu installation.
https://github.com/mailgun/documentation/blob/master/source/samples/add-domain.rst
Looks like the Curl example is missing a -X POST or similar qualifier. I'll submit a PR that fixes this.
http://documentation.mailgun.com/libraries.html#python
The link for "Werkzeug/Flask" seems to be broken, thanks.
does official c# client exists or restsharp
(or httpclient
) is still the way to go?
After i put ssl certs on my VPS server ( letsencrypt ), the links inside emails stop working.
I have no idea what happend, i was searching in google the issue but every similar topics says to check is email tracking is enable, but they dosen't. Every one is puting to disable.
Is any one can help me with this? My clients send my many messages with informatin, that they cannot click in activation links inside first email after registration.
Best,
Tom
https://documentation.mailgun.com/user_manual.html#mailing-lists
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = new Mailgun('key-fe05e4e079fc3c3a80355bf87c80832b');
$domain = "mg.fourbody.com.au";
# Make the call to the client.
$result = $mgClient->sendMessage($domain, array(
'from' => 'Excited User <[email protected]>',
'to' => '[email protected], [email protected]',
'subject' => 'Hello',
'text' => 'If you wish to unsubscribe,
click http://mailgun/unsubscribe/%recipient.id%',
'recipient-variables' => '{"[email protected]": {"first":"Bob", "id":1},
"[email protected]": {"first":"Alice", "id": 2}}'
));
In the example above, Alice and Bob both will get personalized subject lines “Hey, Alice” and “Hey, Bob” and unique unsubscribe links.
shouldn't
'subject' => 'Hello',
be
'subject' => 'Hello %recipient.first%',
RestSharp is dead, should be using HttpClient instead.
Similar to PR #196, but for other languages that need a simple, standalone, constant-time secure comparison function.
secureCompare
for Ruby:
# Run a constant-time comparison against two strings to determine equality.
# Useful for performing cryptographic comparison / avoiding timing attacks.
#
# @param [String] a
# @param [String] b
# @return [Boolean]
def secureCompare(a, b)
if a.length != b.length then
return false
end
result = 0
cmp = Hash[[a.bytes, b.bytes].transpose]
cmp.each do |x, y|
result |= x ^ y
end
return result == 0
end
secureCompare
for NodeJS
var bufferEq = require('buffer-equal-constant-time');
function secureCompare(a, b) {
bufA = new Buffer(a);
bufB = new Buffer(b);
return bufferEq(bufA, bufB);
}
secureCompare
for PHP
<?php
function secureCompare($a, $b) {
$bytes_a = unpack("C*", $a);
$bytes_b = unpack("C*", $b);
$cmplen = count($bytes_a);
if ($cmplen !== count($bytes_b)) {
return false;
}
$result = 0;
// The result from unpack() is 1-indexed instead of 0-indexed.
for ($i = 1; $i <= $cmplen; $i++) {
$result |= $bytes_a[$i] ^ $bytes_b[$i];
}
return $result === 0;
}
?>
TODO:
buffer-equal-constant-time
)hmac.compare_digest
or standalone code..? -- done in #196 )hmac.Equal
or standalone code...?)Resources:
Issue: If I click the Control Panel
link, I'm directed to https://cp
.
Expected: To be redirected to the Control panel, not a broken link.
Steps to reproduce the bug:
Thanks for the sweet service, mailgun is really cool!
Would like to see an example in the documentation that shows how to use the Events API to pull a log of only dropped messages.
Since "dropped" is not a filter event, and you would need to use the event:failed and then add the severity: temporary to pull dropped messages only I think it would be helpful to have an example showing that. Bounced messages have their own API so even though an example of using Severity:Permanent would be helpful it probably isn't as necessary.
You can create Route catch_all() --> forward("smtp-relay.gmail.com:25") no ?
Hi, shouldn't the dots between the parts of the domain name in match_recipient be preceded by a backslash if these are regexps? e.g.
match_recipient("info@example\.com")
rather than
match_recipient("[email protected]")
While it's unlikely it'd match anyone else, with all the new TLDs, who knows, it might in future.
Python inline images documentation code example has an error:
add "rb" to open method in files=[("inline", open("files/test.jpg"))],
This code snippet:
def send_inline_image():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages",
auth=("api", "YOUR_API_KEY"),
files=[("inline", open("files/test.jpg"))],
data={"from": "Excited User <YOU@YOUR_DOMAIN_NAME>",
"to": "[email protected]",
"subject": "Hello",
"text": "Testing some Mailgun awesomness!",
"html": '<html>Inline image here: <img src="cid:test.jpg"></html>'})
should change to:
def send_inline_image():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages",
auth=("api", "YOUR_API_KEY"),
files=[("inline", open("files/test.jpg","rb"))],
data={"from": "Excited User <YOU@YOUR_DOMAIN_NAME>",
"to": "[email protected]",
"subject": "Hello",
"text": "Testing some Mailgun awesomness!",
"html": '<html>Inline image here: <img src="cid:test.jpg"></html>'})
Would be really great to replace the old Jersey 1 examples with Jersey 2. I'd be surprised if any new projects would be on Jersey 1.
In the PHP code example of the securing webhooks section, the timestamp freshness is calculated assuming that the receiving server's local time will be greater than the webhook's timestamp value. This might not be true, and therefore arbitrarily future timestamps would be considered for validation instead of immediately discarded.
(See PR)
Please forgive my ignorance.. I tried without success to create a simple PR to include my recommended addition to documentation to help wayward developers after me to not burn an hour and a half the way I just did:
bronius@c2c6323#diff-229131ed0af7cf80ed3a9470ec7beb4c
Just a note that when operating in testmode, there's no way to know whether the recipient-variables and template recipient variable placeholders are translating as expected.
Thanks!
-Bronius
It's not a big deal, but could cause confusion.
The URL that appears in http://documentation.mailgun.com/api-sending.html#retrieving-stored-messages looks like store(notify="http:mydomain.com/callback")
and should be store(notify="http://mydomain.com/callback")
.
I noticed that you use URLs like 'http' for the examples. Shouldn't be better practice write the examples using 'https'?
Hi,
Just wanted to point out that the Java Library version on the Libraries page is outdated.
I see that all other Java examples are using Unirest.
In documentation you recommend to use gem multimap but this gem is not been maintained: https://github.com/josh/multimap --> last commit was 5 years ago!
Not sure if it's only my environment (rails '3.2.14' and ruby 2.0.0) but it doesn't seems to work for me.
As a work around, you could suggest to simply use RestClient, e.g.
def create_route
RestClient.post "https://api:key-SECRET_KEY"\
"@api.mailgun.net/v2/routes",
:priority => 0,
:description => "Sample route",
:expression => "match_recipient(\"[email protected]\")",
:action => "forward(\"http://myhost.com/messages/\")"
end
URL: http://documentation.mailgun.com/api-mailinglists.html#examples
Screenshot
the example written in GO is showing broken in PHP, it shouldnt show at all, and also it's just broken!
Even tho it's specified in the docs. I think this is some remains for the removed delete functionality.
(fbbf927)
Docs for "message-url" remains here.
https://documentation.mailgun.com/user_manual.html#storing-and-retrieving-messages
I saw the following curl request after I signed up.
curl -s --user 'api:key-BLAH BLAH' \
https://api.mailgun.net/v3/sandbox-whatever.mailgun.org/messages \
-F from='Mailgun Sandbox <[email protected]>' \
-F to='Test Test <[email protected]>'\
-F subject='Hello Test Test' \
-F text='Congratulations Test Test, you just sent an email with Mailgun! You are truly awesome!
However the last line is missing the ending single quote. I can send a pull request but it seems like it's not in this repo.
The events documentation in the events structure page says this:
Event id. It is guaranteed to be unique within a day. It can be used to distinguish events that have already been retrieved when requests with overlapping time ranges are made.
but none of the example responses include an id key.
What happens when requests fail? What does the message body look like?
The PHP example under "Get a single domain" on the documentation, http://documentation.mailgun.com/api-domains.html#example needs to be updated to be similar to :
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
$domain = 'samples.mailgun.org';
# Issue the call to the client.
$result = $mgClient->get("domains/$domains");
Hi!
At least by comparing with the cURL format, I believe that the java example is missing the following line:
form.field("html", "<html>HTML version of the body</html>");
on the
Sending a message with HTML and text parts. This example also attaches two files to the message:
example
Using the @-method to pass files to cURL was deprecated in PHP 5.5.0. Now you have to use CURLFile.
http://www.php.net/manual/en/class.curlfile.php
Reference: 58321
The documentation for sending booleans uses yes/no while the following examples use True/False.
For example, setting o:tracking
o:tracking
Toggles tracking on a per-message basis, see Tracking Messages for details. Pass yes or no.
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
-F from='Sender Bob <sbob@YOUR_DOMAIN_NAME>' \
-F to='[email protected]' \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!' \
-F o:tracking=False
Mailgun registers its domains and IP addresses with most ESPs' Feedback Loop programs.
Some ESPs perform Feedback Loop participation by domain, rather than IP address. We need to have a tutorial to explain what settings are required for these feedback loop programs to allow Mailgun to consume the complaint.
Replace first paragraph of the Introduction with the following:
"Mailgun is a programmable email platform. It allows your application to
become a fully featured email server. Send, receive and track messages with ease
using your favorite programming language."
Just made a pull request for this.
The quickstart docs for tracking are showing every code sample and the language selector is not working.
http://documentation.mailgun.com/quickstart-events.html#how-to-start-tracking-email-events
The docs now have the names and descriptions of all the fields for the JSON body of a POST request for an inbound mail forward rule, but I'd love to see a dump of the HTTP headers you will send as well as a complete JSON message body.
All the examples shows plain text examples, what about showing an simple example with html?
The instructions for consuming custom variables on https://documentation.mailgun.com/user_manual.html#tracking-bounces implies that the "custom variables"
form field is consumed. This is not correct. Add an example to show the correct behavior.
For the email validation API, the address/validate
endpoint doesn't support validating email with display names, but the address/parse
endpoint does support it.
(ref: http://documentation.mailgun.com/api-email-validation.html#example)
The example is a bit misleading, in particular, because the example response shows a display_name
part, which would imply that the address/validate
would support validating display names.
Based on this it was a change to drop support, which should be reflected in documentation and made clear that the endpoint does not validate display name.
In the Tracking Failures section, there's a list of "reasons" that you could receive.
Bounce
indicates a hard or soft bounce.
ESPBlock
indicates a soft bounce and the maximum number of attempts was reached.
...
When I send a test webhook for a failed delivery from the Logs page in the control panel, the request I receive has the reason hardfail
with description Not delivering to previously bounced address
. This reason doesn't appear in the list of documented reasons.
It seems like the equivalent of the documented reason Suppress-Bounce
which indicates that Mailgun stopped delivery to a previously bounced address.
Is the list of documented reasons outdated?
The SMTP simple sending examples fail to work with the error message, "535 5.7.0 Mailgun is not loving your login or password". Fix.
Hello, I noticed a few discrepancies in the docs and inconsistencies in the API between adding a single unsubcribe and adding multiple unsubscribes.
https://documentation.mailgun.com/en/latest/api-suppressions.html#add-a-single-unsubscribe
This sentence in particular does not match what I've found using the API.
Fields within each individual unsubscribe record are the same as for the “add a single unsubscribe” API method, with the same defaults and optionality rules.
Through testing I discovered that single unsubscribe works as expected using the tag
field (which is given in the example), and multiple unsubscribe only with the tags
(plural) field
Single address unsubscribe:
tag
field, 1 tag can be added as expectedtags
field, this field is ignored. the API responds success. instead an unsubscribe is added with the '*'
tagcreated_at
field is ignored in both cases. If the user had already unsubscribed to some tags, this field is always updated to the current time. I was trying to preserve the original created_at
time by passing it back but this was not possible.Multiple unsubscribe method:
tag
field, the tag value is ignored and the tag '*'
is added insteadtags
works as expected if you send an arraycreated_at
field works as expected and I can preserve the original timestampcould you please add an example to the documentation that shows using additional parameters such as skip, limit, code, error, and address. Don't need an example for each in my opinion but just something that gets the idea across. Something like this:
curl -s --user 'api:key-ex4mp134p1k3y4741s71ng' -G
https://api.mailgun.net/v2/example.domain.com/bounces
-d skip=1
If you do the steps given in the manual:
https://documentation.mailgun.com/en/latest/quickstart-sending.html#send-with-smtp-or-api
you directly get a deprecation warning.
Look at https://github.com/mailgun/mailgun-php for the new implementation.
looked at the 'email validation' example in the docs and tried to copy & paste the code to test it - didn't work. I got a 404
.
Then I looked at the live example on the homepage and it uses the v2 API: https://api.mailgun.net/v2
- example says v3.
What is the correct way to access the validation endpoint?
https://documentation.mailgun.com/api-suppressions.html#view-all-bounces
limit Maximum number of records to return (optional, default: 100, max: 10000)
I think the limit is 1000, so that should be:
limit Maximum number of records to return (optional, default: 100, max: 1000)
Is it possible to grab all logs daily? I want to save the logs to ftp server.
Can we get some node.js samples in the docs? And how did golang make it ahead of node?
mailgun-request.js
:
'use strict';
var request = require('request');
request({
url: 'https://api.mailgun.net/v3/example.com/messages'
, method: 'POST'
, auth: { user: 'api', pass: 'key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' }
, formData: {
from: 'Excited User <[email protected]>'
, to: [
'[email protected]'
, '[email protected]'
]
, subject: '[Mailgun Test] Hello'
, text: 'Testing some Mailgun awesomeness!'
, encoding: 'utf-8'
}
}, function (err, response, body) {
var json = JSON.parse(body);
console.log(json);
});
Or, for those that don't want to use request
, which has a boatload of dependencies and features that aren't needed for mailgun (since it is so well-behaved), it can reasonably be done in-the-raw:
mailgun-raw.js
:
'use strict';
var https = require('https');
var FormData = require('form-data');
var options;
var form;
var request;
options = {
host: 'api.mailgun.net'
, port: 443
, method: 'POST'
, auth: 'api:key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
, path: '/v3/example.com/messages'
};
form = new FormData();
form.append('from', 'Excited User <[email protected]>');
form.append('to', '[email protected]');
form.append('to', '[email protected]');
form.append('subject', '[Mailgun Test] Hello');
form.append('text', 'Testing some Mailgun awesomeness!');
options.headers = form.getHeaders();
request = https.request(options);
form.pipe(request);
request.on('response', function (res) {
console.log(res.statusCode);
var data = '';
res.on('data', function (chunk) {
data += chunk.toString('utf-8');
});
res.on('end', function () {
console.log(data);
});
});
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.