I'm using the following Python code to send Mandrill email:
json_mandrill = dict(
key=MANDRILL_KEY,
template_name=template_name,
template_content=[],
global_merge_vars=[],
message=dict(to=[dict(email=recipient)])
)
for name, content in merge_vars.items():
json_mandrill["global_merge_vars"].append(
dict(name=name, content=content))
url = "https://mandrillapp.com/api/1.0/messages/send-template.json"
logging.info(json.dumps(json_mandrill))
result = urlfetch.fetch(url=url,
payload=json.dumps(json_mandrill),
method=urlfetch.POST,
headers={'Content-Type': 'application/x-www-form-urlencoded'})
Here is an example of the submitted JSON from my logs:
{"global_merge_vars": [{"content": 7, "name": "free_duration"}, {"content": 4615291308867584, "name": "eid"}, {"content": "poll", "name": "mode"}, {"content": "31 July 2015 at 09:44 EDT", "name": "exp"}, {"content": "Jeff", "name": "name"}],
"template_content": [],
"message": {"to": [{"email": REDACTED}]},
"key": REDACTED,
"template_name": "manager-welcome"}
My Mandrill settings are set to use Handlebars and here is an excerpt from the template:
<p>Dear {{name}},</p>
And this is what appears in the received email:
<p>Dear ,</p>
The emails get sent, but the merge variables in the email are just blank. Any idea what I am doing wrong?
Looking at the submitted JSON, it looks like the "global_merge_vars" aren't nested properly. They should be nested in the "message" struct, instead of on the same level.
Related
By default the Twilio Python client seems to log out personal information (emails and numbers). I know you can access the logger like this twilio_logger = logging.getLogger('twilio.http_client')
Is there a simple setting change we can make to filter out this personal information, either directly through the library or by changing the logger?
NOTE: I have attempted to do this by creating a custom formatter:
class SensitiveDataFormatter(logging.Formatter):
"""Formatter that removes sensitive information in urls."""
#staticmethod
def _filter(s):
print('filter')
return re.sub(r'([A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,})', r'[email_redacted]', s)
def format(self, record):
original = logging.Formatter.format(self, record)
return self._filter(original)
LOGGING = {
'version': 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'sensitive'
},
},
'root': {
'handlers': ['console'],
'level': 'INFO'
},
'formatters': {
'sensitive': {
'()': 'my_project.settings.logging.sensitive_data_formatter.SensitiveDataFormatter'
}
}
}
This works in the general case, however I'm struggling to apply it to Twilio
It seems that you can apply filters to Python loggers using logger config and a custom class that inherits from logging.Filter.
I'm not a Python developer, so pointing you to this blog post is the best way I can answer this question. I will note that the post appears to be from 2014, so may need updates for Python 3, but the Python logging documentation is also pretty extensive, so should help you out here.
Here is how you can configure the Twilio logger in the Python library to use a custom formatter. To test this I took your formatter and modified it to redact Twilio accounts, messaging services and phone numbers.
client = Client(account_sid, auth_token)
class SensitiveDataFormatter(logging.Formatter):
#staticmethod
def _filter(s):
filters = [
[r'(AC[a-f0-9]+)', '[account_redacted]'],
[r'(MG[a-f0-9]+)', '[messaging_service_redacted]'],
[r'(\+[0-9]+)', '[phone_redacted]'],
]
for f in filters:
s = re.sub(f[0], f[1], s)
return s
def format(self, record):
original = logging.Formatter.format(self, record)
return self._filter(original)
# create a logging handler with the custom formatter attached
handler = logging.StreamHandler()
handler.setFormatter(SensitiveDataFormatter())
# add the stream handler to the Twilio logger
client.http_client.logger.addHandler(handler)
client.http_client.logger.setLevel(logging.INFO)
Example log after sending an SMS:
POST Request: https://api.twilio.com/2010-04-01/Accounts/[account_redacted]/Messages.json
PAYLOAD: {'To': '[phone_redacted]', 'From': '[messaging_service_redacted]', 'Body': 'Friendly reminder that you have an appointment with us next week.'}
POST Response: 201 {"sid": "SM4428eb430949461d9bd58d44da1dd999", "date_created": "Thu, 19 May 2022 08:57:49 [phone_redacted]", "date_updated": "Thu, 19 May 2022 08:57:49 [phone_redacted]", "date_sent": null, "account_sid": "[account_redacted]", "to": "[phone_redacted]", "from": null, "messaging_service_sid": "[messaging_service_redacted]", "body": "Friendly reminder that you have an appointment with us next week.", "status": "accepted", "num_segments": "0", "num_media": "0", "direction": "outbound-api", "api_version": "2010-04-01", "price": null, "price_unit": null, "error_code": null, "error_message": null, "uri": "/2010-04-01/Accounts/[account_redacted]/Messages/SM4428eb430949461d9bd58d44da1dd999.json", "subresource_uris": {"media": "/2010-04-01/Accounts/[account_redacted]/Messages/SM4428eb430949461d9bd58d44da1dd999/Media.json"}}
So i grab data from an Airtable and then have a custom PUT as the second action using Samba Lives API, specifically Sessions -> PUT Session https://documenter.getpostman.com/view/2014682/samba-live-rest-api/6YzutHM#c87c1db7-2b5c-9b2b-7d63-6b531793cfe2
This is the data in the custom PUT:
Method: PUT
URL: https://samba.live/api/2/ourusername/session
Data Pass-Through? No
Data:
input_type=json&rest_data={
"topic": "Crazy Topic",
"duration": 30,
"start_time": "2025-09-10 12:00:00",
"invited_participants":[
{
"email":"flast#company.com",
"first_name":"First",
"last_name":"Last",
"role":2,
"send_email_invitation":true
},
{
"email": "first.last#gmail.com",
"first_name": "First",
"last_name": "Last",
"role": 1,
"send_email_invitation": true
}
],
}
Unflatten- yes
Basic Auth- ourusername|ourpassword
Headers- none
But the test fails and says "App returned "rest_data" param is incorrect. JSON is expected."
I'm not really sure what to try and Zapier just said we don't help with that. Only thing i could think to try was to delete the input_type section, and that returned with an error saying "Topic is required." Same thing when i left most of it and just deleted the rest_data part.
Any ideas?
Fixed - apparently the comma after the ] threw everything off.
I am trying to find MailChimp documentation for implementing iOS app that sends instant email to user just like SendGrid. But I can't details about send instant email using email templates via MailChimp even I don't know was it possible or not. How to send instant email to receiver through mail chimp email templates? Any link or suggestion. Thanking you!
For reference I added Sample code sending email via SendGrid:
let dictionary: [String: Any] = [
"personalizations" :[
[
"to":[
[
"email": Constants.feedbackEmail,
"name": Constants.feedbackEmailUser
]
],
"dynamic_template_data": [ //Dynamic data to apply email body
"sender_name": name,
"subject":subject,
"content":content,
"type":type
]
]
],
"from" :[
"email": Constants.feedbackEmail,
"name": Constants.feedbackEmailUser
],
"reply_to":[
"email": Constants.feedbackEmail,
"name": Constants.feedbackEmailUser
],
"template_id": "d-7336fe13346e82434596ed08b023529"
]
//TODO:- Calling POST method URL with body data of this JSON object.
To send instant transactional emails to your users you have to use Mandrill, which is the transactional tool of Mailchimp made exactly for your use case.
You will be able to create your templates in Mailchimp and use them in Mandrill.
I have retrieved a json object using typhoeus gem.
url = 'www.example.com' <br>
request = ::Typhoeus::Request.get(url,userpwd: username + ":" + pass)<br>
content = JSON.parse(request.body)
I would like to count the occurence of "Priority":"high" including the quotes inside the json response. How do I go about doing this?
Edit:
"priority":"high" is a key value pair. It is deeply nested inside the json tree.(Don't how deeply it is nested). All I need is count of occurence of "priority":"high"
Any and all suggestion is welcome.
Sample data:
"tickets": [{
"url": "https://.zendesk.com/api/v2/tickets/xxxx.json",
"id": xxxxx,
"external_id": null,
"via": {
"channel": "email",
"source": {
"from": {
"address": "#compli.com",
"name": ""
},
"to": {
"name": "organization Global Support",
"address": "support#organization.zendesk.com"
},
"rel": null
}
},
"created_at": "2016-08-04T16:23:13Z",
"updated_at": "2016-08-08T20:26:01Z",
"type": "problem",
"subject": "Problems with abc Connect",
"raw_subject": "Problems with abc Connect",
"description": "Hi – our Tenet ID is 5675.\n\n \n\nThe abc report is not providing the full data when I run the billing preview. I am running it using Chrome. Attached are snapshots of what I’m doing plus the report generated.\n\n \n\nA perfect example of the problem is shown at the bottom of the report generated. Garber Automotive Group, account number A00000490 does not display the data for all of their products. Their data is shown on rows 5658 thru 5712 on the excel file BillingPreviewResult_201620 report run 08.04.16.\n\n \n\nHowever the EXACT same report (all the parameters are the same) run on 07/01/16 included all of Garber’s information. The excel file abc report run 07.01.16 10.13 AM has the data for Garber on rows 6099 – 6182.\n\n \n\nThe report is cutting off a lot of data for some reason. As you can see by comparing the amount of data between the two excel reports there are much fewer lines on the report run on today as opposed to the one run on 07/01, 6182 rows vs 5712 rows.\n\n \n\nThis is a business critical report for us. It is used for cash forecasting, monthly financial reporting, rolling budgeting and ad hoc reporting.\n\n \n\nWe need this problem identified and fixed immediately. It is already causing a problem with finalizing our July results.\n\n \n\nLet me know if you have any questions or need any additional data.\n\n \n\n \n\nRegards,\n\n \n\n \n\n \n\n| Controller\ndesk: 503.963-4239 | fax: 503.294.1200 | \n\nCompli - Cool, Calm and Compliant. TM\n\nVisit() to learn more.\n\n \n\nFollow us on LinkedIn () and Twitter",
"priority": "normal",
"status": "open",
"recipient": "support#organization.zendesk.com",
"requester_id": 1336424406,
"submitter_id": 1336424406,
"assignee_id": null,
"organization_id": 224504969,
"group_id": 21606503,
"collaborator_ids": [560973773, 786229209, 421597631, 539566717, 707192615, 1336424406, 31365392, 719608577, 1817633993],
"forum_topic_id": null,
"problem_id": null,
"has_incidents": false,
"due_at": null,
"tags": ["1_price", "best_practice_advise", "engage_global_services__email_", "escalate", "hard", "internal_escalation", "p0", "yes_escalated", "xxxxx", "zhub"],
"custom_fields": [{
"id": 22024091,
"value": "p0"
}, {
"id": 24212576,
"value": "best_practice_advise"
}, {
"id": 22035048,
"value": "xxx and so on.....
I am sending emails to lists of contacts based on templates using Mandrill. I would like to track if the contacts have replied to my email and, to do so, I would like to check whether the Message-Id of my sent emails appears in the In-Reply-To header field of new messages.
The problem is that I have to generate and set the Message-Id manually since Mandrill only gives me their internal _id. However, since I am sending emails to various contacts at the same time, I set preserve_recipients to false. But then I can only set one Message-Id, which will therefore become not globally unique.
Here is an example JSON that I'm sending:
{
"from_email": "itsme#email.com",
"from_name": "Its Me",
"headers": {"Message-Id": ["<20150528161426.4265.93582#email.com>"]},
"subject": "Thesubject",
"text": "Thebody",
"to": [
{
"email": "john#email.com",
"name": "John",
"type": "to"
},
{
"email": "patrick#email.com",
"name": "Patrick",
"type": "to"
}
],
"preserve_recipients": false
}
In this case, two messages will be sent, but they'll have the same Message-Id. If I don't set it, Mandrill will automatically assign one, but then I can't retrieve it.
Any idea what I could do ? Maybe my whole approach is incorrect...
I ended up looping over all the recipients and generating a new Message-Id at each iteration and send one email at a time. Probably not optimal since I'm not using Mandrill bulk capability, but at least now I can store the email id.
import email
import mandrill
mandrill_client = mandrill.Mandrill('YOUR_MANDRILL_KEY')
for recipient in recipients:
# Generate RFC 2822-compliant Message-ID header
message_id = email.Utils.make_msgid()
m = {
"headers": {"Message-Id": [message_id],
"from_email": "itsme#email.com",
"from_name": "Its Me",
"subject": "The subject",
"text": "The body",
"to": [{"email": recipient["email"],
"name": recipient["name"],
"type": "to"}],
"track_clicks": True,
"track_opens": True
}
result = mandrill_client.messages.send(message=m)
From mandrill documentation you can retrieve the _id from the return value of the message.