UI/iFrame integrations
JavaScript API

App methods

reload()

Reloads the iframe.

search(text)

Initiates a new search.

Param * requiredDefaultDescription
text*""Search term

alert(options)

Displays an error modal. It only has a “Got it” action.

Param * requiredDefaultDescription
options{}
   title"Error in “Your Integration” integration"Error title
   message""Error description
   note""Error note

navigate(options)

Navigate to a conversation.

Param * requiredDefaultDescription
options{}
   conversationId""Conversation ID

on(event, callback, options)

Registers an event callback.

Param * requiredDefaultDescription
event*""Event to register
callback*Callback function
options{}
   retroactivefalseTriggers the callback immediately if the event has occurred before the callback is registered

openForm(data)

Displays a form popup. Multiple forms can be stacked over each other.
=> Promise(Object)
    ⮑ Resolves with Field objects

Param * requiredDefaultDescription
data{}
   name""Form title
   fields[]Array of FormField objects
   comments[]Array of FormComment objects
   notes[]Array of FormNote objects
   buttons[]Array of FormButton objects
   options{}
      autoClosetrueClose the popup on submit

closeForm()

Closes the last open form popup.

openSelf()

Opens the integration sidebar if closed and selects the integration.

closeSelf()

Closes the integration sidebar if opened.

openURL(url)

Opens the URL in a new tab on desktop. Opens in native browser or in-app browser depending on user settings on mobile.

Param * requiredDefaultDescription
url*""URL string

openContextMenu(data)

Opens a context menu

Param * requiredDefaultDescription
data*{}
   top0Top position of the menu
Menu will be below that point

Note: do not set if data.bottom is provided
   bottomnullTop position of the menu
Menu will be above that point

Note: do not set if data.top is provided
   left0Left position of the menu
Menu will be to the right of that point

Note: do not set if data.right is provided
   rightnullRight position of the menu
Menu will be to the left of that point

Note: do not set if data.left is provided
   options*[]Array of Option objects

setActions(actions)

Actions are available throughout the app as an option in context menus or swipe action.

Param * requiredDefaultDescription
actions[]Array of Action objects

setAsUtility()

Mark the integration as an utility integration. It will not display the iframe in the integration sidebar. Useful for integrations that only display actions in context menus.

setPermissions(permissions)

Make Missive requests certain media permissions. Required on macOS for integrations that require Camera or Microphone usage. You may need to reload the integration once Missive has been granted access.

Param * requiredDefaultDescription
permissions{}
   camerafalseRequest permission to use camera
   microphonefalseRequest permission to use microphone

storeGet(key)

Retrieve data that has been previously stored using storeSet. The data is persistent between page reloads and app reloads.

Param * requiredDefaultDescription
key*""A unique identifier used when storing the data using storeSet(key, data).

storeSet(key, data)

Store data that remains consistent between page reloads and app reloads.

Param * requiredDefaultDescription
key*""A unique identifier for the data to be stored. This key is used to retrieve the data later using storeGet(key).
data*{}The data (String, Array or Object) to be stored.

Example usage:

const userData = {
  id: '1234',
  name: 'John Doe',
  email: 'john.doe@example.com'
};

Missive.storeSet('userData', userData);

Missive.storeGet('userData')
  .then(data => {
    console.log(data);
  });

respondToMessage(data)

The respondToMessage method can be used to send commands to the Command Bar inside the Action callback of the command_bar context.

Param * requiredDefaultDescription
data*{}
   commands*{}List of commands that are rendered in the command bar
      id*""Unique identifier of the command
      picture{}An image displayed alongside the command using the grid layout
         src*""Path to the image
         webp""Optional WEBP image path that is used when the browser supports it
         alt""Alt attribute for the image tag
      iconUrl""Icon displayed alongside the command using the list layout
      label""Text displayed with the command using the list layout
      payload{}An object returned to the callback event of type execute
      closeOnExecutefalseSpecifies whether or not the Command Bar should close when the command is executed

