Giter Site home page Giter Site logo

interfax / interfax-dotnet Goto Github PK

View Code? Open in Web Editor NEW
8.0 10.0 14.0 802 KB

Fax send and receive in .NET with the InterFAX REST API

Home Page: https://www.interfax.net/en/dev/dotnet

License: MIT License

C# 99.88% HTML 0.12%
fax fax-api hipaa inbound interfax interfax-api library dotnet csharp vb-net

interfax-dotnet's Introduction

InterFAX .NET Library

NuGet version Build Status

Installation | Getting Started | Running Tests | Contributing | License

Send and receive faxes in CLI Languages with the InterFAX REST API.

(examples are in C#)

Installation

This library targets .NET Standard 2.0/.NET 4.6.1+ and is installed via NuGet:

Install-Package InterFAX.Api -Version 3.1.5

For a full list of supported platforms see the .NET Standard reference documentation.

The legacy PCL format package targetting .NET 4.5.2 is available as version 1.X.X:

Install-Package InterFAX.Api -Version 1.0.5

Warning: If building with VS2015, the NuGet package manager must be updated to v3.6+ in order to recognise .NET Standard packages within the IDE (download). If required, the updated package manager will additionally prompt and link to install an updated .NET standard runtime.

(Advanced) For use with the PCI compliant InterFAX API, select the InterFAX_PCI root during initialization (See Client)

Getting started

Usage

Client | Account | Outbound | Inbound | Documents

Client

Credentials are set through environment variables, or passed as parameters directly during initialization. Credentials passed as parameters take precedence over those set in the environment.

using InterFAX.Api;

// | Initialize using parameters
var interfax = new FaxClient(username: "...", password: "...");

// | Initialize using Environment variables
// key : string 
// INTERFAX_USERNAME : InterFax Username
// INTERFAX_PASSWORD : InterFax Password
var interfax = new FaxClient();

// Initialize with a specific InterFAX API Endpoint (EG PCI Compliant)
// InterFAX_Default: https://www.interfax.net/en-us/dev/rest/reference
// InterFAX_PCI: https://www.interfax.net/en-us/dev/rest_pci/reference
var interfax = new FaxClient(apiRoot: FaxClient.ApiRoot.InterFAX_PCI);

// Locale specific endpoints for data-sovereignty
// InterFAX_US_PCI: USA
var interfax = new FaxClient(apiRoot: FaxClient.ApiRoot.InterFAX_US_PCI);
// InterFAX_CA_PCI: Canada
var interfax = new FaxClient(apiRoot: FaxClient.ApiRoot.InterFAX_CA_PCI);

Use of configurationManager was removed in 2.0.0, due to conversion to .NET Standard.

All connections are established over HTTPS.

Client must support TLS 1.1+ as of June 30th 2018 (See TLS 1.0 End of Life)

Account

Balance

async Task<decimal> GetBalance();

Determine the remaining faxing credits in your account.

var interfax = new FaxClient();

var balance = await interfax.Account.GetBalance();
Console.WriteLine($"Account balance is {balance}"); //=> Account balance is 9.86

More: documentation

Outbound

Send | Get list | Get completed list | Get record | Get image stream | Cancel fax | Search

Send fax

async Task<int> SendFax(IFaxDocument faxDocument, SendOptions options) async Task<int> SendFax(List<IFaxDocument> faxDocuments, SendOptions options)

Submit a fax to a single destination number. Returns the messageId of the fax.

For small documents, there are a few ways to send a fax. You can directly provide a file path, a file stream or a url, which can be a web page anywhere or a link to a previously uploaded document resource (see Documents).

var options = new SendOptions { FaxNumber = "+11111111112"};

// with a path
var fileDocument = interfax.Documents.BuildFaxDocument(@".\folder\fax.txt");
var messageId = await interfax.Outbound.SendFax(fileDocument, options);

// with a stream
// NB : the caller is responsible for opening and closing the stream.
using (var fileStream = File.OpenRead(@".\folder\fax.txt"))
{
  var fileDocument = interfax.Documents.BuildFaxDocument("fax.txt", fileStream);
  var messageId = await interfax.Outbound.SendFax(fileDocument, options);
}
// with a byte array
byte[] file = ...
var urlDocument = interfax.Documents.BuildFaxDocument(file, ".pdf"));
var messageId = await interfax.Outbound.SendFax(urlDocument, options);

