/**
  * @param \HelpScout\model\Attachment $attachment
  */
 public function createAttachment(Attachment $attachment)
 {
     list(, $body) = $this->doPost('attachments.json', $attachment->toJson(), 201);
     if ($body) {
         $attachment->setHash($body['item']['hash']);
     }
 }
<?php

include_once 'ApiClient.php';
use HelpScout\ApiClient;
use HelpScout\model\Attachment;
$client = ApiClient::getInstance();
$client->setKey('example-key');
$attachment = new Attachment();
$attachment->setFileName('photo.png');
$attachment->setMimeType('image/png');
$attachment->setData(file_get_contents('/tmp/photo.png'));
$client->createAttachment($attachment);
// at this point, the image as been uploaded and is waiting to be attached to a conversation
// Now let's build a conversation
$customerRef = $client->getCustomerRefProxy(null, '*****@*****.**');
$conversation = new \HelpScout\model\Conversation();
$conversation->setType('email');
$conversation->setSubject('I need help');
$conversation->setCustomer($customerRef);
$conversation->setCreatedBy($customerRef);
// The mailbox associated with the conversation
$conversation->setMailbox($client->getMailboxProxy(2431));
// A conversation must have at least one thread
$thread = new \HelpScout\model\thread\Customer();
$thread->setBody('Hello there - I need some help please.');
// add any and all previously uploaded attachments. Help Scout will take
// the attachments you've already uploaded and associate them with this conversation.
$thread->setAttachments(array($attachment));
// Create by: required
$thread->setCreatedBy($customerRef);
$conversation->addLineItem($thread);
 /**
  * @param  \HelpScout\model\Attachment $attachment
  * @return void
  */
 public function createAttachment(Attachment $attachment)
 {
     list(, $body) = $this->doPost('attachments.json', $attachment->toJson(), 201);
     if ($body) {
         $body = json_decode($body);
         $attachment->setHash($body->item->hash);
     }
 }
 /**
  * @param $consoleCommand SyncCommandBase
  * @param $grooveMessage array
  * @param $ticketStatus
  * @param $grooveTicket
  * @return array
  * @throws ApiException
  * @throws \Exception
  * @internal param array $grooveTicket
  */
 private static function retrieveAttachmentsForGrooveMessage($consoleCommand, $grooveMessage, $ticketStatus, $grooveTicket)
 {
     $grooveTicketNumber = $grooveTicket['number'];
     if (!isset($grooveMessage['links']['attachments'])) {
         return null;
     }
     $grooveMessageId = null;
     $matches = array();
     $helpscoutAttachments = array();
     $failedAttachments = array();
     if (preg_match('@^https://api.groovehq.com/v1/attachments\\?message=(.*)@i', $grooveMessage['links']['attachments']['href'], $matches) === 1) {
         $grooveMessageId = $matches[1];
     } else {
         return $helpscoutAttachments;
     }
     $attachments = $consoleCommand->makeRateLimitedRequest(GROOVE, function () use($consoleCommand, $grooveMessageId) {
         return $consoleCommand->getGrooveClient()->messages()->attachments(['message' => $grooveMessageId])['attachments'];
     });
     foreach ($attachments as $grooveAttachment) {
         // Attachments: attachments must be sent to the API before they can
         // be used when creating a thread. Use the hash value returned when
         // creating the attachment to associate it with a ticket.
         $fileName = $grooveAttachment['filename'];
         $fileSize = $grooveAttachment['size'];
         $consoleCommand->info("Groove message #{$grooveMessageId} (ticket #{$grooveTicketNumber}): Attachment {$fileName} found ({$fileSize} bytes). Uploading to HelpScout...");
         $helpscoutAttachment = new Attachment();
         $helpscoutAttachment->setFileName($fileName);
         try {
             $buffer = file_get_contents($grooveAttachment['url']);
             $finfo = new finfo(FILEINFO_MIME_TYPE);
             $mimeType = $finfo->buffer($buffer);
             $helpscoutAttachment->setMimeType($mimeType);
             $helpscoutAttachment->setData($buffer);
             if (intval($grooveAttachment['size']) > 10485760) {
                 $consoleCommand->warn("Warning: Maximum file size supported by HelpScout is 10 MB (10485760 bytes). File size for {$fileName} is {$fileSize} bytes.");
             }
             $consoleCommand->makeRateLimitedRequest(GROOVE, function () use($consoleCommand, $helpscoutAttachment) {
                 $consoleCommand->getHelpScoutClient()->createAttachment($helpscoutAttachment);
             });
             // hash should be programmatically be set now
             $helpscoutAttachment->setData(null);
             $helpscoutAttachments[] = $helpscoutAttachment;
         } catch (\Exception $e) {
             $consoleCommand->error("Failed to create HelpScout attachment for {$fileName}: " . $e->getMessage());
             // For whatever reason the upload failed, let's create a private note containing a
             // link where the attachment can be viewed
             $note = new Note();
             $note->setType('note');
             $note->setStatus($ticketStatus);
             $createdBy = new PersonRef();
             $createdBy->setId(config('services.helpscout.default_user_id'));
             $createdBy->setType('user');
             $note->setCreatedBy($createdBy);
             $datetime = new DateTime($grooveMessage['created_at']);
             $note->setCreatedAt($datetime->format('c'));
             $url = $grooveAttachment['url'];
             $note->setBody("Attachment \"{$fileName}\" failed to upload. Please view original here: <a href=\"{$url}\">{$url}</a>");
             $failedAttachments[] = $note;
         }
     }
     return array($helpscoutAttachments, $failedAttachments);
 }