Example usage:

Missive.setActions([
  {
    label: `My command bar action`,
    contexts: ['command_bar'],
    placeholder: "Command Bar's input placeholder",
    callback: async (event, messageId) => {
      if (event.type === 'load') {
        Missive.respondToMessage(messageId, {
          commands: [
            {
              id: 'command-id',
              iconUrl: 'https://via.placeholder.com/64',
              label: 'command-text',
              payload: {},
              closeOnExecute: true,
            },
          ],
        })

        return
      }

      if (event.type === 'search') {
        const commands = searchCommands(event.value)
        Missive.respondToMessage(messageId, { commands })

        return
      }

      if (event.type === 'execute') {
        executeCommand(event.payload)

        return
      }
    },
  },
])

fetchConversations(ids)

Fetches attributes for the given conversation IDs.
=> Promise(Array)
    ⮑ Resolves with Conversation objects

Param * requiredDefaultDescription
ids*[]Array of conversation IDs

Example usage:

Missive.on('change:conversations', (ids) => {
  Missive.fetchConversations(ids).then((conversations) => {
    if (conversations.length != 1) {
      // Do nothing if multiple conversations are selected.
      return
    }

    var message = conversations[0].latest_message
    if (!message || !message.from_field) {
      // Do nothing if conversation has no message (only chat comments) or if
      // message has no From field.
      return
    }

    var from = message.from_field
    console.log('Message from:', from.name, from.address)
    console.log('Message subject:', message.subject)
  })
})

Available attributes for conversations:

// Conversation
{
  id: '2b3db130-e94e-43fa-970a-63bae8cb10ee',
  color: '#ff0000',
  subject: 'Keep it secret, keep it safe',
  users: [ /* Array of User objects */ ],
  assignees: [ /* Array of User objects */ ],
  authors: [ /* Array of AddressField object */ ],
  messages_count: 1,
  messages: [/* Array of Message object (see below) */],
  latest_message: {
    id: 'daa5e30e-490b-4d54-ba7b-63f19b529ab7',
    from_field: { /* AddressField */ },
    to_fields: [ /* Array of AddressField objects */ ],
    cc_fields: [ /* Array of AddressField objects */ ],
    bcc_fields: [ /* Array of AddressField objects */ ],
    reply_to_fields: [ /* Array of AddressField objects */ ],
    subject: 'Keep it secret, keep it safe',
    preview: 'Where is it? --Gandalf',
    body: '<p>Where is it?</p><p>--<br>Gandalf</p>',
    delivered_at: 1550698870,
  },
  link: 'https://mail.missiveapp.com/#inbox/conversations/37c8d757-2a20-45f6-9aa1-dbe815d27cb0',
}

fetchMessages(ids)

Fetches attributes for the given message IDs.
=> Promise(Array)
    ⮑ Resolves with Message objects

Param * requiredDefaultDescription
ids*[]Array of message IDs

Available attributes for messages:

// Message
{
  id: 'daa5e30e-490b-4d54-ba7b-63f19b529ab7',
  from_field: { /* AddressField */ },
  to_fields: [ /* Array of AddressField objects */ ],
  cc_fields: [ /* Array of AddressField objects */ ],
  bcc_fields: [ /* Array of AddressField objects */ ],
  reply_to_fields: [ /* Array of AddressField objects */ ],
  subject: 'Keep it secret, keep it safe',
  preview: 'Where is it? --Gandalf',
  body: '<p>Where is it?</p><p>--<br>Gandalf</p>',
  delivered_at: 1550698870,
}

fetchUsers()

Fetches attributes for all users.
=> Promise(Array)
    ⮑ Resolves with User objects

// User
{
  id: '6b52b6b9-9b51-46ad-a4e3-82ef3c45512c',
  avatar_url: 'https://gravatar.com/avatar/014bcc1f9c5920c658a198e6649cd20b',
  email: 'frodo@fellowship.org',
  first_name: 'Frodo',
  last_name: 'Baggins',
  display_name: 'You',
  me: true,
}