// with a URL
var urlDocument = interfax.Documents.BuildFaxDocument(new Uri("https://s3.aws.com/example/fax.html"));
var messageId = await interfax.Outbound.SendFax(urlDocument, options);

// or a combination
var documents = new List<IFaxDocument> { fileDocument, urlDocument };
var messageId = await interfax.Outbound.SendFax(documents, options)

InterFAX supports over 20 file types including HTML, PDF, TXT, Word, and many more. For a full list see the Supported File Types documentation. The supported types are mapped to media types in the file SupportedMediaTypes.json - this can be modified by hand.

The returned object is the Id of the fax. Use this Id to load more information, get the image, or cancel the sending of the fax.

var result = await interfax.CancelFax(messageId);

// result in this case is just "OK".

SendOptions: FaxNumber, Contact, PostponeTime, RetriesToPerform, Csid, PageHeader, Reference, PageSize, FitToPage, PageOrientation, Resolution, Rendering


Get outbound fax list

async Task<IEnumerable<OutboundFaxSummary>> GetList(Outbound.ListOptions options = null);

Get a list of recent outbound faxes (which does not include batch faxes).

var faxes = await interfax.Outbound.GetList();

Outbound.ListOptions: Limit, LastId, SortOrder, UserId


Get completed fax list

async Task<IEnumerable<OutboundFaxSummary>> GetCompleted(params int[] ids)

Get details for a subset of completed faxes from a submitted list. (Submitted id's which have not completed are ignored).

var completed = await interfax.Outbound.GetCompleted(1, 2, 3);

More: documentation


Get outbound fax record

async Task<OutboundFaxSummary> GetFaxRecord(Int64 id);

Retrieves information regarding a previously-submitted fax, including its current status.

var fax = interfax.Outbound.GetFaxRecord(123456)

More: documentation


Get outbound fax image stream

async Task<Stream> GetFaxImageStream(Int64 id);

Retrieve the fax image stream (TIFF file) of a submitted fax.

using (var imageStream = await _interfax.Outbound.GetFaxImageStream(662208217))
{
    using (var fileStream = File.Create(@".\image.tiff"))
    {
        InterFAX.Utils.CopyStream(imageStream, fileStream);
    }
}

More: documentation


Cancel a fax

async Task<string> CancelFax(Int64 id)

Cancel a fax in progress.

var result = interfax.Outbound.CancelFax(123456)

// => OK

More: documentation


Search fax list

async Task<IEnumerable<OutboundFax>> SearchFaxes(SearchOptions searchOptions)

Search for outbound faxes.

var faxes = await interfax.Outbound.Search(new SearchOptions {
  faxNumber = '+1230002305555'
});

Options: Ids, Reference, DateFrom, DateTo, Status, UserId, FaxNumber, Limit, Offset

Inbound

Get list | Get record | Get image stream | Get emails | Mark as read | Resend to email

Get inbound fax list

async Task<IEnumerable<InboundFax>> GetList(ListOptions listOptions = null)

Retrieves a user's list of inbound faxes. (Sort order is always in descending ID).

var faxes = await interfax.Inbound.GetList(new ListOptions { UnreadOnly = true });

Options: UnreadOnly, Limit, LastId, AllUsers


Get inbound fax record

async Task<InboundFax> GetFaxRecord(Int64 id)

Retrieves a single fax's metadata (receive time, sender number, etc.).

var fax = await interfax.Inbound.GetFaxRecord(123456);

More: documentation


Get inbound fax image stream

async Task<Stream> GetFaxImageStream(Int64 id)

Retrieves a single fax's image.

using (var imageStream = await _interfax.Inbound.GetFaxImageStream(291704306))
{
    using (var fileStream = File.Create(@".\image.tiff"))
    {
        Utils.CopyStream(imageStream, fileStream);
    }
}

More: documentation


Get forwarding emails

async Task<IEnumerable<ForwardingEmail>> GetForwardingEmails(Int64 id)

Retrieve the list of email addresses to which a fax was forwarded.

var emails = await interfax.Inbound.GetForwardingEmails(12345);
foreach(var email in emails)
	Console.WriteLine($"{email.EmailAddress}, {email.MessageStatus}, {email.CompletionTime.ToString("s")}")

More: documentation


Mark as read/unread

async Task<string> MarkRead(Int64 id) async Task<string> MarkUnread(Int64 id)

Mark a transaction as read/unread.

// mark as read
var result = interfax.Inbound.MarkRead(123456);

// => OK

// mark as unread
var result = interfax.Inbound.MarkUnread(123456);

// => OK

More: documentation

Resend inbound fax

async Task<string> Resend(Int64 id, string emailAddress = null)

Resend an inbound fax, optionally to a specific email address.

// resend to the email(s) to which the fax was previously forwarded
var result = await interfax.Inbound.Resend(123456);

// => OK

// resend to a specific address
var result = await interfax.Inbound.Resend(123456) "[email protected]");

