Merge pull request #1747 from RocketChat/mail-messages

Mail messages
pull/1749/head
Gabriel Engel 10 years ago
commit ff7e45c7f3
  1. 54
      packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.coffee
  2. 15
      packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.html
  3. 7
      packages/rocketchat-channel-settings-mail-messages/i18n/en.i18n.json
  4. 19
      packages/rocketchat-channel-settings-mail-messages/server/methods/mailMessages.coffee
  5. 18
      packages/rocketchat-lib/server/models/Users.coffee
  6. 28
      server/publications/userAutocomplete.coffee

@ -7,6 +7,29 @@ Template.mailMessagesInstructions.helpers
return ChatRoom.findOne(Session.get('openedRoom'))?.name
erroredEmails: ->
return Template.instance()?.erroredEmails.get().join(', ')
autocompleteSettings: ->
return {
limit: 10
# inputDelay: 300
rules: [
{
# @TODO maybe change this 'collection' and/or template
collection: 'CachedChannelList'
subscription: 'userAutocomplete'
field: 'username'
template: Template.userSearch
noMatchTemplate: Template.userSearchEmpty
matchAll: true
filter:
exceptions: Template.instance().selectedUsers.get()
selector: (match) ->
return { username: match }
sort: 'username'
}
]
}
selectedUsers: ->
return Template.instance().selectedUsers.get()
Template.mailMessagesInstructions.events
'click .cancel': (e, t) ->
@ -25,9 +48,9 @@ Template.mailMessagesInstructions.events
t.$('.error-select').show()
error = true
if t.$('input[name=to]').val().trim()
if t.$('input[name=to_emails]').val().trim()
rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/
emails = t.$('input[name=to]').val().trim().split(',')
emails = t.$('input[name=to_emails]').val().trim().split(',')
erroredEmails = []
for email in emails
unless rfcMailPatternWithName.test email.trim()
@ -37,7 +60,7 @@ Template.mailMessagesInstructions.events
if erroredEmails.length > 0
t.$('.error-invalid-emails').show()
error = true
else
else if not t.selectedUsers.get().length
t.$('.error-missing-to').show()
error = true
@ -46,7 +69,8 @@ Template.mailMessagesInstructions.events
else
data =
rid: Session.get('openedRoom')
to: t.$('input[name=to]').val().trim()
to_users: t.selectedUsers.get()
to_emails: t.$('input[name=to_emails]').val().trim()
subject: t.$('input[name=subject]').val().trim()
messages: selectedMessages.map((i, message) -> return message.id).toArray()
language: localStorage.getItem('userLanguage')
@ -56,6 +80,7 @@ Template.mailMessagesInstructions.events
if err?
return toastr.error(err.reason or err.message)
console.log(result)
toastr.success(TAPi18n.__('Your_email_has_been_queued_for_sending'))
t.reset()
@ -66,10 +91,29 @@ Template.mailMessagesInstructions.events
view?.templateInstance?().selectedMessages = _.pluck(ChatMessage.find({rid: Session.get('openedRoom')})?.fetch(), '_id')
$(".messages-box .message").addClass('selected')
'autocompleteselect #to_users': (event, instance, doc) ->
instance.selectedUsers.set instance.selectedUsers.get().concat doc.username
event.currentTarget.value = ''
event.currentTarget.focus()
'click .remove-to-user': (e, instance) ->
self = @
users = Template.instance().selectedUsers.get()
users = _.reject Template.instance().selectedUsers.get(), (_id) ->
return _id is self.valueOf()
Template.instance().selectedUsers.set(users)
$('#to_users').focus()
Template.mailMessagesInstructions.onCreated ->
@autoCompleteCollection = new Mongo.Collection null
@selectedUsers = new ReactiveVar []
@erroredEmails = new ReactiveVar []
@reset = ->
@reset = =>
@selectedUsers.set []
RocketChat.TabBar.setTemplate('channelSettings')
view = Blaze.getView($('.messages-box')[0])
view?.templateInstance?().resetSelection?(false)