fetchLabels()

Fetches attributes for all shared labels.
=> Promise(Array)
    ⮑ Resolves with Label objects

// Label
{
  avatar_url: "https://…",
  color: "#000"
  description: null
  emoji: null
  id: "93c1010b-8a43-4325-a2af-b3f2d7bedfd3"
  name: "GitHub"
  organization_id: "555abd43-5d6c-426b-bcb0-84180689bc86"
  parent_id: null
  share_with_organization: true
  share_with_team_id: null
  share_with_user_ids: []
  type: "shared_label"
  visibility: "organization"
}

Conversation methods

createConversation(options)

Creates a new conversation.

Param * requiredDefaultDescription
options{}
   selecttrueNavigate to the newly created conversation(s)
   count1Number of conversations to create

archive()

Archives current conversation.

trash()

Trashes current conversation.

moveToInbox()

Moves current conversation to Inbox.

comment(body)

Creates a comment in the current conversation.

Param * requiredDefaultDescription
body*""Body of the comment

createTask(body, completed)

Creates a task in the current conversation.

Param * requiredDefaultDescription
body*""Body of the task
completedfalseMark task as completed

addLabels(labelIds)

Adds labels to the current conversation.

Param * requiredDefaultDescription
labelIds*[]Array of label ids

removeLabels(labelIds)

Removes labels from the current conversation.

Param * requiredDefaultDescription
labelIds*[]Array of label ids

close()

Closes the current conversation.

reopen()

Reopens the current conversation.

assign(userIds)

Assigns users to the current conversation.

Param * requiredDefaultDescription
userIds*[]Array of user ids
Empty array removes all assignees

addAssignees(userIds)

Adds assignees to the current conversation.

Param * requiredDefaultDescription
userIds*[]Array of user ids

removeAssignees(userIds)

Removes assignees from the current conversation.

Param * requiredDefaultDescription
userIds*[]Array of user ids

setColor(color)

Sets current conversation color.

Param * requiredDefaultDescription
color*""Color in HEX format

setSubject(subject)

Sets current conversation subject.

Param * requiredDefaultDescription
subject*""Subject of the conversation
Empty or null resets the subject

Composer methods

compose(options)

Creates a new draft in a new conversation.

Param * requiredDefaultDescription
options{}
   deliverfalseInstantly deliver newly created draft
   mailto{}
      subject""Draft subject
      body""Draft body
      to_fields[]Array of AddressField objects
      cc_fields[]Array of AddressField objects
      bcc_fields[]Array of AddressField objects

composeInConversation()

Creates a new draft in current conversation.
Same params as #compose

reply(options)

Replies to current conversation latest message.

Param * requiredDefaultDescription
options{}
   deliverfalseInstantly deliver newly created reply
   mailto{}See compose method above

forward(options)

Forwards current conversation latest message.

Param * requiredDefaultDescription
options{}
   privatefalseCreate draft in a new private conversation
   deliverfalseInstantly deliver newly created draft
   mailto{}See compose method above

insertText(text)

Inserts content as text in the currently selected composer.

Param * requiredDefaultDescription
text""Text content

insertHtml(text)

Inserts content as HTML in the currently selected composer.

Param * requiredDefaultDescription
text""HTML content

Helper methods

isToday(date)

Tests if date is today.
=> Boolean

Param * requiredDefaultDescription
date*Date object

isTomorrow(date)

Tests if date is tomorrow.
=> Boolean

Param * requiredDefaultDescription
date*Date object

isPast(date)

Tests if date is past.
=> Boolean

Param * requiredDefaultDescription
date*Date object

isInLessThan(date, options)

Tests if date is in less than X hours / minutes / seconds.
=> Boolean

Param * requiredDefaultDescription
date*Date object
options{}
   hours0Hours in the future
   minutes0Minutes in the future
   seconds0Seconds in the future