// => OK

More: documentation


Documents

Create document upload session | Upload chunk | Get upload session list | Status | Cancel

Document upload sessions allow for uploading of large files up to 20MB in chunks of arbitrary size.

You can do this with either a file path :

UploadSession UploadDocument(string filePath)

var fileInfo = new FileInfo("test.pdf"));
var session = _interfax.Outbound.Documents.UploadDocument(fileInfo.FullName);

Or with a file stream :

UploadSession UploadDocument(string fileName, FileStream fileStream)

using (var fileStream = File.OpenRead("test.pdf"))
{
  var session = _interfax.Outbound.Documents.UploadDocument(filePath, fileStream);
}

The Uri property of the returned session object can be used when sending a fax.

If you want to control the chunking yourself, the following example shows how you could upload a file in 500 byte chunks:

var fileInfo = new FileInfo("large.pdf");

var sessionId = CreateUploadSession(new UploadSessionOptions
{
    Name = fileInfo.Name,
    Size = (int) fileInfo.Length
}).Result;

using (var fileStream = File.OpenRead(filePath))
{
    var buffer = new byte[500];
    int len;
    while ((len = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        var data = new byte[len];
        Array.Copy(buffer, data, len);
        var response = UploadDocumentChunk(sessionId, fileStream.Position - len, data).Result;
        if (response.StatusCode == HttpStatusCode.Accepted) continue;
        if (response.StatusCode == HttpStatusCode.OK) break;
    }
}

Create Document Upload Session

async Task<string> CreateUploadSession(UploadSessionOptions options)

Create a document upload session, allowing you to upload large files in chunks.

var sessionId = _interfax.Outbound.Documents.CreateUploadSession(options);

Options: Disposition, Sharing


Upload chunk

async Task<HttpResponseMessage> UploadDocumentChunk(string sessionId, long offset, byte[] data)

Upload a chunk to an existing document upload session. The offset refers to the offset in the unchunked file not the data parameter.

var response = UploadDocumentChunk(sessionId, offset, data).Result;

// HttpStatusCode.OK (done) or HttpStatusCode.Accepted (unfinished)

More: documentation


Get Upload Session List

async Task<IEnumerable<UploadSession>> GetUploadSessions(ListOptions listOptions = null)

Get a list of previous document uploads which are currently available.

var list = _interfax.Outbound.Documents.GetUploadSessions(new Documents.ListOptions
                {
                    Offset = 10,
                    Limit = 5
                }).Result;

Options: Limit, Offset


Get upload session status

async Task<UploadSession> GetUploadSession(string sessionId)

Get the current status of a specific document upload session.

var session = interfax.Documents.GetUploadSession(123456);

More: documentation


Cancel document upload session

interfax.documents.cancel(document_id, callback);

Cancel a document upload and tear down the upload session, or delete a previous upload.

var result = await interfax.Outbound.Documents.CancelUploadSession(sessionId);

// => OK

More: documentation


Running Tests

Manually (Visual Studio)

  1. Build the project
  2. Open the Test Explorer Test > Windows > Test Explorer
  3. "Run All"

Manually (CLI/Console Runner)

  1. Install the .NET Core SDK
  2. Run dotnet test in the root or desired test folder

Note: Integration Testing

Integration tests require valid api credentials to pass, these can be provided within the testingConfig.cs within. A free developer account can be registered at https://www.interfax.net/en/dev/register.

Contributing

  1. Fork the repo on GitHub
  2. Clone the project to your own machine
  3. Commit changes to your own branch
  4. Push your work back up to your fork
  5. Submit a Pull request so that we can review your changes

License

This library is released under the MIT License.

interfax-dotnet's People

Contributors

cbetta avatar eyalnevo avatar fouwels avatar jdpearce avatar ricky-shake-n-bake-bobby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

interfax-dotnet's Issues

InboundFax.MessageId datatype is inconsistent API

InboundFax.MessageId is a string, but all other operations against an InboundFax require fax identification by integer.

Working with the API while processing the inbound queue requires integer parsing to complete the cycle of Inbound.GetList, GetFaxImageStream, MarkAsRead.

Deploying inside Azure Functions...

I am trying to use this SDK within my Azure Functions project. Everything works great when I test on my machine. However, when I deploy my project to Azure (production), I get a runtime error saying that the 'SupportedMediaTypes.json' file is not deployed in the 'bin' folder. Instead, Visual Studio places this file inside the parent '\wwwroot' folder.

I do not know how to instruct VS to place this file in the '\wwwroot\bin' folder where the 'InterFAX.Api.dll' assembly is located and where this assembly is looking for it. Also, why is this file even necessary? It would be nice if the SDK just supported these types by default, unless overridden by the presence of this file. Alternatively, if I could setup the mappings in code, rather than via this file.

Please help - this is crucial I resolve this issue. Many thanks in advance!

Typo README.md

Hi Team,

I see typo fileDocument => faxDocument in "Send fax" section.

FaxClient should not set default serialization settings

Any time a FaxClient is created in our application, it overwrites the default serialization settings in Json.Net. Investigating the code, there is this code block in the constructor that should be removed/reworked:

JsonConvert.DefaultSettings = () => { var settings = new JsonSerializerSettings(); settings.Converters.Add(new StringEnumConverter { CamelCaseText = true }); return settings; };
This is generally considered a bad practice for any libraries as it interferes with app behavior.

TLS 1.0 Depreciated causing Exceptions

Since the library 1.05 is built on .NET 4.5.2, it requires an additional line of code to be invoked prior to any API calls to force use of TLS 1.2:

C# ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
VB ServicePointManager.SecurityProtocol = DirectCast(3072,System.Net.SecurityProtocolType)

Here is some useful information regarding TLS1.2 and .NET:
https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

For 2008 R2, registry settings to enable support.
https://support.microsoft.com/en-us/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in
https://support.microsoft.com/en-us/help/3154518/support-for-tls-system-default-versions-included-in-the-net-framework
https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings

There are a few options I foresee:

  1. Update the documentation to include mention of the above line before invoking
  2. Hardcode the above line into the client to force TLS1.2 usage
  3. Recompile the client to require .NET 4.7+ (which uses operating system defaults)

Potential problems with each one:
Option 1: Added complexity put upon the end user/developer
Option 2: You've now hardcoded something which will eventually become a problem.
Option 3: Limit usage by potential users/developers that use older .NET versions.

Fix: InterFAX.Api does not have a strong name...

My project complains when building with the InterFAX.Api assembly. Below is the error:

"Referenced assembly 'InterFAX.Api, Version=3.0.1.0, Culture=neutral, PublicKeyToken=null' does not have a strong name."

Can you please resolve this and post an updated version to Nuget? Many thanks.

How to set up proxy?

We are using below code to connect. But we are not sure where to add proxy settings. Can you please help ?

        public void Initialise(HttpMessageHandler messageHandler = null, HttpClient httpClient = 
        null)
        {
        var username = _faxConfiguration.UserName;
        var password = _faxConfiguration.Password;
        if (string.IsNullOrEmpty(username))
            throw new ArgumentException($"{username} has not been set.");

        if (string.IsNullOrEmpty(password))
            throw new ArgumentException($"{password} has not been set.");

        Account = new Account(this);
        Inbound = new Inbound(this);
        Outbound = new Outbound(this);
        Documents = new Documents(this);

        HttpClient = messageHandler == null ? new HttpClient() : new HttpClient(messageHandler);
        HttpClient = httpClient ?? HttpClient;

        HttpClient.BaseAddress = new Uri($"https://rest.interfax.net/");
        HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        HttpClient.DefaultRequestHeaders.Add("Authorization",
            new List<string> { $"Basic {Utils.Base64Encode($"{username}:{password}")}" });

        JsonConvert.DefaultSettings = () =>
        {
            var settings = new JsonSerializerSettings();
            settings.Converters.Add(new StringEnumConverter { CamelCaseText = true });
            return settings;
        };
    }

Request - Fax byte[] in addition to files...

Please consider supporting FaxClient.Documents.BuildFaxDocument(byte[], ...) in addition to filename and uri building options. We have a need to send from a byte[] directly without the option to be able to write to disk first (which would be unwanted overhead even if we could). Many thanks!

Rename project

The project is referred to as interfax-csharp but the url is interfax-dotnet

SupportedMediaTypes.json Location

In issue #23 it mentions that it uses an embedded version of this file in the assembly but in the code in Documents.cs it also look like if there is not a file on disk it tries to write it out to disk.

`var assembly = Assembly.GetAssembly(typeof(Documents));
var assemblyPath = Path.GetDirectoryName(assembly.Location);
var typesFile = Path.Combine(assemblyPath, "SupportedMediaTypes.json");

if (!File.Exists(typesFile))
{
// unpack the types file to the assembly path
using (var resource = assembly.GetManifestResourceStream("InterFAX.Api.SupportedMediaTypes.json"))
{
using (var file = new FileStream(typesFile, FileMode.Create, FileAccess.Write))
{
resource.CopyTo(file);
}
}
}`

This is a problem I am encountering because it is trying to write the file into the same folder as that the assembly is located in, which if often protected from writing and which with a Store applications it cannot do.

Would it be possible to have a property that is set to define where to write this file and any other files it needs? I have seen other products that define something like "ReferencePath" so that we can define where this is written or I believe this location will work properly for most desktop scenarios, Store and non-Store, although I am not sure about web.

Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

Error on Mac with .NET for Mac

I've installed .NET for Mac via: https://www.microsoft.com/net/core#macos

I am using VS Code with Nuget installed, and when I install the file and run dotnet restore I get the following error.

Errors in /Users/cbetta/code/playground/hwapp/hwapp.csproj
      Package InterFAX.Api 1.0.4 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package InterFAX.Api 1.0.4 supports: net452 (.NETFramew
ork,Version=v4.5.2)
      Package Microsoft.AspNet.WebApi.Client 5.2.3 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package Microsoft.AspNet.WebApi.Clien
t 5.2.3 supports:
        - net45 (.NETFramework,Version=v4.5)
        - portable-net45+netcore45+wp8+wp81+wpa81 (.NETPortable,Version=v0.0,Profile=wp8+netcore45+net45+wp81+wpa81)
      One or more packages are incompatible with .NETCoreApp,Version=v1.1.

Any clues?

Make integration tests work with any set of user credentials

Currently we are using hard coded fax and document IDs in some places in the integration tests. As a result the tests fail when a different user tries to edit the code and run the tests, as they do not have access to the same resources.

We should fix this, one way to do this is to "find" a fax ID first based on the whole list of faxes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.