@ -13,9 +13,20 @@
<div>{{email}}</div>
</div>
<div class="input-line double-col">
<label>{{_ "To"}}</label>
<label>{{_ "To_users"}}</label>
<div>
<input type="text" name="to" value="" />
{{> inputAutocomplete settings=autocompleteSettings id="to_users" name="to_users" class="search" autocomplete="off"}}
<ul class="selected-users">
{{#each selectedUsers}}
<li>{{.}} <i class="icon-cancel remove-to-user"></i></li>
{{/each}}
</ul>
</div>
</div>
<div class="input-line double-col">
<label>{{_ "Additional_emails"}}</label>
<div>
<input type="text" name="to_emails" value="" />
</div>
</div>
<div class="input-line double-col">

@ -1,17 +1,18 @@
{
"Additional_emails" : "Additional E-mails",
"Body" : "Body",
"Cancel" : "Cancel",
"Choose_messages" : "Choose messages",
"From" : "From",
"Mail_Message_Missing_to" : "You must provide one or more To e-mail addresses, separated by commas.",
"Mail_Message_Invalid_emails" : "You have provided one or more invalid e-mails: %s",
"Mail_Message_Missing_to" : "You must select one or more users or provide one or more e-mail addresses, separated by commas.",
"Mail_Message_No_messages_selected_select_all" : "You haven't selected any messages. Would you like to <a href='#' class='select-all'>select all</a> visible messages?",
"Mail_Messages" : "Mail Messages",
"Mail_Messages_Instructions" : "Choose which messages you want to send via e-mail by clicking the messages",
"Mail_Messages_Subject" : "Here's a selected portion of %s messages",
"Mail_Message_Invalid_emails" : "You have provided one or more invalid e-mails: %s",
"Send" : "Send",
"Sending" : "Sending...",
"Subject" : "Subject",
"To" : "To",
"To_users" : "To Users",
"Your_email_has_been_queued_for_sending" : "Your email has been queued for sending"
}

@ -3,7 +3,7 @@ Meteor.methods
if not Meteor.userId()
throw new Meteor.Error('invalid-user', "[methods] mailMessages -> Invalid user")
check(data, Match.ObjectIncluding({ rid: String, to: String, subject: String, messages: [ String ], language: String }))
check(data, Match.ObjectIncluding({ rid: String, to_users: [ String ], to_emails: String, subject: String, messages: [ String ], language: String }))
room = Meteor.call 'canAccessRoom', data.rid, Meteor.userId()
unless room
@ -13,10 +13,20 @@ Meteor.methods
throw new Meteor.Error 'not-authorized'
rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/
emails = data.to.trim().split(',')
emails = _.compact(data.to_emails.trim().split(','))
missing = []
if data.to_users.length > 0
for username in data.to_users
user = RocketChat.models.Users.findOneByUsername(username)
if user?.emails?[0]?.address
emails.push user.emails[0].address
else
missing.push username
console.log emails
for email in emails
unless rfcMailPatternWithName.test email.trim()
throw new Meteor.Error('invalid-email', "[methods] mailMessages -> Invalid e-mail")
throw new Meteor.Error('invalid-email', "[methods] mailMessages -> Invalid e-mail #{email}")
user = Meteor.user()
name = user.name
@ -42,5 +52,4 @@ Meteor.methods
console.log 'Sending email to ' + emails.join(', ')
return true
return { success: true, missing: missing }

@ -71,6 +71,24 @@ RocketChat.models.Users = new class extends RocketChat.models._Base
return @find query, options
findActiveByUsernameRegexWithExceptions: (username, exceptions = [], options = {}) ->
console.log 'findActiveByUsernameRegexWithExceptions', username, exceptions
if not _.isArray exceptions
exceptions = [ exceptions ]
usernameRegex = new RegExp username, "i"
query =
$and: [
{ active: true }
{ username: { $nin: exceptions } }
{ username: usernameRegex }
]
# username: { $regex: usernameRegex, $nin: exceptions }
# username: { $nin: exceptions }
console.log 'findActiveByUsernameRegexWithExceptions query', JSON.stringify query, null, ' '
return @find query, options
findByActiveUsersNameOrUsername: (nameOrUsername, options) ->
query =
username:

@ -0,0 +1,28 @@
Meteor.publish 'userAutocomplete', (selector) ->
unless this.userId
return this.ready()
pub = this
options =
fields:
name: 1
username: 1
status: 1
limit: 10
user = RocketChat.models.Users.findOneById this.userId
exceptions = selector.exceptions or []
exceptions.push user.username
cursorHandle = RocketChat.models.Users.findActiveByUsernameRegexWithExceptions(selector.username, exceptions, options).observeChanges
added: (_id, record) ->
pub.added("autocompleteRecords", _id, record)
changed: (_id, record) ->
pub.changed("autocompleteRecords", _id, record)
removed: (_id, record) ->
pub.removed("autocompleteRecords", _id, record)
@ready()
@onStop ->
cursorHandle.stop()
return
Loading…
Cancel
Save