mandrill web-hooks open event "list of opens" - mandrill

We are using mandrill, and we have webhooks configured to track open events.
But I am a bit confused about the JSON format what mandrill provides.
In of the formats, for open event, we have a key called "opens"
"opens": [
{
"ts": 1420010190,
"ip": "0.0.0.0",
"location": null,
"ua": "Linux/Linux/Gmail image proxy/Gmail image proxy"
},
{
"ts": 1420020155,
"ip": "0.0.0.0",
"location": null,
"ua": "Linux/Linux/Gmail image proxy/Gmail image proxy"
},
],
Are these objects unique ?
will they be duplicates? if so, do mandrill adds all the open list for every event we receive?
From the docs what i could understand is mandrill sends a webhook for every open, if it is, what are these list of opens in every event. which one would i consider.
It will be really helpfull, if someone explain the format.
Thanks in advance.

If you only want to record the individual opens, just use the data at the top level of the webhook event (ts, event, location, ip, for example). Everything under the msg key is data about the message that Mandrill knows when the webhook is created (so it's in addition to information about the individual open that triggered the webhook event). So the msg.opens key will be a list of all opens Mandrill knows about for the message at that time.

Related

Passing additional data to the action listeners along with the block_actions payload in Slack Bolt python

I am new to Slack APP development, I am developing the app using Slack bolt python. In my app I have configured the slack interaction using the button click, on clicking the button I am calling the corresponding listener(identified by action_id mentioned in the button). In the listener I am getting the block_actions payload which contains all the state values of the event, but in addition to that I want to some arguments to the listener function. Is it possible in any way that we can send additional arguments to the listeners
#app.action("change_time_period")
def handle_change_time_period(ack, context, body, client, logger, message, say):
# want the arguments here such as passing email_id from post_data
def post_data(user_id, email_id):
client = WebClient(token=os.environ.get("SLACK_BOT_TOKEN"))
result = client.chat_postMessage(
channel=user_id,
blocks=[
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"emoji": True,
"text": "Change time period"
},
"style": "primary",
"value": "time_period",
"action_id": "change_time_period"
}
]
}
]
)
In the code above, I will be calling the post_data which will post the message containing the block kit, once the user clicks the button the handle_change_time_period will be called
Slack block kit buttons do not have a field where we can pass metadata to the interactivity handler. One workaround to achieve this would be to make use of the value field of the button element dict to dump a JSON with the required data. From the Slack API doc, the value field can hold a maximum of 2000 characters. Your value field can be something like
"value": json.dumps({"actual_value" : "time_period", "email" : "johndoe#abc.com"})
This can be optimized further by reducing the characters in keys. If the extra data you need to pass goes beyond the char limit, you might have to consider caching the data on the server and passing a cache key in the block which can then be used in handler to retrieve the actual data from the cache.

Identifying messages posted by my app in Slack

I'm developing a Slack app that posts alert apps to channels. I want this app to check the history of a channel to find messages it has posted earlier so it can respond accordingly. For example, if there's an alert that has not yet "cleared" it will update said alert instead of posting a new message.
The challenge I'm encountering is that it's not clear how I can identify messages that my app has posted. I see that I can search a channel with conversations.history, and that gives me message events. It looks like some messages have a user property. There are also bot_message sub-type messages that have a bot_id property. However, I don't see any way to identify my app ID.
Should every app have an associated bot_id? user ID? If so, where do I get these IDs so I can filter the conversation history?
Update
I tried calling the bots.info method with no bot ID parameter hoping it would give me my bot ID, but it returned no data other than an "OK" status.
Perhaps because Slack has a long history of different APIs, I was misled. Apparently, it's possible for me to find messages my bot previously posted but not how I thought. Here were my misunderstandings and what I've found out when playing with the Slack API tester.
Using conversations.history, you can get a list of messages posted in a channel. The docs say that the history returns an array of message events, and that these have a subtype field. One of the subtypes is bot_message, so my assumption is that messages posted by my bot would have this sub-type. The docs for bot_message has a bot_id, which I don't know for my app, and username, which I don't know what it will match.
However, it turns out when I posted a test message, that the message did not show up as a bot_message; rather it appears in the history without a subtype and has properties which don't seem to match any documentation:
{
"bot_id": "B01HSBYRKUZ",
"type": "message",
"text": "Testing the Slack API; please ignore.",
"user": "U01HDNUJ5EE",
"ts": "1609878469.036400",
"team": "<omitted>",
"bot_profile": {
"id": "B01HSBYRKUZ",
"deleted": false,
"name": "my-bot-name",
"updated": 1608584973,
"app_id": "<omitted>",
"icons": {
"image_36": "...",
"image_48": "...",
"image_72": "..."
},
"team_id": "<omitted>"
}
}
So although it's risky to code against an undocumented format (or maybe I just can't find the right docs?), I can filter these messages by looking to see if there's a bot_profile.app_id that matches my app's ID, which I do know.
you may know id your bot if use context. Example: const {botUserId} = context

Look a message's text from events api response

