Gmail Contextual Gadget fails in long Conversation Mode Messages - google-apps-marketplace

We have been noticing that the Google Gadget is failing in long conversations.
In some cases the gadget will not appear at all in a longer conversation. In other cases only some of the extractors are available but the gadget is visible.
Note:- this is only happening in long conversations.
I was hoping that others might be able to confirm/deny this behaviour.
To do so - simply open a long Gmail conversation and confirm whether your gadget is working as expected.
Thanks for your help on this!
Edit 18/10
I've done some more digging on this issue. If I debug the gadget the matches Array only has the first two values where as our spec defines 6.
We get matches[2]
matches[0] = date_sent
matches[1] = date_received
So for some reason the matches Array populated by Google is not complete. On the shorter conversations all 6 matches values are populated....
We get matches[6]
matches[0] = date_sent
matches[1] = date_received
matches[2] = message_id
matches[3] = recipient_to_email
matches[4] = subject
matches[5] = sender_email

Related

Get a message's ts value from /archives link

Slack has a Copy link feature, which copies a deep link to an individual chat message to the clipboard:
Here's an example of such a deep link (obfuscated):
https://myworkspace.slack.com/archives/CqwertGU/p1234567898000159
What I'd like to do is, get the details of that message from the Slack API given that link.
The first string after /archives/ is the channel's ID. I'm not quite clear about that second string though:
According to Slack's API documentation,
channels.history can also be used to pluck a single message from the
archive.
You'll need a message's ts value, uniquely identifying it within a
channel. You'll also need that channel's ID.
So, what I've found is that the p1234567898000159 value in the link above is almost the message's ts value, but not quite (the Slack API won't accept it): the leading p needs to be removed, also there has to be a . inserted after the 10th digit: 1234567898.000159
Putting all this together into an API request...
https://slack.com/api/channels.history?latest=1234567898.000159&channel=CqwertGU&count=1&pretty=1&token=mytoken123&inclusive=true
... I'm getting a response with all the message details, exactly what I need.
My question is: am I doing this right? Do I really need to craft the message's ts value from the URL parameter this way, or is there a better, more robust, officially supported way?
Im new in python, but i got same problem when i creating SlackBot (by SlackBolt), and i solved it like that:
link = 'https://***.slack.com/archives/C03UGEVQ6BX/p1668769293636169'
#Grab information from link
wrong_link_list = link.split('/')
wrong_ts = wrong_link_list[-1]
t_ts = wrong_ts.replace('p', '', 1)
dot = '.'
char_count = 10
#Put information in variables
channel = wrong_link_list[-2]
text = 'Hey dude!'
mess_ts = t_ts[:char_count] + dot + t_ts[char_count:]
app.client.chat_postMessage(channel=channel, text=text, thread_ts = mess_ts)
Hope this will help you!

Logging Into Google To Scrape A Private Google Group (over HTTPS)

I'm trying to log into Google, so that I can scrape & migrate a private google group.
It doesn't seem to log in over SSL. Any ideas appreciated. I'm using Mechanize and the code is below:
group_signin_url = "https://login page to goolge, with referrer url to a private group here"
user = ENV['GOOGLE_USER']
password = ENV['GOOGLE_PASSWORD']
scraper = Mechanize.new
scraper.user_agent = Mechanize::AGENT_ALIASES["Linux Firefox"]
scraper.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
page = scraper.get group_signin_url
google_form = page.form
google_form.Email = user
google_form.Passwd = password
group_page = scraper.submit(google_form, google_form.buttons.first)
pp group_page
I worked with Ian (the OP) on this problem and just felt we should close this thread with some answers based on what we found when we spent some more time on the problem.
1) You can't scrape a Google Group with Mechanize. We managed to get logged in abut the content of the Google Group pages is all rendered in-browser, meaning that HTTP requests, such as issued by Mechanize, are returned with a few links and no actual content.
We found that we could get page content by the use of Selenium (we used Selenium in Firefox, using the Ruby bindings).
2) the HTML element IDs/classes in Google Groups are obfuscated but we found that these Selenium commands will pull out the bits you need (until Google change them)
message snippets (click on them to expand messages)
find_elements(:class, 'GFP-UI5CCLB')
elements with name of author
find_elements(:class, 'GFP-UI5CA1B')
elements with content of post
find_elements(:class, 'GFP-UI5CCKB')
elements containing date
find_elements(:class, 'GFP-UI5CDKB') (and then use the attribute[:title] for a full length date string)
3) I have some Ruby code here which scrapes the content programmatically and uploads it into a Discourse forum (which is what we were trying to migrate to).
It's hacky but it kind of works. I recently migrated 2 commercially important Google Groups using this script. I'm up for taking on 'We Scrape Your Google Group' type work, please PM me.

Bing translator HTTP API throws bad request error, how to solve this?

