code: async function addAttachment(activity, arg) {
      let parts = arg.trim().split(' ');
      let contentUrl = parts[0].trim();
      let contentType = (parts.length > 1) ? parts[1].trim() : undefined;
      if (contentType) {
          contentType = contentType.toLowerCase();
          if (cardContentTypes[contentType])
              contentType = cardContentTypes[contentType];
      }
      else {
          contentType = mime.lookup(contentUrl) || cardContentTypes[path.extname(contentUrl)];
  
          if (!contentType && contentUrl && contentUrl.indexOf('http') == 0) {
              let options = { method: 'HEAD', uri: contentUrl };
              let response = await request(options);
              contentType = response['content-type'].split(';')[0];
          }
      }
  
      const charset = mime.charset(contentType);
  
      // if not a url
      if (contentUrl.indexOf('http') != 0) {
          // read the file
          let content = await readAttachmentFile(contentUrl, contentType);
          // if it is not a card
          if (!isCard(contentType) && charset !== 'UTF-8') {
              // send as base64
              contentUrl = `data:${contentType};base64,${new Buffer(content).toString('base64')}`;
              content = undefined;
          } else {
              contentUrl = undefined;
          }
          return (activity.attachments || (activity.attachments = [])).push(new Attachment({ contentType, contentUrl, content }));
      }
      // send as contentUrl
      return (activity.attachments || (activity.attachments = [])).push(new Attachment({ contentType, contentUrl }));
  }
docs: Adds an attachment to the activity. If a mimetype is
  specified, it is used as is. Otherwise, it is derived
  from the file extension.
  
  @param {Activity} activity The activity to add the attachment to
  @param {*} contentUrl contenturl
  @param {*} contentType contentType
  
  @returns {Promise<number>} The new number of attachments for the activity