I'm trying to figure out a way to send an email to an anonymous user when one creates an issue through the email. What I need is for this anonymous user to receive a notification email when the issue was opened,commented and closed.
According to their official documentation this can only be done if the creator is already a user in JIRA or if a user will be created on the fly. None of which works for me.
The work-arounds that I found so far are:
JEMH - which promises this functionality but looks unstable, meaning it seems to break (at least for a little bit) with every JIRA update and no downtime is acceptable for me.
Writing my own script as was recommended in the similar thread
I have no problems writing my own script but I just wanted to be sure I won't be reinventing the wheel. Are there any other ways of doing this?
I'll be very greatful for any help.
I just noticed this question. JEMH has now evolved into a fully fledged commercial plugin, and has a mass of new features, some of which actually address supporting remote 'anonymous' users for issue creation, essentially turning JIRA into a fully capable email helpdesk solution. Specific template customization is available for this on a per-event basis.
Regarding breakages, staying at the 'latest' release gives developers absolutely no time to catchup. Play smart, give all developers a chance to catchup.
With the depths of JIRA API's that JEMH plumbs, breakages were unfortunately common, but now are less likely thanks to Atlassian stabilizing some core API's in 5.0+. Work also also underway to provide end-end integration testing, which is a mission in its own right!
Here is how I did it using the Script Runner pluging, I've told Jira to get emails from my mailbox, and create issues from them. Than, on the workflow, I saved the sender's email and name to a custom fields using the following script:
from com.atlassian.jira import ComponentManager
import re
cfm = ComponentManager.getInstance().getCustomFieldManager()
# read issue description
description = issue.getDescription()
if (description is not None) and ('Created via e-mail received from' in description):
# extract email and name:
if ('<' in description) and ('>' in description):
# pattern [Created via e-mail received from: name <email#company.com>]
# split it to a list
description_list = re.split('<|>|:',description)
list_length = len(description_list)
for index in range(list_length-1, -1, -1):
if '#' in description_list[index]:
customer_email = description_list[index]
customer_name = description_list[index - 1]
break
else:
# pattern [Created via e-mail received from: email#company.com]
customer_name = "Sir or Madam"
# split it to a list
description_list = re.split(': |]',description)
list_length = len(description_list)
for index in range(list_length-1, -1, -1):
if '#' in description_list[index]:
customer_email = description_list[index]
break
# if the name isn't in the right form, switch it's places:
if (customer_name[0] == '"') and (customer_name[-1] == '"') and (',' in customer_name):
customer_name = customer_name[1:-1]
i = customer_name.index(',')
customer_name = customer_name[i+2:]+" "+customer_name[:i]
# insert data to issue fields
issue.setCustomFieldValue(cfm.getCustomFieldObject("customfield_10401"),customer_email)
issue.setCustomFieldValue(cfm.getCustomFieldObject("customfield_10108"),customer_name)
than, send the mail using the following script:
import smtplib,email
from smtplib import SMTP
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
import os
import re
from com.atlassian.jira import ComponentManager
customFieldManager = ComponentManager.getInstance().getCustomFieldManager()
cfm = ComponentManager.getInstance().getCustomFieldManager()
# read needed fields from the issue
key = issue.getKey()
#status = issue.getStatusObject().name
summary = issue.getSummary()
project = issue.getProjectObject().name
# read customer email address
toAddr = issue.getCustomFieldValue(cfm.getCustomFieldObject("customfield_10401"))
# send mail only if a valid email was entered
if (toAddr is not None) and (re.match('[A-Za-z0-9._%+-]+#(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,4}',toAddr)):
# read customer name
customerName = issue.getCustomFieldValue(cfm.getCustomFieldObject("customfield_10108"))
# read template from the disk
template_file = 'new_case.template'
f = open(template_file, 'r')
htmlBody = ""
for line in f:
line = line.replace('$$CUSTOMER_NAME',customerName)
line = line.replace('$$KEY',key)
line = line.replace('$$PROJECT',project)
line = line.replace('$$SUMMARY',summary)
htmlBody += line + '<BR>'
smtpserver = 'smtpserver.com'
to = [toAddr]
fromAddr = 'jira#email.com'
subject = "["+key+"] Thank You for Contacting Support team"
mail_user = 'jira#email.com'
mail_password = 'password'
# create html email
html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">'
html +='<body style="font-size:12px;font-family:Verdana">'
html +='<p align="center"><img src="http://path/to/company_logo.jpg" alt="logo"></p> '
html +='<p>'+htmlBody+'</p>'
html +='</body></html>'
emailMsg = email.MIMEMultipart.MIMEMultipart('alternative')
emailMsg['Subject'] = subject
emailMsg['From'] = fromAddr
emailMsg['To'] = ', '.join(to)
emailMsg.attach(email.mime.text.MIMEText(html,'html'))
# Send the email
s = SMTP(smtpserver) # ip or domain name of smtp server
s.login(mail_user, mail_password)
s.sendmail(fromAddr, [to], emailMsg.as_string())
s.quit()
# add sent mail to comments
cm = ComponentManager.getInstance().getCommentManager()
email_body = htmlBody.replace('<BR>','\n')
cm.create(issue,'anonymous','Email was sent to the customer ; Subject: '+subject+'\n'+email_body,False)
content of new_case.template:
Dear $$CUSTOMER_NAME,
Thank you for contacting support team.
We will address your case as soon as possible and respond with a solution very quickly.
Issue key $$KEY has been created as a reference for future correspondence.
If you need urgent support please refer to our Frequently Asked Questions page at http://www.example.com/faq.
Thank you,
Support Team
Issue key: $$KEY
Issue subject: $$PROJECT
Issue summary: $$SUMMARY
All scripts should be attach to the workflow, to Create transition.The scripts are written using Jython, so it needs to be installed to use it.
I doubt this functionality is available already built-in to JIRA, and I have not seen a plugin that will do it.
I looked into this in the past and came up empty. I suspect it is not built in because for many potential customers it would allow them to get away with a 10 user license and yet still support thousands of users.
We went with the unlimited user license instead.
Update: I meant to add to this that you could write a script that would do this, I think. But it looks like it would be a PITA with having to create a custom listener for it to capture changes to the issue https://developer.atlassian.com/display/DOCS/Plugin+Tutorial+-+Writing+event+listeners+with+the+atlassian-event+library
You can send notification to email stored in Jira custom field using Raley Email Notifications
The configuration is trivial, here's an example how to do it:
https://wiki.raleyapps.com/display/RAL/Sending+email+to+value+from+JIRA+issue+custom+field
Related
Hi everyone and thanks in advance for taking the time reading my question.
I have this scenario: I'm using EAGetMail DLL to retrieve emails from a POP3 e-mail server. I have used an example given on the website and so far so good; I can get all the emails from my inbox.
My problem arises when I try to use the data filters that the DLL provides, in order to not get all the emails in the inbox, just a few, using a certain data range.
The code that I'm using for this purpose is the following:
Dim oClient As New MailClient("TryIt")
oClient.Connect(oServer)
Dim options As GetMailInfosOptionType
options = options Or GetMailInfosOptionType.DateRange
options = options Or GetMailInfosOptionType.OrderByDateTime
oClient.GetMailInfosParam.Reset()
oClient.GetMailInfosParam.GetMailInfosOptions = options
oClient.GetMailInfosParam.DateRange.SINCE = System.DateTime.Now.AddDays(-4)
oClient.GetMailInfosParam.DateRange.BEFORE = System.DateTime.Now.AddDays(1)
Theoretically this should retrieve only the emails within last four days from today, but it is not working. Everytime I execute the code I get every e-mail from my inbox.
Has someone faced something similar to this?
The first sentence on this page, regarding the MailClient.GetMailInfosParam property, says that POP3 is not supported:
Search email on IMAP4 Server and MS Exchange Server. It doesn't
support POP3 protocol.
I'm building a slack bot. You feed my bot several info, including an email address, and it sends the data through an outgoing webhook.
The problem is that if I give my bot the required info, the http request returns this (exemple) :
{"name":"Alexandre","email":"<mailto:test#gmail.com|test#gmail.com>","test":"hello world"}
This sucks, because the server catching the hook (zapier) cannot interpret the mailto: with the brackets. This message formatting is something slack does automatically. Any ideas on how I can remove message formatting for URLs and emails ?
Thanks !
I would suggest passing the argument parse as none, according to https://api.slack.com/docs/formatting.
I don't know if you've fixed this issue. I just encountered the same problem. I built my slackbot using Python and I created a method to get rid of the "mailto". This might not be the answer that you are looking for, but hopefully it gives some insight:
def unformat_message(param):
while param.count('mailto') >= 1:
mailto_position_at_param = param.find("<mailto")
end_of_mailto_position_at_param = param.find("com>")
taken_email_position = param.find("com|")
if mailto_position_at_param != -1 and end_of_mailto_position_at_param != -1 and taken_email_position != -1:
old_string = param[mailto_index:end_mailto_index+4]
new_string = param[mailto_index+8:email_index+3]
param = param.replace(old_string,new_string)
return param
I am creating the application which need to track all tweets from user who registered to my application, i tried to track those with streaming API , there are public API, user API , and site API,
in those API it just have an option to follow the user ID by add the comma separated user ID
https://dev.twitter.com/streaming/overview/request-parameters#follow
but i think it is not flexible, if there are a new user registered , i need to rebuild the HTTP request , and also if there are so many users try to listen this stream and query will be so long,
it will be
https://stream.twitter.com/1.1/statuses/filter.json?follow=[user1],[user2],[user3]........[userN],
i afraid the query wont fit, i just need a parameter to filter all user who registered in my application such as, for example.
https://stream.twitter.com/1.1/statuses/filter.json?application=[applicationID]
but i think twitter dev does not provide it
so, is there any way to filter stream by application ID?
I didn't see anything like tracking by application id. If your query become too complex (too many follows/keywords), public streaming api will reject it,
and you can't open more than 2 connections with user stream. So, last solution is using Site Stream, -> you can open as many user connections as you have users registered to your app.
BUT the docs says :
"Site Streams is currently in a closed beta. Applications are no
longer being accepted."
Contact twitter to be sure
Arstechnica has a very interesting article about it. Take a look at this code and the link in the end of this post
If you are using python pycurl will do the job. Its provides a way to execute a function for every little piece of data received.
import pycurl, json
STREAM_URL = "http://chirpstream.twitter.com/2b/user.json"
USER = "YOUR_USERNAME"
PASS = "XXXXXXXXX"
userlist = ['user1',...,'userN']
def on_receive(self, data):
self.buffer += data
if data.endswith("rn") and self.buffer.strip():
content = json.loads(self.buffer)
self.buffer = ""
if "text" in content and content['user'] in userlist:
#do stuff
conn = pycurl.Curl()
conn.setopt(pycurl.USERPWD, "%s:%s" % (USER, PASS))
conn.setopt(pycurl.URL, STREAM_URL)
conn.setopt(pycurl.WRITEFUNCTION, on_receive)
conn.perform()
You can find more information here Real time twitter stream api
I'm searching for a way to let people open Trac ticket by email.
The only solution I've found so far is email2trac | https://oss.trac.surfsara.nl/email2trac/wiki The problem with this solution is that I don't want to install & setup a mailserver. I would like a less invasive solution.
I was thinking about a cron script that download messages from a POP3 account and open/update tickets by parsing the content.
Is this possible ?
I was thinking about a cron script that download messages from a POP3
account and open/update tickets by parsing the content. Is this
possible ?
I think it would be possible yes. Certainly once you had the data from a POP3 account, you could iterate over it and create/update tickets as appropriate with the Trac API.
For the data retrieval step, you could create a new plugin, with a Component which implements the IAdminCommandProvider interface. How you actually retrieve and parse the data is an implementation detail for you to decide, but you could probably use the email/poplib modules and follow some of the parsing structure from email2trac.
For some untested boilerplate to get you started...
from trac.admin import IAdminCommandProvider
from trac.core import Component, implements
from trac.ticket import Ticket
def EmailToTicket(Component):
implements(IAdminCommandProvider)
def get_admin_commands(self):
yield ('emailtoticket retrieve',
'Retrieve emails from a mail server.'
None, self._do_retrieve_email)
def _do_retrieve_email(self):
# TODO - log into the mail server, then parse data.
# It would be nice to have a tuple of dictionaries,
# with keys like id, summary, description etc
# iterate over the data and create/update tickets
for email in emails:
if 'id' in email: # assuming email is a dictionary
self._update_ticket(email)
else:
self._create_ticket(email)
def _update_ticket(self, data):
ticket = Ticket(self.env, data[id])
for field, value in data.iteritems():
ticket[field] = value
ticket.save_changes(author, comment, when)
def _create_ticket(self, data):
ticket = Ticket(self.env)
for field, value in data.iteritems():
ticket[field] = value
ticket.insert()
You could then have Cron tab execute this command via TracAdmin (the frequency is up to you - the below example runs every minute)
* * * * * trac-admin /path/to/projenv emailtoticket retrieve
The find out more about plugin development, you should read this Trac wiki page.
I'm trying to use the new version of Odoo Survey and survey_crm but I'm facing the following problems.
In the previous version there is an option of restricting number of answer per user but in this new version there is no such option (may be I don't know yet), however I tried the following:
Quizz mode (check box): I used this but still not working any user has an option to answer twice
In the invitation I used the last option (which is, Send private invitation to your audience(only one response per recipient and per invitation)) but still this option wouldn't prevent user answering more than once b/c of "Test" link in the Kanban view of Survey
when I tried to send any invitation it popups an error saying OpenERP server error even if I successfully configure my outgoing and incoming email server but when i try it again without and modification it sends with out any error.
As in v8 we are getting wizard.survey_id as "survey.survey" object , instead of id. so, override the _get_public_url function as below:
def _get_public_url(self, cr, uid, ids, name, arg, context=None):
res = dict((id, 0) for id in ids)
survey_obj = self.pool.get('survey.survey')
for wizard in self.browse(cr, uid, ids, context=context):
if isinstance(wizard.survey_id,int):
res[wizard.id] = survey_obj.browse(cr, uid, wizard.survey_id, context=context).public_url
else:
res[wizard.id] = wizard.survey_id.public_url
return res
While Share and Invite by Mail select "Send private invitation to your audience (only one response per recipient and per invitation)" option so that it sends a unique link for each contact and you can able to see those linked Tokens in Answers.
One more thing, these links won't work until and unless the Odoo server start with db-filter option(if multiple databases are present). Because, with these links data base name is not present. So, if we click on these generated links it returns an Error like "This webpage is not available".