Whenever I call Bing Translation API [HTTP] to translate some text, first time it works fine, and second time onwards it gives me 'bad request' [status code 400] error. If I wait for 10 or so minutes and then try again, then first request is successful, but second one onwards same story. I have a free account [2million chars translation] with Bing Translation APIs, are there any other limitations calling this API?
Thanks, Madhu
Answer:
hi, i missed to subscribing to Microsoft Translator DATA set subscription. Once i get the same, then things have solved. i.e; once i have signed up for https://datamarket.azure.com/dataset/bing/microsofttranslator then things are working.
i was generating the access_token correctly, so that is not an issue.
thanks, madhu
i missed to subscribing to Microsoft Translator DATA set subscription. Once i get the same, then things have solved. i.e; once i have signed up for https://datamarket.azure.com/dataset/bing/microsofttranslator then things are working.
i was
thanks, madhu
As a note to anyone else having problems, I figured out that the service only allows the token to be used once when using the free subscription. You have to have a paid subscription to call the Translate service more than once with each token. This limitation is, of course, undocumented.
I don't know if you can simply keep getting new tokens -- I suspect not.
And regardless of subscription, the tokens do expire every 10 minutes, so ensure you track when you receive a token and get a new one if needed, e.g. (not thread-safe):
private string _headerValue;
private DateTime _headerValueCreated = DateTime.MinValue;
public string headerValue {
get {
if(_headerValueCreated < DateTime.Now.AddMinutes(-9)) {
var admAuth = new AdmAuthentication("myclientid", "mysecret");
_headerValue = "Bearer " + admAuth.GetAccessToken();
_headerValueCreated = DateTime.Now;
}
return _headerValue;
}
}

Reminder being executed only when adding new reminder

i am trying to use the reminder api but with no luck. The code that i use to create the reminder is located below. The thing that happens is that the reminder is not triggered until i add another reminder, att this point the old reminder goes of immediately. I guess this code does not say much as it is almost copy pasted from Microsoft's tutorial on reminders. however i do not know where the problem could be otherwise (i will post other code snippets if you have suggestions where the problem may lie)
Reminder notification = new Reminder(""+uniqueId);
notification.Title = "Title";
notification.Content = "Content";
notification.BeginTime = DateTime.Now.AddSeconds(10);
notification.RecurrenceType = RecurrenceInterval.None;
notification.NavigationUri = new Uri("/MyPage.xaml?id=" + uniqueId, UriKind.Relative);
// Register the reminder with the system.
ScheduledActionService.Add(notification);
Ok there was nothing wrong with the code. The emulators system time was set to automatic but was somehow going 20 min wrong which led to strange behaviour. After setting time manually it works as expected.

How to get the recipient address of an email via IMAP in Ruby

We have a user whose mail account is deluged with spam. I'm suspecting that he fields a large number of email accounts and therefore is subject to more than he might be with only one or two addresses.
I want to knock up some code which will scan his mailbox and report on the number of addresses that were mailed to (ideally the ones which delivered to his mailbox, eg if he's BCC'd and the To: is billg#microsoft.com, I'd like to know which address was the one which reached him).
I can get the To: if it's present in the envelope, but if not then I need to fall back on alternatives like Cc: and maybe actually get regex-y in the message headers to ID who this message was delivered for. I can handle that. I'm just not sure about how to pull apart the Ruby msg object.
So maybe a better question for me would be, "knowing that I have an object msg returned from imap.fetch, how may I inspect the various methods available such as msg.to and msg.from?"
And perhaps also "should I be using a fancy mail library like Ruby's Mail?"
Code so far - I'm REALLY new to Ruby, OK?
imap = Net::IMAP.new(server)
imap.login(user, pass)
imap.select(folder)
imap.search(['ALL']).each do |message_id|
msg = imap.fetch(message_id,'ENVELOPE')[0].attr['ENVELOPE']
if msg.to
puts "#{msg.to[0].mailbox}##{msg.to[0].host}: \t#{msg.from[0].name}: \t#{msg.subject}"
else
# puts msg.inspect
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
puts msg.inspect
quit
end
# p msg.methods
end
I do something similar to this for a script that I have. It might help you out. The key to remember is that all elements returned are arrays, even if they only have 1 element.
imap.search(["ALL"]).each do |msg|
envelope = imap.fetch(msg, "ENVELOPE")[0].attr["ENVELOPE"]
sender = envelope.from[0].mailbox # This will give you the mailbox name without #domain.com
recipient = envelope.to[0].mailbox # You can also do envelope.to.each { operations } to get the full list of recipients
end
The envelope is what contains all of the data you are trying to look at.
envelope.from[0].mailbox is the sender without the #domain.com
envelope.to[0] is the first recipient without the #domain.com
envelope.subject is the subject
and so on and so on

Resources