getMonth(index, options)

Returns the month name of a given index.
=> String

Param * requiredDefaultDescription
index*0-11 index of the month
options{}
   shortfalseReturns the short version of the month
i.e. "Jan"

getEmailAddresses(conversations)

Returns all the email addresses found in conversations.
=> Array(AddressField)

Param * requiredDefaultDescription
conversations*[]Array of Conversation object

getPhoneNumbers(conversations)

Returns all the phone numbers found in conversations.
=> Array(PhoneField)

Param * requiredDefaultDescription
conversations*[]Array of Conversation object

formatTimestamp(timestamp, options)

Formats given timestamp.
=> { date, formatted }

Param * requiredDefaultDescription
timestamp*Unix timestamp in seconds or milliseconds
i.e. 1550586350
options{}
   todayfalseDisplays "Today" when date is today
   tomorrowfalseDisplays "Tomorrow" when date is tomorrow
   yearfalseForces the year to be displayed
Year is not displayed by default when current year
   timefalseDisplays the hours and minutes
   untilUnix timestamp
When date spans over multiple days

formatDate(string, options)

Formats given date.
=> { date, formatted }

Param * requiredDefaultDescription
string*""Date string
i.e. "2018-10-19 17:32:45 GMT"
options{}See formatTimestamp options above

formatContact(contact)

Formats given contact.
=> { letters, formatted }

Param * requiredDefaultDescription
contact*AddressField object

capitalize(string)

Capitalizes given string.
=> String

Param * requiredDefaultDescription
string*""String to be capitalized

classNames(classes)

Converts object to CSS class names.
=> String

Param * requiredDefaultDescription
classes*{}Object of CSS classes definitions and assertions
i.e. { foo: true, bar: true, baz: false }

writeToClipboard(text)

Write text to the user’s clipboard.

Param * requiredDefaultDescription
text""String to copy to the clipboard

Events

main_action

Triggered when user press the “Integrations main action” shortcut.
=> ()

message_sent

Triggered when a user sends a message, or when a message is scheduled to be sent. Be careful as once triggered, the user can still cancel the delivery of the message within a short period (Undo).
=> (id)

PayloadDescription
idUse fetchMessages to fetch the data of the message.

change:conversations

Triggered when selected conversation(s) change.
=> (ids)

PayloadDescription
idsArray of the selected Conversation IDs. Use fetchConversations to fetch the data of newly selected conversation(s).

change:users

Triggered when users change.
=> ()

Use #fetchUsers to fetch users data.

Glossary

Action

{ label: 'New task', callback: () => {} }
{ label: 'Forward', contexts: ['message'], callback: () => {} }

Param * requiredDefaultDescription
contexts[]Contexts where the action will be available in the Missive UI.

Any of draft, conversations, conversation, message, tel, comment, comment_box, swipe, command_bar, setting

All when omitted.
label*""Action name
emoji""Emoji ID of the emoji used as the action icon in the Missive UI. You can find the ID of a specific emoji on this page. For instance, for this 🧹 emoji the ID is :broom:.
swipe_id""Unique string per swipe action
i.e. new-task

*Required for swipe context
callback*nullAction callback

Receives an object with either conversations, conversation, message, tel, comment, comment_box as keys depending on the context the action was triggered.

Callbacks for the command_bar context take an event object wither either a load, search, execute type as well as a messageId. The callback can be used to send commands that will be displayed in the Command Bar. See the respondToMessage method for more details.
swipe_color"#aaa"Background color of the swipe action
layout"list"The layout of the commands inside the Command Bar when using the command_bar context. It can be either list or grid.
placeholder""Placeholder of the Command Bar input

AddressField

{ address: 'frodo@missiveapp.com', name: 'Frodo Baggins' }
{ address: 'sam@missiveapp.com' }

Param * requiredDefaultDescription
address*""Email address
name""Contact name

FormField

{ type: 'input', data: { … }, options: { … } }
{ type: 'calendar', data: { … } }