I'm using slacks events API and have setup a subscription to the reactions_added event. Now when a reaction is added to a message, slack will send me a post body with all the details of the dispatched event as described here.
The problem I'm having is that I want to get the details, specifically the text of the message that my users have reacted to so I can parse/store etc that specific message. I assumed the message would return with some type of UUID that I could then respond to the callback and get the text, however I'm find it difficult to get the specific message.
The only endpoint I see available is the channels.history, which doesn't seem to give me the granularity I'm looking for.
So the tl;dr is: How do I look up a via slacks API, a messages text sent from the events API? Give the information I have the event_ts, channel and message ts I thought would be enough. I'm using the ruby slack-api gem FWIW.
You can indeed use the method channels.history (https://api.slack.com/methods/channels.history) to retrieve message from a public channel . The reaction_added dispatched event includes the channel ID and timestamp of the original message (in the item) and the combination of channelId + timestamp should be unique.
Be careful that you use the correct timestamp though. You need to use item.ts not event_ts
Full example dispatched event from the docs:
{
"token": "z26uFbvR1xHJEdHE1OQiO6t8",
"team_id": "T061EG9RZ",
"api_app_id": "A0FFV41KK",
"event": {
"type": "reaction_added",
"user": "U061F1EUR",
"item": {
"type": "message",
"channel": "C061EG9SL",
"ts": "1464196127.000002"
},
"reaction": "slightly_smiling_face"
},
"event_ts": "1465244570.336841",
"type": "event_callback",
"authed_users": [
"U061F7AUR"
]}
So calling channels.history with these values set should work:
latest = item.ts value
oldest = item.ts value
inclusive = 1
channel = item.channel value
If you want to get messages from a private channel you need to use groups.history.
https://api.slack.com/methods/channels.history

Open URL in browser from Message Button using Slack API

I am sending the users a slack message with a button through a Slack App. On every click of the button, I generate a new URL.
At the moment, I am able to return the URL back as a message. The user clicks on the message to open the URL in the browser.
Instead of the sending a message back, I want to open the URL directly in the browser using slack API.
How can I accomplish it? I can't seem to find anything in the documentation that does that.
Thanks
PS: Google Drive integration does that already.
It appears Slack introduced this feature recently.
As documented in https://api.slack.com/docs/message-attachments#link_buttons
"actions": [
{
"type": "button",
"text": "Book flights 🛫",
"url": "https://flights.example.com/book/r123456"
}
It's possible to preview in Slack's interactive message builder
Unfortunately slack does not support opening urls from message buttons.
You can monitor what slack is planning on releasing here though: https://trello.com/b/ZnTQyumQ/slack-platform-roadmap-for-developers :)
According to Slack, message attachments is the "old way" of composing messages, which will be deprecated in favour of the new Block Kit API.
I found this example on how to do button links on their docs, using the actions object in the message payload.
I haven't implemented it yet, but you can send the message to a channel in your workspace straight from the docs and try it, and it does open the link in the browser as expected.
Update 04/2022
{
"blocks": [
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View",
"emoji": true
},
"style": "primary",
"url": "https://flights.example.com/book/r123456"
}
]
}
]
}
Test on Slack Blockit Builder: Link

Strategies for sending weekly newsletter emails from Rails

So we have about 50,000 users who have signed up for a weekly newsletter. The contents of this email is personalized for each user though, it's not a mass email.
We are using Rails 4 and Mandrill.
Right now we're taking about 12 hours every time we want to fire off this emails.rake task and I'm looking for a way to distribute that time or make it shorter.
What are some techniques I can use to improve this time that is only growing longer the more people sign up?
I was thinking of using mandrill templates, and just sending the json object to mandrill and have them send the email from their end, but I'm not really sure if this is even going to help improve speeds.
At the 50,000+ level: How do I keep email sending times manageable?
Looks like you could use MailyHerald. It is a Rails gem for managing application emails. It sends personalized emails in the background using Sidekiq worker threads which should help you out in terms of performance.
MailyHerald has a nice Web UI and works with email services like Amazon SES or Mandrill.
You need to probably look into Merge Tags on Mandrill. It allows you to define custom content per email. So you can break your newsletter sending into fewer API calls to Mandrill instead of 1 per email. The number of calls will just depend on the size of your data since I am sure there is probably a limit.
You can just create a template and put in merge vars such as *|custom_content_placeholder|** wherever you need user specific content to be placed. You can do this templating in your system and just pass it into the message or you can set it up in Mandrill and make a call to that template.
When you make the Mandrill API call to send an email or email template you just attach the JSON data such as:
"message": {
"global_merge_vars": [
{
"name": "global_placeholder",
"content": "Content to replace for all emails"
}
],
"merge_vars": [
{
"rcpt": "user#domain.com",
"vars": [
{
"name": "custom_content_placeholder",
"content": "User specific content"
},
{
"name": "custom_content_placeholder2",
"content": "More user specific content"
}
]
},
{
"rcpt": "user2#domain.com",
"vars": [
{
"name": "custom_content_placeholder",
"content": "User2 specific content"
},
{
"name": "custom_content_placeholder2",
"content": "More user2 specific content"
}
]
}
],
You can find more info on Merge Tags here:
https://mandrill.zendesk.com/hc/en-us/articles/205582487-How-to-Use-Merge-Tags-to-Add-Dynamic-Content
If you are familiar with handlebars for templating, Mandrill now supports it with the merge tags:
http://blog.mandrill.com/handlebars-for-templates-and-dynamic-content.html

Resources