feat: IMAP Email Channel (#3298)
This change allows the user to configure both IMAP and SMTP for an email inbox. IMAP enables the user to see emails in Chatwoot. And user can use SMTP to reply to an email conversation. Users can use the default settings to send and receive emails for email inboxes if both IMAP and SMTP are disabled. Fixes #2520
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div class="settings--content">
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.IMAP.TITLE')"
|
||||
:sub-title="$t('INBOX_MGMT.IMAP.SUBTITLE')"
|
||||
>
|
||||
<form @submit.prevent="updateInbox">
|
||||
<label for="toggle-imap-enable">
|
||||
<input
|
||||
v-model="isIMAPEnabled"
|
||||
type="checkbox"
|
||||
name="toggle-imap-enable"
|
||||
/>
|
||||
{{ $t('INBOX_MGMT.IMAP.TOGGLE_AVAILABILITY') }}
|
||||
</label>
|
||||
<p>{{ $t('INBOX_MGMT.IMAP.TOGGLE_HELP') }}</p>
|
||||
<div v-if="isIMAPEnabled" class="imap-details-wrap">
|
||||
<woot-input
|
||||
v-model.trim="address"
|
||||
:class="{ error: $v.address.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.IMAP.ADDRESS.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.IMAP.ADDRESS.PLACE_HOLDER')"
|
||||
@blur="$v.address.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model="port"
|
||||
type="number"
|
||||
:class="{ error: $v.port.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.IMAP.PORT.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.IMAP.PORT.PLACE_HOLDER')"
|
||||
@blur="$v.port.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model="email"
|
||||
:class="{ error: $v.email.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.IMAP.EMAIL.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.IMAP.EMAIL.PLACE_HOLDER')"
|
||||
@blur="$v.email.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model="password"
|
||||
:class="{ error: $v.password.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.IMAP.PASSWORD.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.IMAP.PASSWORD.PLACE_HOLDER')"
|
||||
type="password"
|
||||
@blur="$v.password.$touch"
|
||||
/>
|
||||
<label for="toggle-enable-ssl">
|
||||
<input
|
||||
v-model="isSSLEnabled"
|
||||
type="checkbox"
|
||||
name="toggle-enable-ssl"
|
||||
/>
|
||||
{{ $t('INBOX_MGMT.IMAP.ENABLE_SSL') }}
|
||||
</label>
|
||||
</div>
|
||||
<woot-submit-button
|
||||
:button-text="$t('INBOX_MGMT.IMAP.UPDATE')"
|
||||
:loading="uiFlags.isUpdatingInbox"
|
||||
:disabled="($v.$invalid && isIMAPEnabled) || uiFlags.isUpdatingIMAP"
|
||||
/>
|
||||
</form>
|
||||
</settings-section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import SettingsSection from 'dashboard/components/SettingsSection';
|
||||
import { required, minLength, email } from 'vuelidate/lib/validators';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SettingsSection,
|
||||
},
|
||||
mixins: [alertMixin],
|
||||
props: {
|
||||
inbox: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isIMAPEnabled: false,
|
||||
address: '',
|
||||
port: '',
|
||||
email: '',
|
||||
password: '',
|
||||
isSSLEnabled: true,
|
||||
};
|
||||
},
|
||||
validations: {
|
||||
address: { required },
|
||||
port: { required, minLength: minLength(2) },
|
||||
email: { required, email },
|
||||
password: { required },
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ uiFlags: 'inboxes/getUIFlags' }),
|
||||
},
|
||||
watch: {
|
||||
inbox() {
|
||||
this.setDefaults();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setDefaults();
|
||||
},
|
||||
methods: {
|
||||
setDefaults() {
|
||||
const {
|
||||
imap_enabled,
|
||||
imap_address,
|
||||
imap_port,
|
||||
imap_email,
|
||||
imap_password,
|
||||
imap_enable_ssl,
|
||||
} = this.inbox;
|
||||
this.isIMAPEnabled = imap_enabled;
|
||||
this.address = imap_address;
|
||||
this.port = imap_port;
|
||||
this.email = imap_email;
|
||||
this.password = imap_password;
|
||||
this.isSSLEnabled = imap_enable_ssl;
|
||||
},
|
||||
async updateInbox() {
|
||||
try {
|
||||
this.loading = true;
|
||||
const payload = {
|
||||
id: this.inbox.id,
|
||||
formData: false,
|
||||
channel: {
|
||||
imap_enabled: this.isIMAPEnabled,
|
||||
imap_address: this.address,
|
||||
imap_port: this.port,
|
||||
imap_email: this.email,
|
||||
imap_password: this.password,
|
||||
imap_enable_ssl: this.isSSLEnabled,
|
||||
imap_inbox_synced_at: this.isIMAPEnabled
|
||||
? new Date().toISOString()
|
||||
: undefined,
|
||||
},
|
||||
};
|
||||
await this.$store.dispatch('inboxes/updateInboxIMAP', payload);
|
||||
this.showAlert(this.$t('INBOX_MGMT.IMAP.EDIT.SUCCESS_MESSAGE'));
|
||||
} catch (error) {
|
||||
this.showAlert(this.$t('INBOX_MGMT.IMAP.EDIT.ERROR_MESSAGE'));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.imap-details-wrap {
|
||||
margin-bottom: var(--space-medium);
|
||||
}
|
||||
</style>
|
||||
@@ -353,6 +353,8 @@
|
||||
<woot-code :script="inbox.forward_to_email"></woot-code>
|
||||
</settings-section>
|
||||
</div>
|
||||
<imap-settings :inbox="inbox" />
|
||||
<smtp-settings :inbox="inbox" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="selectedTabKey === 'preChatForm'">
|
||||
@@ -378,6 +380,8 @@ import FacebookReauthorize from './facebook/Reauthorize';
|
||||
import PreChatFormSettings from './PreChatForm/Settings';
|
||||
import WeeklyAvailability from './components/WeeklyAvailability';
|
||||
import GreetingsEditor from 'shared/components/GreetingsEditor';
|
||||
import ImapSettings from './ImapSettings';
|
||||
import SmtpSettings from './SmtpSettings';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -387,6 +391,8 @@ export default {
|
||||
PreChatFormSettings,
|
||||
WeeklyAvailability,
|
||||
GreetingsEditor,
|
||||
ImapSettings,
|
||||
SmtpSettings,
|
||||
},
|
||||
mixins: [alertMixin, configMixin, inboxMixin],
|
||||
data() {
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div class="settings--content">
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.SMTP.TITLE')"
|
||||
:sub-title="$t('INBOX_MGMT.SMTP.SUBTITLE')"
|
||||
>
|
||||
<form @submit.prevent="updateInbox">
|
||||
<label for="toggle-enable-smtp">
|
||||
<input
|
||||
v-model="isSMTPEnabled"
|
||||
type="checkbox"
|
||||
name="toggle-enable-smtp"
|
||||
/>
|
||||
{{ $t('INBOX_MGMT.SMTP.TOGGLE_AVAILABILITY') }}
|
||||
</label>
|
||||
<p>{{ $t('INBOX_MGMT.SMTP.TOGGLE_HELP') }}</p>
|
||||
<div v-if="isSMTPEnabled" class="smtp-details-wrap">
|
||||
<woot-input
|
||||
v-model.trim="address"
|
||||
:class="{ error: $v.address.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.SMTP.ADDRESS.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.SMTP.ADDRESS.PLACE_HOLDER')"
|
||||
@blur="$v.address.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model="port"
|
||||
type="number"
|
||||
:class="{ error: $v.port.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.SMTP.PORT.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.SMTP.PORT.PLACE_HOLDER')"
|
||||
@blur="$v.port.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model="email"
|
||||
:class="{ error: $v.email.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.SMTP.EMAIL.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.SMTP.EMAIL.PLACE_HOLDER')"
|
||||
@blur="$v.email.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model="password"
|
||||
:class="{ error: $v.password.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.SMTP.PASSWORD.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.SMTP.PASSWORD.PLACE_HOLDER')"
|
||||
type="password"
|
||||
@blur="$v.password.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model.trim="domain"
|
||||
:class="{ error: $v.domain.$error }"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.SMTP.DOMAIN.LABEL')"
|
||||
:placeholder="$t('INBOX_MGMT.SMTP.DOMAIN.PLACE_HOLDER')"
|
||||
@blur="$v.domain.$touch"
|
||||
/>
|
||||
</div>
|
||||
<woot-submit-button
|
||||
:button-text="$t('INBOX_MGMT.SMTP.UPDATE')"
|
||||
:loading="uiFlags.isUpdatingInbox"
|
||||
:disabled="($v.$invalid && isSMTPEnabled) || uiFlags.isUpdatingSMTP"
|
||||
/>
|
||||
</form>
|
||||
</settings-section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import SettingsSection from 'dashboard/components/SettingsSection';
|
||||
import { required, minLength, email } from 'vuelidate/lib/validators';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SettingsSection,
|
||||
},
|
||||
mixins: [alertMixin],
|
||||
props: {
|
||||
inbox: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isSMTPEnabled: false,
|
||||
address: '',
|
||||
port: '',
|
||||
email: '',
|
||||
password: '',
|
||||
domain: '',
|
||||
};
|
||||
},
|
||||
validations: {
|
||||
address: { required },
|
||||
port: {
|
||||
required,
|
||||
minLength: minLength(2),
|
||||
},
|
||||
email: { required, email },
|
||||
password: { required },
|
||||
domain: { required },
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ uiFlags: 'inboxes/getUIFlags' }),
|
||||
},
|
||||
watch: {
|
||||
inbox() {
|
||||
this.setDefaults();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setDefaults();
|
||||
},
|
||||
methods: {
|
||||
setDefaults() {
|
||||
const {
|
||||
smtp_enabled,
|
||||
smtp_address,
|
||||
smtp_port,
|
||||
smtp_email,
|
||||
smtp_password,
|
||||
smtp_domain,
|
||||
} = this.inbox;
|
||||
this.isSMTPEnabled = smtp_enabled;
|
||||
this.address = smtp_address;
|
||||
this.port = smtp_port;
|
||||
this.email = smtp_email;
|
||||
this.password = smtp_password;
|
||||
this.domain = smtp_domain;
|
||||
},
|
||||
async updateInbox() {
|
||||
try {
|
||||
const payload = {
|
||||
id: this.inbox.id,
|
||||
formData: false,
|
||||
channel: {
|
||||
smtp_enabled: this.isSMTPEnabled,
|
||||
smtp_address: this.address,
|
||||
smtp_port: this.port,
|
||||
smtp_email: this.email,
|
||||
smtp_password: this.password,
|
||||
smtp_domain: this.domain,
|
||||
},
|
||||
};
|
||||
await this.$store.dispatch('inboxes/updateInboxSMTP', payload);
|
||||
this.showAlert(this.$t('INBOX_MGMT.SMTP.EDIT.SUCCESS_MESSAGE'));
|
||||
} catch (error) {
|
||||
this.showAlert(this.$t('INBOX_MGMT.SMTP.EDIT.ERROR_MESSAGE'));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.smtp-details-wrap {
|
||||
margin-bottom: var(--space-medium);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user