Param * requiredDefaultDescription
type*""Field type
Any of input, textarea, select, calendar, duration, progress, html
scope{}Dynamically filter out fields not matching this scope
i.e. { project_id: 12345 }
Would only show this field when project 12345 is selected
data*{}Data available for all types
See following FormField(type:) for specific types data
   name*""Name of the field
As you would normally use inside a <form>
   value*""Default value of the field
   placeholder*""Field placeholder
   requiredfalseForm won’t submit unless user fills this field

FormField(type:input)

{ type: 'input', data: { … }, options: { … } }

Param * requiredDefaultDescription
data{}
   type*{}Input type
Any of text, number, hidden
   focusfalseAuto focus the input
   disabledfalseMake the input non-editable
   precisionFormat number to specific precision
For number input type only
options{}
   prefixfalseMake the placeholder always visible
   thinfalseRender a smaller input
For text input type only

FormField(type:textarea)

{ type: 'textarea', data: { … } }

Param * requiredDefaultDescription
data{}
   rows4Number of visible rows
   focusfalseAuto focus the textarea

FormField(type:select)

{ type: 'select', data: { … } }

Param * requiredDefaultDescription
data{}
   valueValue of the selected option
   options[]Array of Option objects
   multiplefalseAllow selecting multiple options

FormField(type:calendar)

{ type: 'calendar', data: { … } }

Param * requiredDefaultDescription
data{}
   value{ timestamp, all_day }Unix timestamp and boolean
i.e. { timestamp: 1550586350, all_day: true }
   allow_pastfalseAllow setting a date in the past
   allow_all_dayfalseAllow setting a full-day date

FormField(type:duration)

{ type: 'duration', data: { … } }

Param * requiredDefaultDescription
data{}
   value""HH:MM duration
i.e. "00:30"

FormField(type:progress)

{ type: 'progress', data: { … } }

Param * requiredDefaultDescription
data{}
   valueValue of the selected step
   steps[]Array of Step objects

FormField(type:html)

{ type: 'html', data: { … } }

Param * requiredDefaultDescription
data{}
   value""HTML string
i.e. "
  <p>Hey <b>there</b>!</p>
  <p>How <span style="color: red">are you</span>?</p>
"

FormComment

{
  content: 'I will take the Ring, though I do not know the way.',
  authorName: 'Frodo Baggins',
  authorAvatar: 'https://gravatar.com/avatar/014bcc1f9c5920c658a198e6649cd20b',
}

Param * requiredDefaultDescription
content*""Comment body
authorAvatar""Author avatar URL
authorName""Author name
date""Date string with format of your choosing
i.e. "Feb 18, 2019"

FormNote

{ message: '✓ Completed on Feb 18' }
{ message: 'View on Missive', url: 'https://missiveapp.com' }

Param * requiredDefaultDescription
message*""Note body
url""Turn the note into a clickable link

FormButton

{ type: 'cancel', label: 'Cancel' }
{ type: 'submit', label: 'Create' }

Param * requiredDefaultDescription
type*""Button type
Any of submit, cancel
label""Button label

Option

{ label: 'My Project', value: 12345 }
{ label: 'My Tag', value: 54321, color: '#F00' }

Param * requiredDefaultDescription
label*""Option label
value*""Option value
disabledfalseMake the option non-clickable
color""Color in HEX format
Add a color pin to the option
colorRadius"100%"Specify the radius of the color pin
callbacknullOption callback
For openContextMenu options

PhoneField

{ phoneNumber: '+11231231234', name: 'Frodo Baggins' }
{ phoneNumber: '+11231231234' }

Param * requiredDefaultDescription
phoneNumber*""Phone number
name""Contact name

Step

{ label: 'In Progress', value: 1 }
{ label: 'Completed', value: 2 }

Param * requiredDefaultDescription
label*""Step label
value*""Step value


Need more specific answers?

Contact us via our Help Center